0.為什么需要服務(wù)注冊(cè)和發(fā)現(xiàn)
在傳統(tǒng)應(yīng)用中,應(yīng)用部署都是部署在一臺(tái)物理機(jī)器上,ip地址和端口是固定的。這些可能配置在配置文件中,調(diào)用時(shí)從配置文件中讀取就好了。但是在云平臺(tái)中是不適用的,在微服務(wù)中服務(wù)實(shí)例會(huì)因?yàn)閿U(kuò)容、失敗和升級(jí)等因素動(dòng)態(tài)變化的,服務(wù)地址是不固定的。所以客戶端需要更復(fù)雜服務(wù)發(fā)現(xiàn)機(jī)制。
0.1 服務(wù)注冊(cè)
服務(wù)注冊(cè)表是服務(wù)發(fā)現(xiàn)的關(guān)鍵,它包含所有的服務(wù)實(shí)例。服務(wù)注冊(cè)表要求是高可用和實(shí)時(shí)性。
服務(wù)注冊(cè)一般包括:
服務(wù)注冊(cè)
心跳檢查
服務(wù)發(fā)現(xiàn)
取消注冊(cè)
可以作為服務(wù)注冊(cè)的有:
Netflix Eureka: 通過運(yùn)行多個(gè) Eureka servers 達(dá)到高可用。
consul:用于發(fā)現(xiàn)和配置服務(wù)的工具??梢詧?zhí)行狀態(tài)檢查確定服務(wù)可用性。
Zookeeper:一種廣泛使用的高性能協(xié)調(diào)服務(wù),適用于分布式應(yīng)用程序。
0.1.1 第三方注冊(cè)和自注冊(cè)
使用自注冊(cè)模式時(shí),服務(wù)實(shí)例負(fù)責(zé)向服務(wù)注冊(cè)表注冊(cè)和注銷自身。 此外,如果需要,服務(wù)實(shí)例會(huì)發(fā)送心跳請(qǐng)求以防止其注冊(cè)過期。

Netflix OSS Eureka client 屬于自注冊(cè)模式,Eureka client 處理所有的服務(wù)注冊(cè)和取消注冊(cè)。
在Spring Cloud 工程中可以使用注解 @EnableEurekaClient 將服務(wù)實(shí)例自動(dòng)注冊(cè)到Eureka中。
第三方注冊(cè):
使用第三方注冊(cè)模式時(shí),服務(wù)實(shí)例不負(fù)責(zé)向服務(wù)注冊(cè)表注冊(cè)自己。 相反,另一個(gè)稱為服務(wù)注冊(cè)器的系統(tǒng)組件處理注冊(cè)。 服務(wù)注冊(cè)器通過輪詢部署環(huán)境或訂閱事件來跟蹤對(duì)運(yùn)行實(shí)例集的更改。 當(dāng)它注意到新的服務(wù)實(shí)例時(shí),它會(huì)將服務(wù)注冊(cè)表注冊(cè)到實(shí)例。 服務(wù)注冊(cè)商還注銷已終止的服務(wù)實(shí)例。

0.1.2 高可用與一致性
大多數(shù)服務(wù)注冊(cè)表都提供分區(qū)容錯(cuò)以及一致性或可用性。 由于CAP定理,它們不能提供所有三個(gè)。 例如,Eureka提供可用性,Consul和Apache Zookeeper 都提供了一致性。
0.2 主要的服務(wù)發(fā)現(xiàn)模式:client-side discovery 和 server-side discovery
client-side discovery:在客戶端模式中,客戶端負(fù)責(zé)確認(rèn)所有的可用服務(wù)實(shí)例并負(fù)責(zé)負(fù)載均衡。服務(wù)啟動(dòng)時(shí)要把自己的服務(wù)信息(網(wǎng)絡(luò)地址等)注冊(cè)到服務(wù)注冊(cè)表中,服務(wù)down機(jī)時(shí)要從服務(wù)注冊(cè)表中移除。通常使用心跳機(jī)制定期刷新服務(wù)實(shí)例的注冊(cè)。

Netflix Eureka 和 Netflix Ribbon 是這種模式,Eureka 提供服務(wù)注冊(cè)和發(fā)現(xiàn), Ribbon 提供負(fù)載均衡。 這種模式比較簡(jiǎn)單,除了服務(wù)注冊(cè)表之外,沒有其他組件。另外客戶端了解所有可用的服務(wù)實(shí)例,因此可用進(jìn)行智能、特定的負(fù)載均衡策略。缺點(diǎn)是:客戶端與服務(wù)注冊(cè)表耦合在一起,不同的語言和框架必須實(shí)現(xiàn)自己的服務(wù)發(fā)現(xiàn)邏輯。
server-side discovery:
服務(wù)端模式是client發(fā)送一個(gè)請(qǐng)求到Load Balancer,然后LB查找服務(wù)注冊(cè)表并把每個(gè)請(qǐng)求路由到服務(wù)實(shí)例。與客戶端一樣,也需要注冊(cè)和注銷服務(wù)注冊(cè)表

AWS ELB 是這種模式,另外像Nginx plus和Nginx也可以用作服務(wù)端發(fā)現(xiàn)模式 負(fù)載均衡器。
一些部署環(huán)境像 Kubernetes and Marathon 在每個(gè)集群上運(yùn)行一個(gè)代理,這個(gè)代理就扮演了服務(wù)端服務(wù)發(fā)現(xiàn)模式負(fù)載均衡器的角色。
服務(wù)端發(fā)現(xiàn)模式的好處是,客戶端沒必要了解服務(wù)發(fā)現(xiàn)的細(xì)節(jié),只要向負(fù)載均衡器發(fā)送請(qǐng)求就好了,另外不同語言和框架也不需要實(shí)現(xiàn)自己的客戶端。缺點(diǎn)是,除非部署環(huán)境提供負(fù)載均衡器,否則需要自己實(shí)現(xiàn)和管理另外一個(gè)高可用組件。
更多細(xì)節(jié)可參考文章:https://www.nginx.com/blog/service-discovery-in-a-microservices-architecture/
我們這里使用Consul來進(jìn)行服務(wù)注冊(cè)和發(fā)現(xiàn)
1.Consul 介紹
Consul is a distributed service mesh to connect, secure, and configure services across any runtime platform and public or private cloud
Consul是一個(gè)分布式服務(wù)網(wǎng)格,用于跨任何運(yùn)行時(shí)平臺(tái)和公共云或私有云連接,保護(hù)和配置服務(wù)
1.1 install & command
https://www.consul.io/intro/getting-started/install.html
1.2 web
安全啟動(dòng)后默認(rèn)訪問地址: http://localhost:8500/
1.3 Docker compose
docker dev 模式啟動(dòng):
$ docker run -d --name=dev-consul -p 8500:8500 -e CONSUL_BIND_INTERFACE=eth0 consul
https://hub.docker.com/r/library/consul/ docker運(yùn)行consul
https://github.com/emdem/consul-cluster-compose 單機(jī)consul-cluster docker compose 腳本,使用了7個(gè)實(shí)例
https://github.com/hashicorp/consul/blob/master/demo/docker-compose-cluster/docker-compose.yml 官方提供集群DEMO
1.3.1 構(gòu)建啟動(dòng)
我們使用官方集群demo啟動(dòng)
將 docker-compose.yml
docker-compose up 創(chuàng)建容器并啟動(dòng)docker-compose stop
-d 后臺(tái)運(yùn)行
--no-recreate 不重新創(chuàng)建只啟動(dòng)未啟動(dòng)的容器
$ docker-compose up -d --no-recreate
Starting consul_consul-server-2_1 ... done
Starting consul_consul-server-bootstrap_1 ... done
Starting consul_consul-agent-3_1 ... done
Starting consul_consul-agent-1_1 ... done
Starting consul_consul-agent-2_1 ... done
Starting consul_consul-server-1_1 ... done

可以看到consul 有3個(gè)節(jié)點(diǎn)。
http://m.itdecent.cn/p/f8746b81d65d 一個(gè)consul使用的詳細(xì)介紹
http://www.ymq.io/2017/11/26/spring-cloud-consul/ (推薦)更詳細(xì)的可以參考這個(gè)
2.SpringCloud 結(jié)合 consul使用
創(chuàng)建consul-client工程,這里推薦使用 https://start.spring.io 創(chuàng)建工程,因?yàn)镾B1.x 和 SB2.x 在依賴方面改動(dòng)還是比較大的,如果通過網(wǎng)上博客那樣添加出出現(xiàn)各種各樣的問題 o(╥﹏╥)o,IDEA工具自帶。
在Cloud Discovery中選擇 Consul Discovery,同時(shí)選擇 監(jiān)控 actuator,用來做健康檢查,后邊SpringBoot Admin 做監(jiān)控也會(huì)用到。
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
?
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
?</pre>
application.java 中添加 @EnableDiscoveryClient注解
application.yml 文件
server:
port: 8503
spring:
cloud:
consul:
discovery:
health-check-path: /actuator/health # 健康健康路徑,也可以自己寫
health-check-interval: 10s # 檢測(cè)輪訓(xùn)時(shí)間 1m 代碼1分鐘
#instance-id: consul-client00 實(shí)例ID,唯一值
instance-id: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
?
host: localhost
port: 8500
?
application:
name: consul-client
啟動(dòng)服務(wù)實(shí)例:
在 consul-client 根目錄下執(zhí)行 mvn clean package ,我們這里啟動(dòng)兩個(gè)client 實(shí)例
$ nohup java -jar target/consul-client-0.0.1-SNAPSHOT.jar > /dev/null 2>&1 &
$ nohup java -jar target/consul-client-0.0.1-SNAPSHOT.jar --server.port=8503 > /dev/null 2>&1 &
查看 consul UI 控制臺(tái)


github 地址:
https://github.com/dudy0127/spring-cloud