Offloading microservice settings to a configuration server

One thing that quickly adds up when building a microservice-based solution are all the properties that must be managed. It's one thing to manage a single application's application.yml file, and make tweaks and adjustments. But working with all these services, and having to jump to the correct file underneath each application's src/main/resources folder quickly becomes daunting. On top of that, when trying to make changes or adjustments, it is easy to overlook the settings of one microservice.

A key piece of the twelve-factor app (https://12factor.net/) is externalizing configuration. We already took a big step using Spring Boot's powerful property support. But Spring Cloud brings another key technology to the table that takes property support to the next level--Spring Cloud Config Server.

The Config Server let's us put all the properties into a centralized location, and feed them via an application to our existing microservices.

To see how, let's dive into creating one. First, go to http://start.spring.io and select Config Server (along with our other favorite settings).

When we do that, we get a familiar Gradle build file containing the following dependencies:

    buildscript { 
      ext { 
        springBootVersion = '2.0.0.M5' 
        springCloudVersion = 'Finchley.M3' 
      } 
      ... 
    } 
    ... 
    dependencies { 
      compile('org.springframework.cloud:spring-cloud-config-server') 
    } 
 
    dependencyManagement { 
      imports { 
        mavenBom "org.springframework.cloud:spring-cloud-  
dependencies:${springCloudVersion}" } }

We can explain this preceding build file as follows:

  • spring-cloud-starter-config-server is only needed to run a config server, not a config server client
  • The dependencyManagement shows us the release train of Spring Cloud we are using

In a way very analogous to the Hystrix Dashboard, we will create a Config Server:

    @SpringBootApplication 
    @EnableConfigServer 
    public class LearningSpringBootConfigServer { 
 
      public static void main(String[] args) { 
        SpringApplication.run( 
          LearningSpringBootConfigServer.class, args); 
      } 
    } 

This preceding app isn't hard to unravel:

  • @SpringBootApplication marks this as a Spring Boot application. Since this is the cornerstone of the rest of our microservices (including Eureka), it doesn't use Eureka.
  • @EnableConfigServer launches an embedded Spring Cloud Config Server, full of options. We'll use the defaults as much as possible.
  • It has a public static void main to launch itself.

With that, we just need a couple of property settings in application.yml:

    server: 
      port: 8888 
   
    spring: 
      cloud: 
        config: 
          server: 
            git: 
              uri: https://github.com/gregturn/learning-spring-boot-
config-repo

That's it! That's all we need to build a Config Server. We can launch it right now, but there is one thing missing--all the other properties of the application!

To configure properties for our Eureka Server, we need to add a eureka.yml that looks like this:

    server: 
      port: 8761 
 
    eureka: 
      instance: 
        hostname: localhost 
      client: 
        registerWithEureka: false 
        fetchRegistry: false 
        serviceUrl: 
          defaultZone: 
http://${eureka.instance.hostname}:${server.port}/eureka/

If you'll notice, this is the exact same setting we put into the Eureka Server's application.yml earlier in this chapter. We are simply moving it into our config repo.

To make our Eureka Server talk to a Config Server, we need to add this to its build file:

    compile('org.springframework.cloud:spring-cloud-starter-config') 

What does this single dependency do?

  • spring-cloud-starter-config empowers the Eureka Server to talk to the Config Server for property settings
It's important to note that spring-cloud-starter-config is for clients to the Config Server. The dependency that was added to the Config Server itself was spring-cloud-starter-config-server, which is only needed to create a Config Server.

There is a certain order by which Spring Boot launches things. Suffice it to say, property sources must be read early in the Spring lifecycle in order to work properly. For this reason, Spring Cloud Config clients must have a bootstrap.yml file. The one for the Eureka Server must look like this:

    spring: 
      application: 
        name: eureka 

Not a whole lot needs to be in here, but at a minimum, spring.application.name needs to be set so that the Config Server knows which property file to fetch from its config repo. By default, Spring Cloud Config clients will seek {spring.application.name}.yml, so in this case, eureka.yml.

Assuming we have committed eureka.yml to our GitHub-based config repo and launched the config server, we can actually see what is served up:

Let's tear apart the details of this preceding screenshot:

  • http://localhost:8888/eureka/default looks up spring.application.name=eureka, and finds the default state of things
  • The name eureka is at the top along with information like its label and SHA version
  • The config server entry lists the available Spring property sources (eureka.yml) along with each property found in that property source
It's possible to retrieve different versions of configuration settings. All we have to do is set spring.cloud.config.label=foo in bootstrap.yml to fetch an alternative label. When we use Git as the repository, a label can refer to either a branch or a tag.

In essence, the Spring Cloud Config Server is Yet Another Way to craft a property source that the Spring Framework can intrinsically consume.

Next, let's move all the properties for images from its application.yml file into the config repo's images.yml like this:

    eureka: 
      client: 
        serviceUrl: 
          defaultZone: http://localhost:8761/eureka/ 
 
    spring: 
      cloud: 
        stream: 
          bindings: 
            output: 
              destination: learning-spring-boot-comments 
              group: comments-service 
              content-type: application/json 

With all these settings moved to the Config Server's images.yml file, we can replace the application.yml with the following src/main/resources/bootstrap.yml file:

    spring: 
      application: 
        name: images 

Earlier in this chapter, spring.application.name=images, along with all the other settings, were combined in application.yml. To work with Spring Cloud Config Server, we split out spring.application.name, and put it inside bootstrap.yml.

We can do the same for comments by moving all of its property settings into comments.yml. You can see it at https://github.com/gregturn/learning-spring-boot-config-repo/blob/master/comments.yml, if you wish, along with hystrix-dashboard.yml.

Instead, we'll give comments the following src/main/resources/bootstrap.yml file:

    spring: 
      application: 
        name: comments 

And do the same for our Hystrix Dashboard app:

    spring: 
      application: 
        name: hystrix-dashboard 

You know what's truly amazing about all this? We don't have to touch the services. At all.

Is running lots of microservices inside your IDE driving you nuts? Constantly starting and stopping can get old, real fast. IntelliJ IDEA has the Multirun (https://plugins.jetbrains.com/plugin/7248) plugin that lets you group together several launch configurations into a single command. If you use Eclipse, the CDT (C/C++ Development Tooling) module provides a component called Launch Groups that lets you do the same. The following screenshot shows the IntelliJ IDEA Multirun plugin configured for our microservices.

Notice the little 10 second delay in the bottom-right corner of the preceding screenshot? The Config Server needs to be up and operational before any other services start, or they'll fall on default settings.

Using the Multirun plugin, if we launch everything, we should have a nice little system up:

Each service, when it launches, should show something like this:

Without touching a line of code, and simply moving most of what we've already written into another location (or into bootstrap.yml), we have extracted the entire configuration of our social media site to a remote location, making configuration a snap to maintain.

So, is our little snap-a-picture social media platform ready for IPO? Heh, maybe not yet. But we've made a major enhancement that will make us more stable and ready for growth by breaking things up into microservices without breaking the bank.

There are lots of options in the Spring Cloud Config Server. You can register it with Eureka, direct clients to fail fast if it's not up, have clients retry if its down at startup, and more. Security options include the ability to secure the Config Server so that not just anyone can access it (something we'll visit in Chapter 9, Securing Your App with Spring Boot). For more details, see http://cloud.spring.io/spring-cloud-config.

Spring Cloud Config Server currently supports GitHub, GitLab, and Bitbucket out of the box. This means that you can quickly put your configuration on a publicly hosted GitHub repository, but you can also install GitLab inside your data center, and point there, instead, to reduce the risk of public repository outages.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.200.3