Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Java Microservices: The Cake Is a Lie But You Can't Ignore It

DZone's Guide to

Java Microservices: The Cake Is a Lie But You Can't Ignore It

An in-depth look at developing microservices in Java, with definitions and a number of options, including Spring Boot, Dropwizard, and other open source choices.

· Java Zone
Free Resource

Learn how to troubleshoot and diagnose some of the most common performance issues in Java today. Brought to you in partnership with AppDynamics.

This post can also be found at Takipi.

It’s becoming impossible to ignore the microservices trend. Some would say it’s just another unbearable buzzword, while others would recite the advantages of breaking down a monolith or take the contrarian approach and focus the negative aspects.

In this post, we’ll take a down-to-earth view at the frameworks we have at our disposal, focusing on the Java ecosystem, to actually implement microservices and see what they’re all about. Let’s dive in.

The Cake Is a Lie

The first question that pops to mind is, do we really need a specialized framework to build microservices with? The answer is no. Can you build a monolith with a microservice framework? Yes. So if it’s really up to you and what you do with it, what are the benefits of a microservice framework over Java EE or Spring? What would make it worth adopting? Do they address both inner architecture and outer, ops-y, architecture?

In the next few sections, we’ll take a closer look at Java EE and its new microprofile initiative, Spring and Spring Boot, the Lightbend stack with Lagom, and other open source solutions like Spotify’s Apollo.

Before we move forward, it’s worth mentioning that there isn’t really a clear definition of what is a microservice architecture. Martin Fowler, ThoughtWorks’ Chief Scientist, tried to define it in his first article covering microservices:

“The microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery”.

This post is not about the pros and cons of microservices and assumes that you’re simply interested in the underlying technology to support it. Another post worth checking out for those issues covers the main challenges in debugging microservices — which is a common pitfall that many don’t think of when considering microservice architectures.

Let’s kick off and examine the following technologies/platforms/frameworks one by one.

1. Java Enterprise Edition

The classic Java EE approach for building applications is geared towards monoliths which over time tend to grow into… spaghetti code monsters. Traditionally, an enterprise application would be packaged into a single EAR (Enterprise Archive) deployment unit which includes WAR (Web Archive) files, and JARs (Java Archive).

Yet, “Vanilla” Java EE could be used for a microservice architecture as well. For a deep dive example of the steps in refactoring a Java EE monolith to a microservice architecture, check out this post from Arun Gupta where he goes over the required steps in this process through an example application of a shopping cart.

Even though there was a slowdown in the development of Java EE 8, the “unofficial” community behind is alive and kicking. A new initiative around optimizing enterprise Java for a microservices architecture comes from folks behind the Java EE Microprofile. You can join the discussion right here.

Another interesting project to look at when thinking about Java EE microservices is Kumuluz. A framework that leverages your existing Java EE knowledge and provides you with a painless way to handpick the components that you need for your application – without wasting too much time on configurations.

Bottom line: Java EE and the projects around it are perfectly fit for microservices, but don’t address the ops aspect and leave its use and best practices for your personal interpretation.

2. Lightbend: Play, Akka, ConductR, and Lagom

Lightbend (formerly Typesafe) provides us with some more options. Similarly to the Kumuluz advantage over plain Java EE, Lagom wraps around the Lightbend stack with Play, Akka, and ConductR under its hood and provides an easier way to build microservices. Its underlying components also include Cassandra, Guice, Jackson, slf4j, Logback, and additional Lightbend components.

Lagom (“just the right amount” in Swedish) is still in its early days, but it looks like a promising direction for the Lightbend stack. In an interview with InfoQ, Jonas Boner, Lightbend’s CTO, said “Most microservices frameworks out there focus on making it easy to build individual microservices – which is the easy part. Lagom extends that to systems of microservices, large systems – which is the hard part, since here we are faced with the complexity of distributed systems.”

Bottom line: Lagom wraps Lightbend’s capabilites in one framework, together with ops capabilities that ConductR provides. Focusing not only on the single microservice, but on the system as a whole.

3.Spring, Spring Boot, and Spring Cloud

While Spring and Spring Boot don’t call themselves microservice frameworks, and the Spring site doesn’t mention microservices on its front page, it doesn’t mean they’re out of the loop. Almost seems as if they’re deliberately not calling it microservices to stay away from the buzzword hype.

Together with Spring Cloud, the Spring Stack is utilizing Netflix Eureka and Ribbon to support the development of distributed systems (a term which often just overlaps with “microservices”). These capabilities include configuration management, service discovery, intelligent routing, control bus, leadership election, distributed sessions, and more.

For a deep dive on how to build microservices with Spring, and several additional Netflix and other open source projects, check out this post from InfoQ.

Bottom line: Spring is well positioned for the development of microservices, together with an offering around external open source projects that address the ops angle.

4. Dropwizard

Similarly to Spring, Dropwizard doesn’t talk much about microservices as well. It’s a Java framework for developing ops-friendly, high-performance, RESTful web services. An opinionated collection of Java libraries that make building production ready Java applications much easier.

Dropwizard Modules allow hooking up additional projects that don’t come with Dropwizards’ core, and there are also modules developed by the community to hook up projects like Netflix Eureka, comparable to Spring Cloud.

We’ve also previously done a head to head comparison between Dropwizard and Spring Boot, examining their features against each other.

Bottom line: Since Dropwizard is a community project that isn’t backed by a major company like Spring and Pivotal, Java EE and Oracle, Lagom and Lightbend, its development might be slower, but there’s a strong community behind it and it’s a go to framework for large companies as well as smaller projects.

5. Spotify Apollo, VertX, and other “Microframeworks”

Apart from the 4 big players we’ve mentioned here, there’s a plethora of other projects that are worth mentioning and can also be used for writing microservices:

Vertx, a tool-kit for building reactive applications on the JVM. Some might argue it should have a spot at the big 4.

Spotify Apollo, a set of Java libraries that is used at Spotify when writing Java microservices. Apollo includes features such as an HTTP server and a URI routing system, making it trivial to implement RESTful services.

Additional frameworks include Spark, Ninja and Jodd, and Restlet.

Bottom line: The Java microservices playing field is quite big, and it’s worth to check out the smaller players as well.

6. Microservice Prerequisites

As Martin Fowler said in his microservices prerequisites post, “It’s important to ensure you can react quickly when your monitoring indicates a problem. In particular any incident management needs to involve the development team and operations, both in fixing the immediate problem and the root-cause analysis to ensure the underlying problems are fixed”. Similarly, this thread and post on Hackernews share more issues that might arise if you’re not ready for a microservice architecture.

At OverOps, we’re building a tool that solves this exact pain and shows when, where and why code breaks in production. It’s the only tool that shows you the complete source code and variable state across the entire call stack for every exception, logged warning, and error. Check it out.

Bottom line: Microservices come with a cost, and aren’t a good fit for every system. If you’re choosing a microservice architecture, you should be aware of the costs and identify the processes you should improve before diving in deeper.

Final Thoughts

It doesn’t matter which framework or platform you’re using, building microservices isn’t tightly coupled with any of them. It’s a mindset and an architectural approach, and you should probably choose whichever option you feel you’d be more productive with.

With that said, successfully implementing a microservice architecture doesn’t stop at the application itself. Much of the cost around it comes from so called DevOps processes, monitoring, CI/CD, logging changes, server provisioning, and more. We’ll cover these aspects on the blog in the future and would be happy to hear your thoughts about it and feature them on our next posts. Feel free to get in touch through and @overopshq.

This post can also be found at Takipi.

Understand the needs and benefits around implementing the right monitoring solution for a growing containerized market. Brought to you in partnership with AppDynamics.

Topics:
java ,jvm ,microservices ,framework

Published at DZone with permission of Alex Zhitnitsky, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}