December 04, 2019

Part 11: Microservices(Spring Cloud Config Server)


Cross Cutting Concerns
Cross cutting concerns can be handled by:
  • Microservice chassis - a framework that handles cross-cutting concerns and simplifies the development of services.
  • Externalized configuration - externalize all configuration such as database location and credentials.
In case of Externalized configuration pattern, we externalize all application configuration including the database credentials and network location. On startup, a service reads the configuration from an external source, e.g. OS environment variables, etc.

We can configure properties in application.properties. Configuration can be achieved in many ways:
1). A single application.properties inside the jar.
2). Multiple application.properties inside the jar for different profiles.
3). application.properties outside the jar, kept at the same location where the jar is present. When the jar is executed this application.properties will override the one present inside the jar.
4). application.properties for different profiles at some different location, while starting the jar we can pass the active profile and the path of property files.

With the above ways we can achieve externalized and environment specific properties. But what about consistency, version history and real-time management?
  • Consistency: Suppose the same jar is deployed at multiple servers, when we change the properties we need to change it on all the servers. There might be a chance that we miss updating the property file on one or some of the servers, which will make our system inconsistent.
  • Version History: Where are we maintaining the version history? Well we can use SVN, GIT or CVS.
  • Real-Time Management: Whenever we update a particular property, we need to restart the JAR. Is their any way by which we can get the updated properties without restarting the application?
Config As a Server
What we can do is create a Configuration Server, all the micro-services will go to this server to get the properties.

When a micro-service get the properties from the configuration server? At the service start up? or every-time or whenever the properties are updated? Fetching the properties everytime is a bad idea. Other 2 options can be configured.

To config as a service we can use Apache Zookeeper, ETCD (distributed key-value store), Hashicorp Consul or Spring Cloud Configuration Server.

Spring Cloud Config Server
Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems and it enables engineers to quickly develop cloud-native applications. One of the features is to maintain application configurations outside the application. This will enable configuration change without restarting micro-service application.

With the Config Server, we can have a central place to manage external properties for applications across all environments.

As an application moves through the deployment pipeline from dev to test and into production, we can manage the configuration between those environments and be certain that applications have everything they need to run when they migrate.

The default implementation of the server storage backend uses git, so it easily supports labelled versions of configuration environments as well as being accessible to a wide range of tooling for managing the content. It is easy to add alternative implementations and plug them in with Spring configuration.

Create Spring Config Server Using Git 
Step 1). Create a new project spring-cloud-config-server and add Config Server (spring-cloud-config-server) dependency init.
Step 2). Adding @EnableConfigServer in our main class.
Step 3). Setup the properties file: You will also have to setup server specific properties in application.properties or bootstrap.properties in the 'src/main/resources' folder. The 'spring.cloud.config.server.git.uri' property is the location of the git repo with the property files. Add the below lines in application.properties:

#Server port
server.port = 8085
#Git repo location
spring.cloud.config.server.git.uri=https://github.com/greekykhs/microservices.git
  • server.port defines the port on which the embedded server will start.
  • spring.cloud.config.server.git.uri will bind the git location to look for the configuration. Here we are using local git repo but can be switched to remote got location by just changing this location.
FYI, at https://github.com/greekykhs/microservices.git location I have added a application.properties file which has only one property configured:
my.greeting.message=Hola como estas?

Step 4). Start the server. We can access the properties from the URL:  http://localhost:port_no/file_name_without_extension/profile_name

In my case its http://localhost:8085/application/default When we open it in browser, we can see the properties.

If we make changes in the application.properties in GIT and refresh the above URL, we get the updated configurations.

Setting up Spring Config Client
Step 1). Let's create spring-cloud-config-client project and add Config Client (spring-cloud-starter-config) and Actuator(pring-boot-starter-actuator) dependencies in it.
Step 2). Add the below properties in application.properties.
#Server port
server.port = 8086
Step 3). Add the below properties in bootstrap.properties.
spring.cloud.config.uri=http://localhost:8085
spring.cloud.config.enabled= true

Step 4). Added a GreetingController which has an API 'greetMe'. This API gets the message from 'my.greeting.message' and return it.

Step 5). Make sure spring-cloud-config-server is started. Now start the spring-cloud-config-client and open http://localhost:8086/greet/greetMe

You will see the greeting message as 'Hola como estas?' (which was configured in GIT).

Dynamic config with spring Boot
By default, the configuration values are read on the client’s startup and not again. We can force a bean to refresh its configuration (to pull updated values from the Config Server) by annotating the Controller/ Configuration File/ Bean with the Spring Cloud Config @RefreshScope and then triggering a refresh event.

To trigger the refresh event, we need to send an empty HTTP POST to the client’s refresh endpoint: http://localhost:8086/actuator/refresh. Then you can confirm it worked by visiting the http://localhost:8086/greet/greetMe endpoint.

To use it, you must add org.springframework.boot:spring-boot-starter-actuator to the client application’s classpath.

Download the code till now from below GIT url:
GIT URL: microservices

-K Himaanshu Shuklaa..

No comments:

Post a Comment