微服務要實現集中管理微服務配置、不一樣環境不一樣配置、運行期間也可動態調整、配置修改後能夠自動更新的需求,Spring Cloud Config同時知足了以上要求。Spring Cloud Config 分爲Config Server和Config Client兩部分,是一個能夠橫向擴展,集中式的配置服務器。spring boot config支持三種存儲方式:本地資源、SVN、GIT。
這裏只介紹GIT的方式。git
Spring Cloud Config 原理圖如圖所示:web
pom.xml以下:spring
<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>com.skyworth.tvmanage</groupId> <artifactId>config-server</artifactId> <version>0.0.1-SNAPSHOT</version> <!-- 必需要引入 springboot parent ,幫咱們實現了不少jar包的依賴管理 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.2.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <dependencyManagement> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!-- 版本集中配置 --> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <dependencies> <!-- springboot 自動集成了mvc,直接引用web組件便可 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- eureka client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- config server --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <!-- bus ribbitmq--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-monitor</artifactId> </dependency> </dependencies> </project>
application.yml :apache
server: port: 8888 spring: application: name: config-server cloud: config: server: git: #服務的git倉庫地址 uri: https://gitee.com/willpan_z/tvmanage #用戶名和密碼 username: **** password: **** #本地git配置路徑 basedir: F:\eclipse-workspace\config #分支 label: tvmanage-config eureka: instance: hostname: config-server prefer-ip-address: true client: serviceUrl: defaultZone: http://skyworth:skyworth1@eureka-server:8761/eureka/,http://skyworth:skyworth2@eureka-server2:8762/eureka/,http://skyworth:skyworth3@eureka-server3:8763/eureka/ #暴露bus-refresh接口用於更新git上的配置 management: endpoints: web: exposure: include: bus-refresh
include: bus-refresh 表示暴露 endpoints 的 /actuator/bus-refresh接口 出去,默認是「health」,「info」bootstrap
在啓動類Application上開啓配置中心的註解:@EnableConfigServer:瀏覽器
@SpringBootApplication @EnableDiscoveryClient @EnableConfigServer public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
啓動服務,先模擬測試一下,在git上直接新建一個common.yml,輸入http://localhost:8888/tvmanage-config/common-a.yml,安全
訪問成功(注:tvmanage-config爲碼雲上分支的名稱,若是沒有放在分支下,去掉便可)springboot
配置服務中心能夠從遠程程序獲取配置信息,http請求地址和資源文件映射以下:,可參考服務器
· /{application}/{profile}[/{label}]mvc
· /{application}-{profile}.yml
· /{label}/{application}-{profile}.yml
· /{application}-{profile}.properties
· /{label}/{application}-{profile}.properties
另外從config-server的控制檯能夠看出,當yml文件從遠端git下載後,會在本地也備份一份,固然這個本地路徑是能夠配置的,
配置命令:spring.cloud.config.server.git.basedir: F:\eclipse-workspace\config
pom.xml依賴:
<!-- eureka --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- config --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-client</artifactId> </dependency> <!-- bus ribbitmq--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> <!-- actuator --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies>
在resources目錄下新建文件bootstrap.yml(這裏有個坑是,eureka的註冊不能寫在遠端,由於要先在eureka註冊後,才能經過eureka服務去找遠端yml)內容:
#前綴路徑 #server: # servlet: # context-path: /tvmanage # 訪問地址:http://localhost:8090/tvmanage/ server: port: 8082 spring: application: name: management-equip cloud: config: discovery: enabled: true service-id: CONFIG-SERVER #對應的配置服務中的應用名稱 name: common #對應config server中配置文件的{label 分支} label: tvmanage-config #對應config server中配置文件的{profile 環境} profile: dev #服務註冊 eureka: instance: hostname: equip prefer-ip-address: true client: serviceUrl: defaultZone: http://skyworth:skyworth1@eureka-server:8761/eureka/,http://skyworth:skyworth2@eureka-server2:8762/eureka/,http://skyworth:skyworth3@eureka-server3:8763/eureka/
啓動類沒有特別須要加的東西。
依次啓動eureka-server,config-server,equip-server,打開瀏覽器訪問:http://localhost:8888/tvmanage-config/common-dev.yml,返回內容:
先說說更新原理:
GIT上的webhook更新調用config server的/monitor(spring-cloud-config-monitor)觸發RefreshRemoteApplicationEvent事件,
而後spring cloud bus的StreamListener監聽RemoteApplicationEvent,經過mq發佈到每一個config client,
而後client接收RemoteApplicationEvent事件來實現refresh。
注:這裏簡單說一下spring cloud bus 和spring cloud stream ,2者都是用來消息代理的,bus主要利用廣播機制實現自動刷新配置,stream主要用於服務間的消息調用。
其實,bus也是基於stream的,它使用了一部分stream的功能。
spring cloud bus實現自動刷新配置的方式有2種:
1. 第一種,bus 的refresh操做發生在client端,而後client端通知消息總線bus這個更新信息,bus再通知其餘client端更新
2. 第二種,bus的refresh操做發生在config server端,config server通知bus,再通知其餘client端去更新
這裏咱們使用第二種方式,原理圖以下:
這裏的遠端GIT使用的是Gitee(碼雲),其 WebHooks 配置方法(本地測試的話,還須要一個內網穿透,這裏使用的是natapp,就很少說了):
這裏設置好了,啓動相關服務(eureka server,config server),點擊測試一下。
當啓動好config server後,咱們打開RibbitMQ:http://localhost:15672 能夠看到cloud bus 自動生成了一個隊列,點擊測試後會有一個消息過來。
通常爲了安全,在git傳輸文件的時候都會進行ssh加密傳輸,這裏簡單說一下公匙的應用。
首先使用git bush 生成公匙,輸入 ssh -keygen
而後根據信息找到公匙生成的位置,打開id_rsa.pub,複製其中的內容
最後在Gitee上找到公匙的管理,添加複製進去就OK了
在配置文件yml中增長一個自定義屬性:
girl: age: 20 name: lili
而後在config client 的controller中或者啓動類中獲取這個自定義屬性(注意增長@RefreshScope 局部刷新註解):
@RestController @RequestMapping("/tvmanage/equip") @RefreshScope public class EquipController { @Value("${girl.age}") private String girl_age; @RequestMapping("hi") public String hi(){ return "hello ,"+ girl_age; } }
而後,咱們把yml中 age改成21,客戶端直接訪問hi()方法,http://localhost:8081/tvmanage/equip/hi ,自動刷新成功