openplanning

Tìm hiểu về Spring Cloud Config Client với ví dụ

  1. Mục tiêu của bài học
  2. Tạo dự án Spring Boot
  3. Cấu hình Spring Cloud Config Client
  4. Controller
  5. Chạy ứng dụng

1. Mục tiêu của bài học

OK, Chúng ta đang trong serial hướng dẫn lập trình một ứng dụng phân tán sử dụng Spring Cloud. Một ứng dụng quản lý Taxi. Trong bài học trước tôi đã hướng dẫn bạn tạo một ứng dụng Config-Server, nó quản lý các thông tin cấu hình cho các dịch vụ (ứng dụng) khác.
Trong bài học này chúng ta sẽ tạo một ứng dụng "About Company", nó là một ứng dụng độc lập với ứng dụng "Passenger Management" (Quản lý hành khách) và "Diver Management" (Quản lý người lái xe). Với một công ty Taxi lớn, chẳng hạn như Uber, số lượng người dùng truy cập vào website của họ rất lớn, thì việc có riêng một ứng dụng giới thiệu về công ty tách biệt với các chức năng khác là điều nên làm.
Ứng dụng "About Company" sẽ sử dụng một cơ sở dữ liệu độc lập, các thông tin cấu hình Database sẽ được quản lý trên Config-Server. Trong kiến trúc Microservice, ứng dụng này không đơn giản chỉ là một website giới thiệu công ty, nó có thể là một dịch vụ cung cấp các thông tin cho các ứng dụng khác, ví dụ cung cấp thông tin về đường dây nóng, email phản hồi,... Tóm lại nó là một phần trong hệ thống Microservice.
Chú ý, mục tiêu chính trong bài học này là thảo luận và thực hành một ví dụ "Làm thế nào một ứng dụng có thể lấy được thông tin cấu hình của nó đang được quản lý trên Config-Server".

2. Tạo dự án Spring Boot

  • Name: ConfigClientAboutCompany
  • Group: org.o7planning
  • Artifact: ConfigClientAboutCompany
  • Description: Spring Cloud Config Client (About Company App)
  • Package: org.o7planning.aboutcompany
JDBC Driver (MySQL, PostGres,..)
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <scope>runtime</scope>
</dependency>

<dependency>
   <groupId>org.postgresql</groupId>
   <artifactId>postgresql</artifactId>
   <scope>runtime</scope>
</dependency>

<!-- SQL Server - Mssql-Jdbc driver -->
<dependency>
   <groupId>com.microsoft.sqlserver</groupId>
   <artifactId>mssql-jdbc</artifactId>
   <scope>runtime</scope>
</dependency>

<!-- Oracle Driver -->
<dependency>
   <groupId>com.oracle</groupId>
   <artifactId>ojdbc6</artifactId>
   <version>11.2.0.3</version>
</dependency>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
   http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.o7planning</groupId>
   <artifactId>ConfigClientAboutCompany</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>jar</packaging>
   <name>ConfigClientAboutCompany</name>
   <description>Spring Cloud Config Config Client (About Company App)</description>
   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>1.5.9.RELEASE</version>
      <relativePath/>
      <!-- lookup parent from repository -->
   </parent>
   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <java.version>1.8</java.version>
      <spring-cloud.version>Edgware.RELEASE</spring-cloud.version>
   </properties>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-actuator</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-config</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-jdbc</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <scope>runtime</scope>
      </dependency>
      <dependency>
         <groupId>org.postgresql</groupId>
         <artifactId>postgresql</artifactId>
         <scope>runtime</scope>
      </dependency>
      <!-- SQL Server - Mssql-Jdbc driver -->
      <dependency>
         <groupId>com.microsoft.sqlserver</groupId>
         <artifactId>mssql-jdbc</artifactId>
         <scope>runtime</scope>
      </dependency>
      <!-- Oracle Driver -->
      <dependency>
         <groupId>com.oracle</groupId>
         <artifactId>ojdbc6</artifactId>
         <version>11.2.0.3</version>
      </dependency>
      <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <scope>runtime</scope>
      </dependency>
      <dependency>
         <groupId>org.postgresql</groupId>
         <artifactId>postgresql</artifactId>
         <scope>runtime</scope>
      </dependency>
      <dependency>
         <groupId>com.microsoft.sqlserver</groupId>
         <artifactId>mssql-jdbc</artifactId>
         <scope>runtime</scope>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>
   <dependencyManagement>
      <dependencies>
         <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
         </dependency>
      </dependencies>
   </dependencyManagement>
   <repositories>
      <!-- Repository for ORACLE JDBC Driver -->
      <repository>
         <id>codelds</id>
         <url>https://code.lds.org/nexus/content/groups/main-repo</url>
      </repository>
   </repositories>
   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
   </build>
</project>
ConfigClientAboutCompanyApplication.java
package org.o7planning.aboutcompany;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ConfigClientAboutCompanyApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigClientAboutCompanyApplication.class, args);
    }
    
}

3. Cấu hình Spring Cloud Config Client

Ứng dụng này cần đọc các cấu hình của nó đang được lưu trữ trên Config-Server, vì vậy bạn cần phải nói cho nó biết các thông tin về Config-Server. Các thông tin này được cấu hình trên tập tin bootstrap.properties (Hoặc bootstrap.yml). Tập tin này được ứng dụng sử dụng rất sớm trong quá trình ứng dụng khởi động.
Có một chút khác biệt về định dạng của tập tin *.properties và tập tin *.yml, và bạn có thể tìm hiểu thêm trong bài viết dưới đây:
  • properties vs yml
bootstrap.properties
# Read file on Config-Server:
# app-about-company.properties or app-about-company.yml
spring.application.name=app-about-company

# This is the default:
spring.cloud.config.uri=http://localhost:8888
management.security.enabled=false
Cấu hình để ứng dụng này chạy trên cổng 7777:
application.properties
server.port=7777
Tập tin cấu hình cho ứng dụng này (Xem trên GitHub):

4. Controller

MainController.java
package org.o7planning.aboutcompany.controller;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RefreshScope
@RestController
public class MainController {

    // https://github.com/o7planning/spring-cloud-config-git-repo-example
    // See: app-about-company.properties
    @Value("${text.copyright: Default Copyright}")
    private String copyright;

    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;

    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.username}")
    private String userName;

    @Value("${spring.datasource.password}")
    private String password;

    @Autowired
    private DataSource dataSource;

    @RequestMapping("/showConfig")
    @ResponseBody
    public String showConfig() {
        String configInfo = "Copy Right: " + copyright //
                + "<br/>spring.datasource.driver-class-name=" + driverClassName //
                + "<br/>spring.datasource.url=" + url //
                + "<br/>spring.datasource.username=" + userName //
                + "<br/>spring.datasource.password=" + password;

        return configInfo;
    }

    @RequestMapping("/pingDataSource")
    @ResponseBody
    public String pingDataSource() {
        try {
            return this.dataSource.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "Error: " + e.getMessage();
        }
    }

}
@RefreshScope:
Bất cứ Spring Bean nào được chú thích (annotate) bởi @RefreshScope sẽ được làm mới tại thời gian chạy (runtime), và tất cả các thành phần nào sử dụng chúng sẽ nhận được một đối tượng mới trong lần gọi phương thức kế tiếp. Được khởi tạo và tiêm (inject) vào các phụ thuộc đầy đủ.

5. Chạy ứng dụng

Trước hết bạn cần chạy ứng dụng Config-Server. Ứng dụng này sẽ chạy trên cổng 8888.
Test nó với URL sau:
Sau đó bạn chạy ứng dụng ConfigClientAboutCompany, ứng dụng này sẽ chạy trên cổng 7777:
Test nó với URL sau: