前面講了 Eureka 和 Spring Cloud Config,今天介紹一個(gè)全能選手 「Consul」。它是 HashiCorp
公司推出,用于提供服務(wù)發(fā)現(xiàn)和服務(wù)配置的工具。用 go 語言開發(fā),具有很好的可移植性。被 Spring Cloud 納入其中,Eureka
停止新版本開發(fā),更多的想讓開發(fā)者使用 Consul 來作為服務(wù)注冊(cè)發(fā)現(xiàn)使用。
Consul 提供的功能包括如下幾個(gè):
服務(wù)發(fā)現(xiàn)
Consul 讓服務(wù)注冊(cè)和服務(wù)發(fā)現(xiàn)(通過 DNS 和 HTTP 接口)更加簡(jiǎn)單,甚至對(duì)于外部服務(wù)(例如SaaS)注冊(cè)也一樣。
故障檢測(cè)
通過健康檢查,服務(wù)發(fā)現(xiàn)可以防止請(qǐng)求被路由到不健康的主機(jī),并且可以使服務(wù)容易斷開(不再提供服務(wù))。
多數(shù)據(jù)中心
Consul 不需要復(fù)雜的配置即可簡(jiǎn)便的擴(kuò)展到多個(gè)數(shù)據(jù)中心,查找其它數(shù)據(jù)中心的服務(wù)或者只請(qǐng)求當(dāng)前數(shù)據(jù)中心的服務(wù)。
鍵值存儲(chǔ)
靈活的鍵值存儲(chǔ),提供動(dòng)態(tài)配置、特征標(biāo)記、協(xié)作、leader 選舉等功能,通過長(zhǎng)輪詢實(shí)現(xiàn)配置改變的即時(shí)通知。
Spring Cloud Consul 將 Consul 進(jìn)行自動(dòng)配置和進(jìn)一步封裝。
Spring Cloud Consul 可替代已有的 Spring Cloud Eureka,也就是當(dāng)做服務(wù)注冊(cè)發(fā)現(xiàn)框架使用。并且 Eureka 2.x
版本也已經(jīng)停止開發(fā),并且 Spring Cloud 官方也建議用 Spring Cloud Consul 來替代,當(dāng)然如果已經(jīng)用了 Eureka
在項(xiàng)目中也沒有關(guān)系,Eureka 已經(jīng)足夠穩(wěn)定,正常使用沒有任何問題。
Spring Cloud Consul 可替代已有的 Spring Cloud Config ,也就是當(dāng)做配置中心使用。
Spring Cloud Consul 主要用作服務(wù)注冊(cè)發(fā)現(xiàn),并且官方建議替代 Eureka,那么它肯定具有 Eureka
或其他框架不具備的優(yōu)勢(shì),下面看一下對(duì)比它和其他服務(wù)發(fā)現(xiàn)方式做的一下對(duì)比(摘自網(wǎng)絡(luò)):
功能點(diǎn) euerka Consul zookeeper etcd
服務(wù)健康檢查 可配支持 服務(wù)狀態(tài),內(nèi)存,硬盤等 (弱)長(zhǎng)連接,keepalive 連接心跳
多數(shù)據(jù)中心 — 支持 — —
kv 存儲(chǔ)服務(wù) — 支持 支持 支持
一致性 — raft paxos raft
cap ap(高可用、分區(qū)容錯(cuò)) ca(數(shù)據(jù)一致、高可用) cp cp
使用接口(多語言能力) http(sidecar) 支持 http 和 dns 客戶端 http/grpc
watch 支持 支持 long polling/大部分增量 全量/支持long polling 支持 支持 long polling
自身監(jiān)控 metrics metrics — metrics
安全 — acl /https acl https 支持(弱)
spring cloud 集成 已支持 已支持 已支持 已支持
Consul 采用 raft 算法來保證數(shù)據(jù)的強(qiáng)一致性,如此帶來的優(yōu)勢(shì)很明顯,相應(yīng)的也帶來了一些犧牲:
* 服務(wù)注冊(cè)相比 Eureka 會(huì)稍慢一些。因?yàn)?Consul 的 raft 協(xié)議要求必須過半數(shù)的節(jié)點(diǎn)都寫入成功才認(rèn)為注冊(cè)成功;
* Leader掛掉時(shí),重新選舉期間整個(gè) consul 不可用,以此保證了強(qiáng)一致性但犧牲了可用性。
Consul 的安裝和啟動(dòng)
與 Eureka 不同,Consul
需要獨(dú)立安裝,可以到官網(wǎng)(https://www.consul.io/downloads.html)下載。具體操作系統(tǒng)的安裝方式不同,可參考官網(wǎng)。
Consul 提供了一系列的參數(shù),用于在命令行執(zhí)行。Consul 默認(rèn)提供了 web UI 界面來查看配置。通過訪問 server 的 8500
端口可以訪問到 web UI 控制臺(tái)。
開發(fā)過程中,我們可以通過命令 consul agent -dev 來啟動(dòng)開發(fā)模式,啟動(dòng)成功后,訪問 localhost:8500 可以看到當(dāng)前 consul
的所有服務(wù)。如下圖:
更多的在生成環(huán)境的部署可自行搜索相關(guān)介紹,這里暫時(shí)只用 dev 模式啟動(dòng),用來介紹 Spring Cloud Consul 的使用。
實(shí)現(xiàn)服務(wù)提供者
1、引用 spring-cloud-consul
<dependency> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-all</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId> </dependency>
<dependencyManagement> <dependencies> <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-consul-dependencies</artifactId>
<version>2.1.0.M2</version> <type>pom</type> <scope>import</scope>
</dependency> </dependencies> </dependencyManagement>
2、設(shè)置 consul 相關(guān)配置,在 bootstrap.yml 配置文件中,配置如下:
spring: cloud: consul: discovery: service-name: consul-provider ## 服務(wù)提供者名稱
host: localhost ## consul 所在服務(wù)地址 port: 8500 ## consul 端口
3、設(shè)置 server 相關(guān)配置,在 application.yml 配置文件中,配置如下:
spring: application: name: consul-provider server: port: 5000 endpoints:
health: sensitive: false restart: enabled: true shutdown: enabled: true
management: security: enabled: false
4、增加一個(gè) RestController ,寫兩個(gè)測(cè)試服務(wù)方法
@RestController @Slf4j public class HelloController { @Autowired private
DiscoveryClient discoveryClient; @GetMapping(value = "test") public String
test(){ List<String> services = discoveryClient.getServices(); for(String s :
services){ log.info(s); } return "hello spring cloud!"; } @GetMapping(value =
"nice") public String nice(){ List<String> services =
discoveryClient.getServices(); for(String s : services){ log.info("gogogo" +
s); } return "nice to meet you!"; } }
5、Spring boot 啟動(dòng)類
@SpringBootApplication @EnableDiscoveryClient public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args); } }
@EnableDiscoveryClient 注解標(biāo)示這是一個(gè) client 端。
啟動(dòng)這個(gè)服務(wù)提供者,打開 http://localhost:8500 可以看到這個(gè)服務(wù)
實(shí)現(xiàn)服務(wù)消費(fèi)者
1、引用相關(guān) maven 包,除了引用與上面服務(wù)提供者相同的包外,還引用了 openFeign
<dependency> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
2、bootstrap.yml 配置,因?yàn)樽鳛榉?wù)消費(fèi)者,所以設(shè)置不注冊(cè)到 consul
spring: cloud: consul: discovery: register: false
3、application.yml 配置
spring: application: name: consul-customer server: port: 5001 endpoints:
health: sensitive: false restart: enabled: true shutdown: enabled: true
management: security: enabled: false
4、項(xiàng)目啟動(dòng)類
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class
Application { @Bean @LoadBalanced public RestTemplate restTemplate() { return
new RestTemplate(); } public static void main(String[] args) {
SpringApplication.run(Application.class, args); } }
使用 @EnableDiscoveryClient 注解表示作為服務(wù) client 端,@EnableFeignClients 啟用 openFeign 。
5、新建一個(gè) openFeign 服務(wù)接口
@FeignClient(value = "consul-provider") public interface IHelloService {
@RequestMapping(value = "/hello") String hello(); @RequestMapping(value =
"nice") String nice(); }
對(duì)應(yīng)服務(wù)提供者中提供的兩個(gè) RESTful 接口地址
6、實(shí)現(xiàn)一個(gè) RestController 來訪問服務(wù)提供者開放出來的服務(wù)
@RestController public class ConsumerController { @Autowired private
LoadBalancerClient loadBalancer; @Autowired private DiscoveryClient
discoveryClient; @Autowired private RestTemplate restTemplate; @Autowired
private IHelloService helloService; private final static String SERVICE_NAME =
"consul-provider"; /** * 使用普通的 RestTemplate 方法訪問服務(wù) * * @return */
@GetMapping(value = "test") public Object test() { String result =
restTemplate.getForObject("http://"+SERVICE_NAME + "/test", String.class);
System.out.println(result); return result; } /** * 使用 openFeign 方式訪問服務(wù) * *
@return */ @GetMapping(value = "feign") public Object feign() { String s =
helloService.nice(); return s; } /** * 獲取所有服務(wù)實(shí)例 * * @return */
@GetMapping(value = "/services") public Object services() { return
discoveryClient.getInstances(SERVICE_NAME); } /** * 從所有服務(wù)中選擇一個(gè)服務(wù)(輪詢) */
@GetMapping(value = "/choose") public Object choose() { return
loadBalancer.choose(SERVICE_NAME).getUri().toString(); } }
啟動(dòng)消費(fèi)者程序,然后訪問對(duì)應(yīng)的 RESTful 接口,可以得到對(duì)應(yīng)的結(jié)果。
實(shí)現(xiàn)高可用服務(wù)提供者
線上的微服務(wù)最好不要是單點(diǎn)形式,接下來通過配置來啟動(dòng)兩個(gè)服務(wù)提供者,只要保證 service-name 相同,就表示這是同一個(gè)服務(wù)。
1、 bootstrap.yml 配置不變
spring: cloud: consul: discovery: service-name: consul-provider host:
localhost port: 8500
2、application.yml 修改為如下配置
spring: profiles: active: consul-provider1 endpoints: health: sensitive: false
restart: enabled: true shutdown: enabled: true management: security: enabled:
false --- spring: profiles: consul-provider1 application: name:
consul-provider1 server: port: 5000 --- spring: profiles: consul-provider2
application: name: consul-provider2 server: port: 5002
3、之后啟動(dòng)的時(shí)候加上 vm 參數(shù)。分別加上參數(shù):
-Dspring.profiles.active=consul-provider1
-Dspring.profiles.active=consul-provider2
分別在 5000 端口和 5002 端口啟動(dòng)服務(wù)提供者 consul-provider
4、最后仍然訪問消費(fèi)者的 RESTful 接口地址,可以在服務(wù)提供者后臺(tái)看到每次請(qǐng)求調(diào)用的服務(wù)實(shí)例。
用作配置中心
我們知道,Spring Cloud Config 提供了配置中心的功能,但是需要配合 git、svn 或外部存儲(chǔ)(例如各種數(shù)據(jù)庫(kù)),那么既然使用了
Consul ,就可以使用 Consul 提供的配置中心功能,并且不需要額外的 git 、svn、數(shù)據(jù)庫(kù)等配合使用。
接下來,簡(jiǎn)單介紹一下 Spring Cloud Consul 如何用作配置中心。Consul 支持 yaml 和 properties
格式的配置文件內(nèi)容,本例中以 yaml 格式為例。
1、引用相關(guān)的 maven 包
<dependency> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId> </dependency>
2、bootstrap.yml 配置,這里主要設(shè)置有關(guān) config 的參數(shù)
spring: cloud: consul: config: enabled: true # 啟用配置中心 format: yaml # 指定配置格式為
yaml data-key: mysql_config # 也就是 consul 中 key/value 中的 key prefix: config #
可以理解為配置文件所在的最外層目錄 defaultContext: consul-config # 可以理解為 mysql_config 的上級(jí)目錄
discovery: register: false
對(duì)應(yīng)到 consul 上,key/value 里的配置如下:
3、application.yml 配置文件內(nèi)容
spring: application: name: consul-config server: port: 5008 endpoints: health:
sensitive: false restart: enabled: true shutdown: enabled: true management:
security: enabled: false
4、定義配置文件實(shí)體類,指定 @ConfigurationProperties 注解,指定前綴為 mysql,也就是 key/value 配置文件中的頂層
key。
@Component @ConfigurationProperties(prefix = "mysql") public class
MySqlComplexConfig { public static class UserInfo{ private String username;
private String password; public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; } public
String getPassword() { return password; } public void setPassword(String
password) { this.password = password; } @Override public String toString() {
return "UserInfo{" + "username='" + username + '\'' + ", password='" + password
+ '\'' + '}'; } } private String host; private UserInfo user; public String
getHost() { return host; } public void setHost(String host) { this.host = host;
} public UserInfo getUser() { return user; } public void setUser(UserInfo user)
{ this.user = user; } }
5、新建一個(gè) RestController 來獲取輸出 value 內(nèi)容
@RestController @Slf4j public class ConfigController { @Autowired private
MySqlConfig mySqlConfig; @Autowired private MySqlComplexConfig
mySqlComplexConfig; @GetMapping(value = "mysqlhost") public String
getMysqlHost(){ return mySqlConfig.getHost(); } @GetMapping(value =
"mysqluser") public String getMysqlUser(){
log.info(mySqlComplexConfig.getHost()); MySqlComplexConfig.UserInfo userInfo =
mySqlComplexConfig.getUser(); return userInfo.toString(); } }
6、最后,啟動(dòng)應(yīng)用,訪問 RestController 中的 RESTful 接口即可看到配置文件內(nèi)容。
與 Spring Cloud Config 相比,Consul 在控制臺(tái)修改配置后,會(huì)立即更新,不用再結(jié)合 Spring Cloud Bus 之類的配合了。
源碼地址 <https://github.com/huzhicheng/spring-cloud-study/tree/master/consul>
如果你覺得寫的還可以的話,請(qǐng)點(diǎn)個(gè)「推薦」吧
歡迎關(guān)注,不定期更新本系列和其他文章
古時(shí)的風(fēng)箏 ,進(jìn)入公眾號(hào)可以加入交流群
熱門工具 換一換
感谢您访问我们的网站,您可能还对以下资源感兴趣:
调教肉文小说-国产成本人片免费av-空姐av种子无码-在线观看免费午夜视频-综合久久精品激情-国产成人丝袜视频在线观看软件-大芭区三区四区无码-啊啊好爽啊啊插啊用力啊啊-wanch视频网-国产精品成人a免费观看