Greetings!
There were time we hard coded configuration properties directly into the code. When we get matured we learnt that it is always a better choice to remove hard coded values from the code and add them as configurable properties. That definitely paid off. For an example we add our database configuration in a separate file so that depending on the environment we can easily change it. We when use profiles we go one step further to add file per environment like dev, live, etc.
How will this effect to microservices architecture? If we are dealing with small number of microservices it is ok to bundle them with the corresponding jar though it is not the microservices way of doing things.
When number of the services are growing how do you maintain your environment? It will be a nightmare to keep a track of all properties in this way. Also, when we automate our release process it will be harder to do so.
This is why in microservices architecture we need to segregate all the service configurations. Application configurations will not bundle with the service instance, instead it will pick its configurations from a central location.
Say what, our microservices will be using another microservices to get their configuration properties!
By the way, how many times have you deployed into production environment with your development environment properties ;)
Complete Source Code
This is what they say;
"Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system. With the Config Server you have a central place to manage external properties for applications across all environments."
Spring cloud config uses file location or github location as the configuration repository which makes maintenance very easy.
Special thing to note here is we need to name file according to our service name.
<service_name>-<profile>.yml
myservice.yml
myservice-dev.yml
Update the application.yml
Start the application and locate to http://localhost:8888/myservice/default
You should get this output.
For the dev profile locate to http://localhost:8888/myservice/dev
Note that this gives both properties though when using in a client dev profile will override the values from the default profile.
Instead of the file location, create a Git repository and commit our service's configuration properties.
Below is the updated application.yml
Re-start the server and you should get the same responses as before.
Spring Boot uses bootstrap file early in the booting process. Hence we can add our service name and configuration service location into boostrap.yml file.
Note: Pay attention to this line;
Fetching config from server at : http://localhost:8888
There were time we hard coded configuration properties directly into the code. When we get matured we learnt that it is always a better choice to remove hard coded values from the code and add them as configurable properties. That definitely paid off. For an example we add our database configuration in a separate file so that depending on the environment we can easily change it. We when use profiles we go one step further to add file per environment like dev, live, etc.
How will this effect to microservices architecture? If we are dealing with small number of microservices it is ok to bundle them with the corresponding jar though it is not the microservices way of doing things.
When number of the services are growing how do you maintain your environment? It will be a nightmare to keep a track of all properties in this way. Also, when we automate our release process it will be harder to do so.
This is why in microservices architecture we need to segregate all the service configurations. Application configurations will not bundle with the service instance, instead it will pick its configurations from a central location.
Say what, our microservices will be using another microservices to get their configuration properties!
By the way, how many times have you deployed into production environment with your development environment properties ;)
Complete Source Code
Do it in Spring way
Sure thing, we are using Spring framework with Spring Boot hence we use Spring Cloud Config.This is what they say;
"Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system. With the Config Server you have a central place to manage external properties for applications across all environments."
Spring cloud config uses file location or github location as the configuration repository which makes maintenance very easy.
Let's create our configuration server
- Generate a project using https://start.spring.io
- Add spring-cloud-config-server as dependencies.
- @EnableConfigServer
- Add configuration repository path.
- Add configurations properties.
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
Boostrap class
@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication
Application properties
Easiest way to add a file repository is using a file location. Let's create default and dev profiles in a file location. (mine is /home/manjula/config-repo)Special thing to note here is we need to name file according to our service name.
<service_name>-<profile>.yml
myservice.yml
message: "Hello from default profile"
myservice-dev.yml
message: "Hello from development team"
Update the application.yml
server:
port: 8888
spring:
profiles:
active: native
cloud:
config:
server:
native:
searchLocations: file:///home/manjula/config-repo
Start the application and locate to http://localhost:8888/myservice/default
You should get this output.
{
"name": "myservice",
"profiles": [
"default"
],
"label": null,
"version": null,
"state": null,
"propertySources": [
{
"name": "file:///home/manjula/config-repo/myservice.yml",
"source": {
"message": "Hello from default profile"
}
}
]
}
For the dev profile locate to http://localhost:8888/myservice/dev
// ommited
{
"name": "file:///home/manjula/config-repo/myservice-dev.yml",
"source": {
"message": "Hello from development team"
}
},
{
"name": "file:///home/manjula/config-repo/myservice.yml",
"source": {
"message": "Hello from default profile"
}
}
// ommited
Note that this gives both properties though when using in a client dev profile will override the values from the default profile.
Using a Git repository
Even though file location solution seems simple and easy, it will add additional problems when working with a team. Also, using a Git repository we can easily manage version history.Instead of the file location, create a Git repository and commit our service's configuration properties.
Below is the updated application.yml
server:
port: 8888
spring:
cloud:
config:
server:
git:
uri: https://github.com/slmanju/microservices-demo
searchPaths: configurations
skipSslValidation: true
Re-start the server and you should get the same responses as before.
Config Client
Now our configuration server is up. We need to update our microservices to fetch the properties from configuration server.Spring Boot uses bootstrap file early in the booting process. Hence we can add our service name and configuration service location into boostrap.yml file.
- Create and update bootstap.yml file.
- Add corresponding property/yml files into configuration repo.
- Update maven dependencies to add config-server.
- Run the application.
Note: Pay attention to this line;
Fetching config from server at : http://localhost:8888
bootstrap.yml
spring:
application:
name: catalog-service
cloud:
config:
uri: http://localhost:8888
add maven dependency
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
Comments
Post a Comment