<div><div class="cl-preview-section"><blockquote>
本篇主要介紹了 Spring Boot
如何與 Consul
進行集成,Consul 只是服務注冊的一種實現,還有其它的例如 Zookeeper、Etcd 等,服務注冊發現在微服務架構中扮演這一個重要的角色,伴隨着服務的大量出現,服務與服務之間的配置管理、運維管理也變的難以維護,通過 Consul 可以解決這些問題,實現服務治理、服務監控。
關於 Consul 的更多知識點不在這里贅述,但是在學習本節之前還是希望您能先了解下,請移步我之前寫的 微服務服務注冊發現之 Consul 系列
快速導航
添加maven依賴
在 Spring Boot
項目的 pom.xml
文件中引入 spring-cloud-starter-consul-discovery
啟動器
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
使用 Consul 配置信息時需要引入 spring-cloud-starter-consul-config
依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>
配置文件
系統級配置文件 bootstrap.yml
使用 Spring Cloud Consul Config
,需要配置以下信息在 bootstrap.yml
文件
spring.cloud.consul.host
:配置consul地址spring.cloud.consul.port
:配置consul端口spring.cloud.consul.config.prefix
:配置基本文件,默認值configspring.cloud.consul.config.enabled
:啟動consul配置中心spring.cloud.consul.config.format
:consul上面文件的格式 YAML、FILES、PROPERTIES、默認 KEY-VALUEspring.cloud.consul.config.data-key
:表示 consul 上面的 KEY 值(或者說文件的名字),默認是 data
bootstrap.yml
spring:
cloud:
consul:
host: 192.168.6.128
port: 8500
config:
prefix: config
enabled: true
format: YAML
data-key: user
應用級配置文件 application.yml
定義應用級別的配置在 bootstrap.yml
之后加載,例如搭配 spring-cloud-config
使用。
spring.cloud.consul.host
:配置consul地址spring.cloud.consul.port
:配置consul端口spring.cloud.consul.discovery.enabled
:啟用服務發現spring.cloud.consul.discovery.register
:啟用服務注冊spring.cloud.consul.discovery.deregister
:服務停止時取消注冊spring.cloud.consul.discovery.prefer-ip-address
:表示注冊時使用IP而不是hostnamespring.cloud.consul.discovery.health-check-interval
:健康檢查頻率spring.cloud.consul.discovery.health-check-path
:健康檢查路徑spring.cloud.consul.discovery.health-check-critical-timeout
:健康檢查失敗多長時間后,取消注冊spring.cloud.consul.discovery.instance-id
:服務注冊標識
server:
port: 8082
spring:
application:
name: consul-service
profiles:
active: dev
cloud:
consul:
host: 192.168.6.128
port: 8500
discovery: # 服務發現配置
enabled: true
register: true
deregister: true
prefer-ip-address: true
health-check-interval: 10s
health-check-critical-timeout: 30s
health-check-path: /health
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port} # 應用名稱+服務器IP+端口
配置Consul管理控制台
Consul
提供了 Key/Value
存儲用於存儲配置數據,在 Spring Cloud Consul
中配置默認存儲於 /config
文件夾下,根據應用程序名和模擬 Spring Cloud Config
順序解析屬性的規則來配置文件。
在本例中操作 Consul 管控台建立以下路徑配置:
config
:為配置基本文件,這里默認為config
。consul-service
:為application.yml
中配置的spring.application.name
值。dev
:為application.yml
中配置的spring.profiles.active
值,也是本程序設置環境變量意為開發環境。user.yml
:為配置的文件名,格式為yml
格式。
config/consul-service.dev/user.yml
最終為 Consul 管控台建立的配置數據如下圖所示:
項目構建
注意:以下只貼核心代碼,源碼參見:Github chapter7-1
建立Config獲取Consul配置數據
- 獲取student配置數據
注意以下屬性名要與在 Consul 管控台中配置的一一對應。
@ConfigurationProperties
進行屬性注入
config/StudentConfig.java
@ConfigurationProperties(prefix = "student") public class StudentConfig { private String name; private int age;
<span class="token keyword">public</span> String <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setName</span><span class="token punctuation">(</span>String name<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> age<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setAge</span><span class="token punctuation">(</span><span class="token keyword">int</span> age<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> String <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"大家好我是"</span> <span class="token operator">+</span> name <span class="token operator">+</span> <span class="token string">",今年"</span> <span class="token operator">+</span> age <span class="token operator">+</span> <span class="token string">"歲,我是一名在校大學生!"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
}
- 獲取teach配置數據
同以上 student 配置,我們可以將不同類型的配置分文件進行配置定義
@ConfigurationProperties(prefix = "teach") public class TeachConfig { private String name; private String course;
<span class="token keyword">public</span> String <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setName</span><span class="token punctuation">(</span>String name<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> String <span class="token function">getCourse</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> course<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setCourse</span><span class="token punctuation">(</span>String course<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>course <span class="token operator">=</span> course<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> String <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"大家好我是"</span> <span class="token operator">+</span> name <span class="token operator">+</span> <span class="token string">",是一名大學老師!教同學們學習"</span> <span class="token operator">+</span> course<span class="token punctuation">;</span> <span class="token punctuation">}</span>
}
編寫啟動類調用配置
注解說明:
EnableDiscoveryClient
:讓注冊中心進行服務發現,將服務注冊到服務組件上。RestController
:是@ResponseBody
和@Controller
注解的組合,注明該注解后整個類所有的方法返回值為json格式。SpringBootApplication
:SpringBoot 的啟動注解。EnableConfigurationProperties
:屬性配置的 class 添加到 SpringBoot 的屬性配置注解里,否則不能通過@Autowired
注解注入我們定義的屬性配置類。
接口說明:
/health
:健康檢查接口/user/description
:@Value 注解獲取用戶信息描述接口/user/student/intro
:@ConfigurationProperties 獲取學生簡介信息接口/user/teach/intro
:@ConfigurationProperties 獲取教師簡介信息接口
@EnableDiscoveryClient @RestController @SpringBootApplication @EnableConfigurationProperties({ StudentConfig.class, TeachConfig.class }) public class ConsulApplication {
<span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">"${description}"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> String description<span class="token punctuation">;</span> <span class="token annotation punctuation">@Autowired</span> <span class="token keyword">private</span> StudentConfig studentConfig<span class="token punctuation">;</span> <span class="token annotation punctuation">@Autowired</span> <span class="token keyword">private</span> TeachConfig teachConfig<span class="token punctuation">;</span> <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">"/health"</span><span class="token punctuation">)</span> <span class="token keyword">public</span> String <span class="token function">Health</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"health"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token string">"OK"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">"/user/description"</span><span class="token punctuation">)</span> <span class="token keyword">public</span> String <span class="token function">Description</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> description<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">"/user/student/intro"</span><span class="token punctuation">)</span> <span class="token keyword">public</span> String <span class="token function">StudentIntro</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> studentConfig<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">"/user/teach/intro"</span><span class="token punctuation">)</span> <span class="token keyword">public</span> String <span class="token function">TeachIntro</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> teachConfig<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span>String<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span> SpringApplication<span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span>ConsulApplication<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
}
接口測試
- 健康檢查接口
該接口在服務啟動后且向 Consul 配置中心注冊后,根據 application.yml 文件配置的 health-check-interval 和 health-check-path屬性進行自動調用。
$ curl http://127.0.0.1:8082/health
OK!
注冊成功后展示我們服務的名稱及健康檢查結果如下:
- 獲取教師簡介配置接口
$ curl http://127.0.0.1:8082/user/teach/intro
大家好我是Teach Li,是一名大學老師!教同學們學習Java軟件開發!
- 獲取學生簡介配置接口
$ curl http://127.0.0.1:8082/user/student/intro
大家好我是Jack,今年18歲,我是一名在校大學生!
- 采用 @Value 注解獲取項目描述接口
$ curl http://127.0.0.1:8082/user/description
用戶信息描述
總結
這里我們只介紹了 Consul 在 Spring Boot 的配置功能,關於 Consul 做為注冊中心在下一章節中介紹,本篇中需要注意通過 @Value 注入的屬性,修改 Consul 后需要重啟服務才能生效,通過 @ConfigurationProperties 注入的屬性,在 Consul 管控台修改屬性之后可立即生效。
如遇到其他什么可在SpringBoot-Course issues中提問
資料
- 個人博客: Node.js技術棧
- Spring Boot 實戰系列:https://github.com/Q-Angelo/SpringBoot-Course
- 項目源碼: Github查看本文完整示例 chapter7-1