Last Tuesday I went to a meetup at Pivotal about Building Microservices with Spring Cloud. At my current company we are moving towards a Service oriented architecture and I was curious about some of the projects that appeared recently on Spring source.
I have to say this is one of the talks I learnt more in around hour and a half and, as soon as I got home, I was already coding a configuration service provider for some toy app microservices 🙂
— José David Baena (@josedab) January 13, 2016
In this post I will go through some of the ideas and projects exposed during the talk, so I can come back later when needed.
There are several reasons about why we want to build microservices:
- For a big company: Team independency and possible isolation to external changes
- Wider flexibility on the way of development, policies, build strategy, etc… On a monolith app normally you will have to be strict about how to build things in a certain way.
- Partial availability without having the whole service down (Ex: netflix showing related videos, top picks, etc…)
- Scale up only when it is needed.
- Flexibility on the deployment
For me, the main one is to be able to ship quickly. Chances are that, if you are in a big company and your code touches a monolith app, there could be lot of delays and messages back and forth about what is going on and how the code should be structured. Having small pieces deployable helps to replace parts easily (servers down, bad deployments, bad functionality, wrong system updates…). On top of that, QA can focus on a specific service and integration tests become easier for a microservices (although you need e2e tests as well).
There are also disadvantages about them like:
- Communication over network. This reminds me to The Eight Fallacies of distributed computing.
- Difficulty increased when locating the resources and source code. More awareness required for each of the subsystems. Although there are solutions like service registries.
- Requires lot of discipline and expertise to break down the services in order to avoid bottlenecks or expensive calls over the network.
- Configuration and communication between systems (on a monolith system, configuration can be shared between process on the same machine for example)
On the talk, the main focus was how to build microservices and use some Open source projects to control the communication between them and detect/solve potential issues. On the following lines, i will comment about some of the issues/solutions Spring Cloud solves.
So you decided to build a microservice: This can get done quickly with a Spring Boot app for example. Easy way to set it up is adding configuration properties to a Yaml/properties file, get that information with @Value and start using it.
However, as the number of microservices keep growing, configuration is going to be an issue. You may need to have a way to have the data centralized, so each service knows where/how to connect to, shares common configuration, etc…
The solution is having a configuration microservice that will expose the properties to be consumed by the different microservices. On Spring Cloud you can do that with Spring cloud config. @EnableConfigServer will provide you the centralized configuration server.
Having configuration centralized have now other issues:
- Caching vs no caching calls to the configuration server.
- Ideally we want the microservice to refresh the information only when the configuration has been updated. This means no polling mechanism is required, only a way of telling the microservice to pull the new information
- Each microservice should have a
/refreshendpoint (available through HTTP or JMX), where they connect to the configuration service and request for the latest data. In the same way, there has to be of loading the configuration dynamically. In order to do that, Spring cloud provides a bean refresh mechanism.If interested have a look to
- Each microservice should have a
Microservices phone book
So, we got to a point where you have several microservices going around. This can become quickly unmaintainable: having to ssh into the machines, relying on knowing where everything is, etc… Solving this issue, Netflix open sourced Eureka, a service registry (basically ‘a phone book for the cloud’). Clients could connect to the Eureka server process to see the services that are registered.
When you get to the point you have 600+ microservices, you want to expose some functionality (maybe even composed functionality from different microservices). With a high number of microservices, you would need to check where each data is exposed. Sometimes, you may even need to have composition of services to return all the data required. This implies logic on the client or the backend to deal with the calls to the different services. As the configuration and exposure of services may change with the time, it seems logical to have the routing logic on the backend. A possible solution is a proxy calling to the required microservices.
In order to redirect to the proper microservice or compose responses , the use of Zuul can become handy. Zuul is an edge service that provides dynamic routing, monitoring, resiliency… This could be a solution to compose, routing and monitoring the main entry point of a specific client. This can be used normally as:
- A proxy (for different microservices)
- Api gateway (entry point for a mobile client, while other zuul implementation is dealing with server clients, etc…)
Service is broken. Fallback strategy is needed
After having the functionality exposed and a proxy redirecting to our microservice, the possibility of the service to stop working is likely to happen (memory, system failure, etc). The incoming http connection keeps hanging blocking the client and keeping the resources.
Hystrix is a helpful way to fallback on responses in case something is taking time or is late rather than hanging the service. It also helps when dealing with system exceptions, status codes, etc
On top of the fallback strategy, HystrixDashboard is a nice way of looking the dependencies/entry points of your microservices and how they are https://www.acheterviagrafr24.com/acheter-viagra-sans-ordonnance/ going.
Some stats about the connections?
When having several microservices, each of them communicating through the network, tools for network tracing become handy. Twitter open sourced Zipkin, a tool for distributed tracing. It reminds me to firebug on the UI: simple and direct. When investigating why a call is taking time, with Zipkin you could easily detect the issue and tackle it.
An example of a call visualized with Zipkin could be:
When working with microservices, you have a complete set of tools exposed on the Spring Cloud project. I think it is amazing how much they have advanced in the last couple of years. If you are going on the idea of building microservices, have a look to these tools/ideas:
- Configuration centralized as a microservice
- Eureka for service discovery
- Zuul for proxying and routing
- Hystrix for fallback mechanism when something is wrong
- Hystrix dashboards to detect possible issues on the microservices
- Ribbon for dynamic load balancing
- Zipkin for distributed tracing
I think, I will dedicate a bit more time during the next months and build something to showcase all these tools in depth.