Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.
See all our reports

Building “Bootiful”­ Microservices with Spring Cloud by Josh Long

josh

Yesterday, the Virtual JUG hosted its second session with Josh Long. This time it was all about building microservices using Spring Boot for development and deploying them to Spring Cloud. Josh is a Spring Developer Advocate at Pivotal, an author of multiple books on real life Spring and a frequent traveller to myriads of Java conferences and meetups around the world. As mentioned, this is the second time, Josh was joining Virtual JUG to deliver a session and as always it was a really great talk.

Here’s the full video of the session, dive in!

So here’s what I took away from this fast-paced session.

Microservices

When we talk about microservices, you have to remember that it’s not a new concept. Already in 1992 there were talks about microkernels and the design of Linux and splitting functionality into smaller chunks that while harder to implement than a monolithic app, but much easier to maintain later.

Screenshot 2015-04-09 19.13.01

Now, contrary to the Linux story, where the monolithic design has mostly won, we’re talking about web-scale architectures and the likes of Twitter, Netflix, Ebay, Google that have successfully split their products into microservices and enjoy the benefits. So the question now is: how can your projects benefit from the less monolithic architectures.

The world has changed a lot in the last 10 years, social came and now everyone is connected to a network of people. Then we got mobile and even more devices joined the race to be served by your servers. Now the Internet of Things is coming around and everything, literally everything, gets an IP address and will be able to connect to your applications.

Below is a slide from Josh’s talk with a list of what you want the API to look like. For the rest of the talk we’ll focus on communication via API and discoverability, though not exactly through HATEOAS.

Screenshot 2015-04-09 19.24.21

Building a microservice is not hard, and I’m pretty sure you’ve seen it already and can write your own HelloWorld app in a matter of minutes.

Josh showed us a very concise example of a Groovy app that uses Spring Boot. Check out the full code below. Yeah, that is it.

@Grab(“spring-boot-starter-actuator”)
@RestController
class GreetingRestController {
  @RequestMapping(“/hi/{name}”)
  def hi(@PathVariable String name) {
    [greetings : “Hello, “ + name + “!”]
  }
}

There’s quite some magic here, like the @Grab annotation that will find the artifact by id, which in our case is the spring-boot-starter-actuator, which is download and added to the classpath.

One spring run hi.groovy later, and the app is ready and accessible via HTTP.

This is how easy it is to get a microservice up and running. Also there are many operation friendly ways to configure the resultant application: system properties, environment variables and so forth. So you’ll have no trouble to configure it running on your machine a Docker container or some staging environment, and you won’t be embarrassed to deliver an unconfigurable artifact to the Ops teams.

Now, there are several ways to start a Spring Boot project, you don’t have to go command line first. For example you can go to start.spring.io and fill a form with the basic data for the project. This will generate you an archive with the project starter that you can download and import and you’re good to go.

Building a proper system

Now we have a microservice ready and building was easy. However, to create a useful system out of these tiny blocks of functionality you’ll have to create many more of them. That’s where the problem starts, scaling the number of microservices you deploy, increasing their dependencies on each other, configuration problems and so forth. In the session Josh continued to show how to build an infrastructure that handles the hordes of microservices in an appropriately painfree way.

The main idea here is to design a system that is as tolerant to individual failures. Spring Cloud is a set of APIs that integrate a set of useful tools, some developed by Netflix, which is the classic example of a microservicy system, some just from the community or other vendors: Spring security, single sign on, ZooKeeper, Console are to name a few.

Configuration service

The central piece of any set of microservices is the centralized configuration service. All our components will boot up, and turn to the configuration to get all the information they need for future work. Introducing such a central dependency might not seem a good idea, however, given the simplicity of its functionality, it’s pretty straightforward to ensure high availability and you cannot possibly think that managing configuration in every single deployment when you have hundreds of microservices is worth it.

Such a central service shines the most when you want to have an audit log to see who made changes to which configs.

So for the session, Josh built a simple Spring Boot application to manage the configs. If you’re a supporter of the idea that Java is verbose, you might get really impressed here. Below is the full code of the configuration microservice:

@EnableConfigServer
@SpringBootApplication
public class ConfigurationApplication { 
  public static void main(String[] args) {
  	SpringApplication.run(ConfigurationApplication.class, args);
  }
}

Really? Really! The @EnableConfigServer is a Spring Cloud annotation that takes care of everything necessary to build a configuration server. The only thing left is to specify what files the config is going to be taken from. And straight away we have our central piece of our infrastructure ready.

Discovery service

The next major piece of functionality any microservices farm needs is a service registry. This is where all your components will turn to for discovering the actual URLs which they can use to communicate to other parts of your system.

In the session, Josh built a service registry based on Eureka by Netflix. The service registry can depend on the configuration service we already have available, and to use that you just need to declare one Maven dependency. Color me impressed.

Obviously you have other options to build a cluster management system, ZooKeeper or anything else. Eureka has an advantage that’s it’s implemented in Java, so it fits our needs perfectly. The code for this is as trivial as we’ve seen for the configuration service above. Everything is taken care by a dependency managed by Maven and we just declare the need for the registry and configure it.

Now we have the configuration and the discovery service in place, so it’s time to create some actual services to communicate to each other.

Your service

So your microservice could be a Spring Boot application, it doesn’t have to be, but it’s a good way to be consistent with the other apps we’ve seen here.

The spring-cloud-starter-eureka dependency will take care of registering this service to the Eureka discovery service, so the app will become available to the other components in our system. The configuration will come from the config service, so naturally, the example Bookmark service that Josh showed consisted of a single class and a tiny properties file that provided the name of the app and the location of the configuration service. Dead simple.

The best part is that not only can you provide the configuration to your app like that, but you can also change it on the fly by modifying the config in the central configuration microservice and using @RefreshScope Spring Cloud annotation on the component that needs to update the config in the actual app.

Note, that this on-the-fly configuration change is quite different from what JRebel code reloading functionality does for you during the development of the app, but is majorly useful in production systems.

In the same fashion you can build other microservices to join your cluster, but let’s get into a more complex example that showcases the microservice that consumes other services through the API. That’s how you organise the fleet of individual components into the structure.

There are a number of libraries that are worth checking out for this use-case. In the session Josh used the following dependencies to build an application that consumes other microservices in a sane manner.

Feign – by Netflix for a declarative REST client, you declare what the URL looks like and let Feign take care of the rest, calling, substituting query parameters, parsing and converting JSON blobs into actual objects.

Zuul – a client side micro proxy, again by Netflix. The main idea is to make the backend microservices available through their consumers. This way you application can access a central service and actually be served by other components through it.

Hystrix – a library for enabling the circuit breaking pattern. If the calls to some services fail, you want to provide sensible fallback mechanisms and Hystrix allows you to do that easily.

The best part is that you can make use of all these libraries just using annotations: @EnableZuulProxy, @EnableFeignClients, @EnableCircuitBreaker.

Now, to consume other services you can use the DiscoveryClient class and just directly obtain the list of instances of services by their name. This will make a call to Eureka service to figure out what instances of the queried service are available.

Or you can use something fancier, for example RestTemplate uses URLs in the form of:
http://service-id/{parameter}/something/something

The RestTemplate will turn the non-sensible host name into the proper host and port pair by querying the discovery service on the fly!

Another way to consume the REST endpoint is to use @FeignClient on an interface and declaratively specify what paths the requests should go to and how to parse the responses.

On the screenshot below you can see two of them.

Screenshot 2015-04-10 20.16.27

By the way, would you believe 5 years ago if I’d tell you that you’ll be able to fit two REST clients in a single screenshot?!

Since this post length is getting out of hand, you’ll have to check the session video to see the example of using Hystrix to specify the fallback mechanisms in the case some of your microservices are not available at the time of the call. It’s done in a now common fashion of putting annotations on the fields and methods.

During the session, Josh built a dashboard application to show how the Hystrix provides the monitoring capabilities to your system.

From here you can now go ahead and conquer the world. You have a solid infrastructure of microservices that can be run as jar files or packaged into Docker containers and deployed to any available PaaS. The one Josh recommends is CloudFoundry by Pivotal which has native support for all the Spring stach and now the native support for Docker containers.
Build, deploy and scale your system while keeping the individual components small and manageable.

I might be pushing it a bit, but if you read upto this point, I think you will have most likely reached approximately the same conclusion. One of the main takeaways from this session is: Stop writing code like it’s 2005.

Interview and final words

After the session, Josh took some time to answer some questions for the regular RebelLabs interview. If you haven’t seen any of them before, check out the previous ones, including Aleksey Shipilev or Markus Eisele.

If you know Josh already, you’ll know that he’s extremely energetic and fun to talk to, so with great pleasure I present you the video of him answering to some questions like how would he approach splitting a monolithic project into microservices and in what direction is Pivotal taking Spring. Also you’ll learn about his dev setup, his favourite tools and what he thinks is important in life.

As always, It’d be really cool if you’d subscribe to our newsletter, we’ll send you an occasional email about our blogposts, reports, or ongoing surveys that we run once in a while. Just enter your email below and we’ll stay in touch.

 

  • Norbertas GL

    Great stuff, i will be implementing it into our next project. I just need to figure out how to secure everything properly.