Sunday, December 21, 2014

Mircoservices with Java, Spring Boot and Docker

Intro to microservices

One of the current buzz-words flying around is "Microservices".

Most big java apps (web-based at least) are packaged as a big WAR-file. The project is one big app, a monolith. This comes with some problems concerning development.

First the obvious, if you change anything you need to redeploy the whole thing. Even the smallest thing.

Second is scaling. If you need to scale up then you scale the whole application.


So what is microservices? Instead of having a monolith you make services as separate projects.
A service would have just one area of responsibility ex. Login-service.

Pros:
Fast development and deployments
Easier to write tests (small project > don't disturb other tests)
Can redeploy that service without redeploying everything
Scaling, just start another instance of the service (needs a good framework for this!)

Problems

So is it a hail mary-technique?

As always, this technique/architecture has its own flaws and problems.

The main con is the complexity of service-handling. The services needs some way of connecting to each other. And "hard-coding" the connection gives us a BIG risk. Because if you change one service, all the services that uses the API of that service might crash in runtime, fun to be that admin.

And how do we know that a service is down?
Say the login-service goes down, the positive is that the app might still work for the people that is already logged in. But no new logins can occur until the service is up again.
With a good health monitoring system ex. Nagios it can check if the service is down, some can even fix the problem!

Solutions

So how do we solve these problems?

First the decoupling from the API. If the services are decouple and doesn't use the API one-to-one we'll escape the hellish nightmare of the total system crash (in this case, might be others).

So we can use some form of integration system like an ESB (Enterprise Service Buss) or just a messaging system (ex. RabbitMQ or ActiveMQ).
This will send the message in to a queue, the service will then grab the message and handle it (complexity gets higher).


Second

A awesome system would be some form of clustering over different locations, load balancing, service discovery and health monitoring.

Some frameworks can actually call the "mother ship" and say "hey I'm bla bla service and I'm ready to Rock! I'm at this location".
The service would have an adjacent health monitoring script.

Is there an actual solution for ALL of this? Answer: Not that I know, but there is some puzzle-pieces.

My Experiment (the plan!)

I'm going to try to make a simple project using microservices.

I'm going to use Spring Boot for the service. Spring Boot is a small application which has a jetty/tomcat server in it and it can either be run as a WAR or by itself.
I'm going to run it by itself. This becomes a app with 12-20 mb per service.
Gradle will be used for the build and dependency scripts.

After the service-app is done, I will contain it in a simple Docker image that is built on start.

Ain't it a problem to start all these docker containers (I will have 3-5 services)?
No, I will use fig (http://www.fig.sh/index.html) to start all the services at once, and to document all the start-commands, linkages, port exposures and more. To sum it: A docker kick-starter.


Ok so Java: check
Containers: check


So regarding the health monitoring. I will try out Consul (https://consul.io/intro/index.html).
I hope I can rock it good with docker and use both the service discovery and the health monitoring.


Onwards

So right now I have made a test-service (hello world in spring boot) and made a docker image of it and ran it successfully.

I will keep you posted of my results, hopefully I can put it all on github when it's done so you can get all the source code.

Another hope I have is that Docker Swarm takes of and either becomes powerful enough on its own or that some awesome frameworks gets created that uses it.

No comments:

Post a Comment