分佈式系統中,因爲服務數量巨多,爲了方便服務配置文件統一管理,實時更新(有某些配置信息變化有必定頻率和規律,而且但願可以作到儘可能實時(營銷類,或活動類應用系統)),因此須要分佈式配置中心組件。 分佈式配置統一解決方案主要目標java
部署極其簡單
: 同一個上線包,無須改動配置,便可在多個環境中(RD/QA/PRODUCTION) 上線部署動態化
: 更改配置,無需從新打包或重啓,便可實時生效統一管理
: 提供web平臺,統一管理 多個環境(RD/QA/PRODUCTION)、多個產品 的全部配置支持微服務架構
目前流行的配置管理平臺有360的QConf
,百度的disconf
,淘寶的diamond
等等,相比較同類產品: git
Spring Cloud Config
最大的優點是Spring無縫集成, Spring應用程序的遷移成本很是低,在配置獲取的接口上是徹底一致, 結合SpringBoot可以使你的項目有更加統一的標準(包括依賴版本和約束規範),避免了應爲集成不一樣開軟件源形成的依賴版本衝突。
支持任何語言的任何應用。它也能爲你支持對應用開發環境、測試環境、生產環境的配置、切換、遷移。默認的配置實現經過git實現,同時很是容易的支持其餘的擴展 github
Spring Cloud Config
本來放在本地
文件的配置抽取出來放在中心服務器
,從而可以提供更好的管理、發佈能力。web
服務端
: 負責將git svn中存儲的配置文件發佈成REST接口客戶端
: 能夠從服務端REST接口獲取配置,客戶端並不能主動感知到配置的變化,從而主動去獲取新的配置,由消息總線來通知各個Spring Cloud Config的客戶端去服務端更新配置。####服務端配置 添加依賴redis
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!-- 可選,安全認證 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
複製代碼
開啓服務註冊(@EnableConfigServer
開啓)spring
@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
複製代碼
增長配置數據庫
spring:
application:
name: config-server
cloud:
config:
label: master
server:
git:
uri: https://github.com/ohcomeyes/spring-cloud.git #注意use https not use ssh
force-pull: true
search-paths: config
# username: ********
# password: ********
server:
port: 8888 # eureka中默認讀取的端口是8888
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
# 須要添加上面所說的安全認證依賴 ConfigSever 默認實現的基本的 HttpBasic 的認證。
security:
user: # user 就是用戶名
password: 123
複製代碼
添加依賴api
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
複製代碼
開啓服務緩存
@EnableEurekaClient
@RestController
@SpringBootApplication
public class EurekaProviderApplication {
@Value("${server.port}")
String port;
// 經過 @Value 獲取服務端的 content 值的內容
@Value("${version}")
String version;
@GetMapping("/")
public String home() {
return "Hello home,port:"+port+"--version:"+version;
}
@GetMapping("/dc")
public String home1() {
return "hello home1 ,port:"+port+"--version:"+version;
}
public static void main(String[] args) {
SpringApplication.run(EurekaProviderApplication.class,args);
}
}
複製代碼
添加配置安全
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: eureka-provider
cloud:
config:
label: master #遠程倉庫的分支
profile: dev # 配置文件
discovery:
enabled: true # 從配置中心讀取文件。
service-id: config-server # 經過服務名稱去 Eureka註冊中心找服務
server:
port: 8081
複製代碼
注意
: 倉庫的配置文件按照{application}-{profile}.yml
或者{application}-{profile}.properties
格式命名,
config-client
的配置文件名和配置中心的{application}
名相匹配。
http請求地址和資源文件映射以下:
/{application}/{profile}[/{label}]
*/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
啓動全部服務後,就能發現全部服務可以從配置中心獲取到配置信息了
上面講的是服務統一從配置中心獲取配置信息,下面講講怎麼來刷新 Spring Cloud Config 中使用 Refresh
要在微服務運行期間動態刷新配置,能夠經過調用/refresh實現,但這樣只能針對單個服務,並且要手動操做 添加依賴
<!-- actuator 健康監控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
複製代碼
添加配置
# 說明:
# 1.要經過actuator暴露端點,必須同時是啓用(enabled)和暴露(exposed)的
# 2.全部除了/health和/info的端點,默認都是不暴露的
# 3.全部除了/shutdown的端點,默認都是啓用的
# PS.生產環境因爲安全性的問題,注意不要暴露敏感端點
# springboot 1.5.X 以上默認開通了安全認證,下面配置關閉
management:
security:
enabled: false // 指定訪問信息不進行用戶驗證
複製代碼
開啓服務
//經過 @RefreshScope 開啓 SpringCloudConfig 客戶端的 refresh 刷新範圍,
//@RefreshScope要加在聲明@Controller聲明的類上,不然refresh以後Conroller拿不到最新的值,會默認調用緩存。
@RefreshScope
@EnableEurekaClient
@RestController
@SpringBootApplication
public class EurekaProviderApplication {
@Value("${server.port}")
String port;
// 經過 @Value 獲取服務端的 content 值的內容
@Value("${version}")
String version;
@GetMapping("/")
public String home() {
return "Hello home,port:"+port+"--version:"+version;
}
@GetMapping("/dc")
public String home1() {
return "hello home1 ,port:"+port+"--version:"+version;
}
public static void main(String[] args) {
SpringApplication.run(EurekaProviderApplication.class,args);
}
}
複製代碼
上面講到的是手動刷新,還只能針對單個服務,下面講講怎麼經過消息總線來廣播式自動刷新,經過RabbitMQ
或kafka
加 Git
的Webhooks
來觸發配置的更新 Spring Cloud Bus
事件處理機制和消息中間件消息的發送和接收整合起來,主要由發送端、接收端和事件組成。針對不一樣的業務需求,能夠設置不一樣的事件,發送端發送事件,接收端接受相應的事件,並進行相應的處理,用於實現微服務之間的通訊。本質是利用了MQ的廣播機制在分佈式的系統中傳播消息 。
默認經常使用rabbitmq
和kafka
兩個binder,說到rabbitmq,先了解下消息隊列 kafka和redis中的消息隊列區別:
好比kafka中發佈一個東西,多個訂閱者能夠分組,(同一個組裏只有一個訂閱者)會收到該消息,這樣能夠用做負載均衡。
消息隊列(MQ) 消息隊列(Message Queue)是一種應用間的通訊方式,消息發送後能夠當即返回,由消息系統來確保消息的可靠傳遞。消息發佈者只管把消息發佈到 MQ 中而不用管誰來取,消息使用者只管從 MQ 中取消息而不論是誰發佈的。這樣發佈者和使用者都不用知道對方的存在。
其它常見場景包括最終一致性、應用解耦(訂單-庫存)、廣播、錯峯流控(秒殺等)等等
MQ和RPC的區別
RabbitMQ RabbitMQ是實現了高級消息隊列協議(AMQP)的開源消息代理軟件,也稱爲面向消息的中間件,是一個在AMQP基礎上完整的,可複用的企業消息系統。它能夠用於大型軟件系統各個模塊之間的高效通訊,支持高併發,支持可擴展。
AMQP
:Advanced Message Queue,高級消息隊列協議。它是應用層協議的一個開放標準,爲面向消息的中間件設計,基於此協議的客戶端與消息中間件可傳遞消息,並不受產品、開發語言等條件的限制。RabbitMQ 最初起源於金融系統,用於在分佈式系統中存儲轉發消息,在易用性、擴展性、高可用性等方面表現不俗。具體特色包括:
靈活的路由
消息集羣
高可用
多種協議
多語言客戶端
管理界面
跟蹤機制
插件機制
webhooks
webhook
:是個在特定狀況下觸發的一種api. 愈來愈多在web上的操做被描述爲事件向服務實例請求Spring Cloud Bus的/bus/refresh
接口,從而觸發總線上其餘服務實例的/refresh
, /bus/refresh
接口還提供了destination
參數,用來定位具體要刷新的應用程序
在github
上有關於Spring Cloud
完整的部署。
其它相關文章
Spring cloud(1)-簡介以及選擇
Spring cloud(2)-服務發現(Eureka,Consul)
Spring cloud(3)-負載均衡(Feign,Ribbon)
Spring cloud(4)-熔斷(Hystrix)
Spring cloud(5)-路由網關(Zuul)
Spring cloud(6)-配置管理及刷新(Config,Bus)
最後,給個 star 吧~
我的博客~
簡書~