簡介
當我們的業務系統越來越龐大復雜的時候,各種配置就會層出不群。一旦配置修改了,那么我們就是必須修改后停服務,然后再上線,如果服務少,我們可以手動來操作,如果是成千上百的服務,如果是手動操作,肯定就不合適宜了,然后SpringCloudConfig就出來了,就是我們通常意義上的配置中心,把應用原本放在本地文件的配置抽取出來放在中心服務器,從而能夠提供更好的管理、發布能力。
SpringCloudConfig分服務端和客戶端,服務端負責將git(svn或本地文件系統)中存儲的配置文件發布成REST接口,客戶端可以從服務端REST接口獲取配置。但客戶端並不能主動感知到配置的變化,從而主動去獲取新的配置,這需要每個客戶端通過POST方法觸發各自的/refresh
。
SpringCloudBus通過一個輕量級消息代理連接分布式系統的節點。這可以用於廣播狀態更改(如配置更改)或其他管理指令。SpringCloudBus提供了通過POST方法訪問的endpoint/bus/refresh
,這個接口通常由git的webhook功能調用,用以通知各個SpringCloudConfig的客戶端去服務端更新配置,本節就講怎么搭建一套自動刷新的spring cloud config
一、創建模塊
模塊結構如下:
二、maven聚合模塊microservice-config的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"> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.5.RELEASE</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.jacky</groupId> <artifactId>miroservice-config</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>microservice-config-server</module> <module>microservice-config-eureka</module> <module>microservice-config-client</module> </modules> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <docker.image.prefix>jacky</docker.image.prefix><!--配置鏡像倉庫的屬性--> <docker.repostory>192.168.6.132:5000</docker.repostory><!--配置鏡像倉庫的對應的地址與端口--> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR7</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> <!--添加利用maven插件構建docker鏡像的插件依賴--> <pluginManagement> <plugins> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.4.13</version> </plugin> </plugins> </pluginManagement> </build> </project>
三、配置中心模塊(microservice-config-eureka)
3.1、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"> <parent> <artifactId>miroservice-config</artifactId> <groupId>com.jacky</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>microservice-config-eureka</artifactId> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <executions> <!--設置在執行maven 的install時構建鏡像--> <execution> <id>build-image</id> <phase>install</phase> <goals> <goal>build</goal> </goals> </execution> </executions> <configuration> <!--安裝了docker的主機,並且打開了api remote接口設置--> <dockerHost>http://192.168.6.130:5678</dockerHost> <pushImage>true</pushImage><!--設置上傳鏡像到私有倉庫,需要docker設置指定私有倉庫地址--> <!--鏡像名稱--> <imageName>${docker.repostory}/${docker.image.prefix}/${project.artifactId}:${project.version}</imageName> <!--鏡像的基礎版本--> <baseImage>java:openjdk-8-jdk-alpine</baseImage> <!--鏡像啟動參數--> <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> </configuration> </plugin> </plugins> </build> </project>
3.2、application.yml
spring:
application:
name: microservice-config-server
security:
basic:
enabled: true
user:
name: jacky
password: admin
server:
port: 9511
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://jacky:admin@localhost:9511/eureka
3.3、啟動類EurekaApplication.java
package com.jacky.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); } }
四、配置中心服務端(microservice-config-server)
4.1、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"> <parent> <artifactId>miroservice-config</artifactId> <groupId>com.jacky</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>microservice-config-server</artifactId> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> <!--配置認證所需要的包--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <executions> <!--設置在執行maven 的install時構建鏡像--> <execution> <id>build-image</id> <phase>install</phase> <goals> <goal>build</goal> </goals> </execution> </executions> <configuration> <!--安裝了docker的主機,並且打開了api remote接口設置--> <dockerHost>http://192.168.6.130:5678</dockerHost> <pushImage>true</pushImage><!--設置上傳鏡像到私有倉庫,需要docker設置指定私有倉庫地址--> <!--鏡像名稱--> <imageName>${docker.repostory}/${docker.image.prefix}/${project.artifactId}:${project.version}</imageName> <!--鏡像的基礎版本--> <baseImage>java:openjdk-8-jdk-alpine</baseImage> <!--鏡像啟動參數--> <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> </configuration> </plugin> </plugins> </build> </project>
4.2、application.yml文件
server:
port: 9518
eureka:
instance:
prefer-ip-address: true # 開啟健康檢查(需要spring-boot-starter-actuator依賴)
lease-expiration-duration-in-seconds: 90 #續約到期時間(單位 S)默認是90S
lease-renewal-interval-in-seconds: 30 # 續約更新時間間隔(默認30秒)
instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
client:
serviceUrl:
defaultZone: http://jacky:admin@localhost:9511/eureka/ #把configservice注冊到eureka上,以便於客戶端通過eureka上注冊的信息找到configservice
#實現的基本的 HttpBasic 的認證
security:
basic:
enabled: true # 開啟基於HTTP basic的認證
user:
name: jacky123 # 配置登錄的賬號
password: admin123 # 配置登錄的密碼
#
spring:
application:
name: microservice-config-service
cloud:
config:
server:
git:
uri: http://git.oschina.net/jacky-lulu/microservice-config-repo #配置git倉庫位置
clone-on-start: true #在啟動的時候克隆倉庫
search-paths: '{application}' #配置倉庫路徑下的相對搜索位置,可以配置多個
username: myuser #填寫git倉庫的用戶名
password: mypass #填寫git倉庫的密碼
rabbitmq:
host: 192.168.6.130
port: 5672
username: myuser
password: mypass
4.3、啟動類ConfigServerApplication.java
package com.jacky.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.config.server.EnableConfigServer; @SpringBootApplication @EnableDiscoveryClient @EnableConfigServer public class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); } }
五、客戶端(microservice-config-client)
5.1、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"> <parent> <artifactId>miroservice-config</artifactId> <groupId>com.jacky</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>microservice-config-client</artifactId> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <executions> <!--設置在執行maven 的install時構建鏡像--> <execution> <id>build-image</id> <phase>install</phase> <goals> <goal>build</goal> </goals> </execution> </executions> <configuration> <!--安裝了docker的主機,並且打開了api remote接口設置--> <dockerHost>http://192.168.6.130:5678</dockerHost> <pushImage>true</pushImage><!--設置上傳鏡像到私有倉庫,需要docker設置指定私有倉庫地址--> <!--鏡像名稱--> <imageName>${docker.repostory}/${docker.image.prefix}/${project.artifactId}:${project.version}</imageName> <!--鏡像的基礎版本--> <baseImage>java:openjdk-8-jdk-alpine</baseImage> <!--鏡像啟動參數--> <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> </configuration> </plugin> </plugins> </build> </project>
5.2、application.yml文件
server:
port: 8081
5.3、bootstrap.yml文件
spring:
cloud:
config:
username: jacky123 #configservice認證的用戶名
password: admin123 #認證密碼
label: master # 倉庫的分支節點
discovery:
enabled: true
service-id: microservice-config-service
profile: dev #倉庫中對應文件的環境,如dev、prod、test等
fail-fast: true
bus:
trace:
enabled: true #開啟消息跟蹤
application:
name: microservice-config-client
rabbitmq:
host: 192.168.6.130
port: 5672
username: myuser
password: mypass
eureka:
client:
serviceUrl:
defaultZone: http://jacky:admin@localhost:9511/eureka
instance:
prefer-ip-address: true
management:
security:
enabled: false #刷新時關閉安全認證
注意:
上面這些屬性必須配置在bootstrap.yml,服務端的配置內容才能正確加載。因為通過bootstrap.yml的加載優先級比配置中心的服務端的高,服務端加載優先於application.yml,所以如果你把上面的配置寫在application.yml中,相當於默認不是從配置中心的服務端中讀取的配置信息,而是spring boot的默認加載。啟動的時候就會看到加載的配置,不是配置中心得配置內容,而是默認的本地的
5.4、啟動類(ConfigClientApplication.java)
package com.jacky.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class ConfigClientApplication { public static void main(String[] args) { SpringApplication.run(ConfigClientApplication.class, args); } }
5.5、控制層類(ConfigClientController.java)
package com.jacky.cloud.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RefreshScope @RestController public class ConfigClientController { @Value("${profile}") private String profile; @GetMapping("/profile") public String getProfile() { return this.profile; } }
六、在碼雲創建git項目,放置配置文件
地址:https://gitee.com/jacky-lulu/microservice-config-repo
七、測試
7.1、http://localhost:9511/
7.2、http://localhost:9518/microservice-config-client/dev
7.3、http://localhost:8081/profile
現在把碼雲上的配置文件 microservice-config-client-dev.yml 改為
profile : helleWordDevUpdate
然后發送post請求到配置中心服務端 http://localhost:9518/bus/refresh
再次訪問客戶端
可以看到自動刷新成功