Sunday, June 12, 2016

Distributed configuration with Spring Cloud

Move from your Monolithic Architecture to a Microservices Architecture style, it implies to deal with some challenges. One of them, is the configuration of all your backend services. Every microservice requires the injection of its configuration. If you don't centralize your configuration, probably you are duplicating a lot of configuration along all your microservices infrastructure.

To make this task easy, it seems that put all your configuration in one place could be a good idea. In fact, it is. When your services are starting up, one of the things that they will do first is to ask for its configuration.

In the next picture you can see the basic workflow of this communication.



Configuration service

To do that, we are going to use Spring Cloud config support. First of all, we need to create a configuration service, that it will expose a Rest API to be able to do the communication that is showed in the picture above. To achieve that is so simple like add in your pom.xml the spring-cloud-config-server dependency as follows:

And in your application.properties add the follow properties:

Finally you have to annotate your class with @EnableServerConfig.

Now we have running our configuration service on port 8888, and is ready to serve configurations to other backend services. Work is almost done.

Client service

Now we are going to do a demo service and configure it as a client of our configuration service.

First of all, to configure a client of the configuration service you have to add the follow dependency in your pom.xml :

Now you have to tell to Spring context that the required configuration is loaded in remote mode. To do this, you need to replace the application.properties by the file bootstrap.properties with the following contents:

Note that in the git repository, the configuration is stored in a hierarchy way. Each backend service has an identifier defined in their bootsrap.properties. For example, a backend service with identifier 'service_1' , its configuration is stored in the file service_1.properties. Also you can define a common configuration called application.properties that is inherited by all services, and also they can override it in their configuration files.

Now when our service_1 is starting, it will ask to configuration service for its configuration before configure the Spring application context.

Then we can create a Rest service which accesses to one property (message.hello) provided by the configuration service.


Ok, we have the work done. But we can improve our solution, with Spring Actuator. If we annotate our Rest service with the annotation @RefreshScope, Spring Actuator can refreshes this bean, and then you can reload the configuration without restart your backend service. Let's see how.

Add the dependency :


After that make sure your class is annotated with @RefreshScope. Finally your can refresh your beans using the endpoints that exposes Spring Actuator in this way:

curl -d {} http://localhost:8080/refresh

And that is all. I hope you found it interesting. See you in the next post.

You can find all the code in the listed links:

3 comments:

  1. Thank you very much Marina ;) . Let me know if you see any mistake or improvement in my solution , of course there are different ways to do that. Feel free to do any sugestion. We keep learning.

    ReplyDelete
  2. very detailed post. Thanks a lot!

    ReplyDelete