Spring Cloud
- 發(fā)布于2015年3月
- 引入NetflixOSS的開源技術(shù)棧
- 基于Spring boot
- 構(gòu)建了分布式系統(tǒng)的公共模式
Spring boot是Spring框架對(duì)“約定優(yōu)于配置”理念的最佳實(shí)踐的產(chǎn)物,比如自動(dòng)配置,它背后通過了Springfactoriesloader,它屬于Spring框架私有的一種擴(kuò)展方案(類似于Java的SPI-Service provider interface), 其主要的功能就是從指定的配置文件meta-inf/spring.factories加載配置。
常見的微服務(wù)組件

服務(wù)端負(fù)載均衡
- HTTP重定向負(fù)載均衡(類似DNS域名解析負(fù)載均衡)
- 優(yōu)點(diǎn)
- 實(shí)現(xiàn)比較簡單
- 缺點(diǎn)
- 瀏覽器需要兩次請求才能完成一次訪問
- 性能較差
- 重定向服務(wù)器自身的處理能力有可能成為瓶頸
- 優(yōu)點(diǎn)

- 反向代理均衡器的優(yōu)點(diǎn)(以Nginx,HA Proxy為代表)
- 比較簡單
- 可以利用反向代理緩存資源
- 改善網(wǎng)站的性能
- 反向代理均衡器的缺點(diǎn)
- 所有請求和響應(yīng)的中轉(zhuǎn)站
- 其性能可能會(huì)成為瓶頸

- 數(shù)據(jù)鏈路層的負(fù)載均衡優(yōu)點(diǎn)
- 不需要修改數(shù)據(jù)包的源地址
- 響應(yīng)數(shù)據(jù)不需要通過負(fù)載均衡器
使用三角傳輸模式的鏈路層負(fù)載均衡是目前大型網(wǎng)站使用最為廣泛的一種負(fù)載均衡手段,在Linux平臺(tái)上面最好的鏈路層負(fù)載均衡開源產(chǎn)品是LVS(Linux Virtual Server)。
以上都是服務(wù)端的負(fù)載均衡,代表的產(chǎn)品有F5,LVS,Nginx,HA Proxy和ELB/ALB等。
客戶端的負(fù)載均衡
在Spring Cloud中提供了Ribbon 作為客戶端的負(fù)載均衡,一般Ribbon和服務(wù)注冊與發(fā)現(xiàn)Eureka一起協(xié)同實(shí)現(xiàn)對(duì)請求的負(fù)載均衡,如圖:

從一個(gè)服務(wù)注冊器中查詢,獲得其中所有可用實(shí)例。然后使用負(fù)載均衡算法(常見的算法:可支持最小連接數(shù)、輪詢、比例、最快響應(yīng)、哈希、預(yù)測、觀察、動(dòng)態(tài)比例等)從多個(gè)服務(wù)實(shí)例中選擇出一個(gè),發(fā)出請求。
如果在有客戶端的負(fù)載均衡情況下,是否還有與服務(wù)端的負(fù)載均衡(比如AWS ELB)混用的情況呢? 在服務(wù)消費(fèi)者與服務(wù)提供者之間增加了ELB類的服務(wù)器端負(fù)載均衡,反而增加了額外的網(wǎng)絡(luò)跳轉(zhuǎn),所以并不推薦,但是可以考慮在Edge Server外添加,如下圖:

服務(wù)注冊與發(fā)現(xiàn)
一個(gè)服務(wù)如何發(fā)現(xiàn)另外一個(gè)服務(wù)的IP和端口呢? 你可能會(huì)說,Hardcode式的靜態(tài)配置,但是當(dāng)服務(wù)按需動(dòng)態(tài)伸縮之后呢?這時(shí)我們就可以引入服務(wù)治理里面非常重要的一個(gè)組件 - 服務(wù)注冊于發(fā)現(xiàn)。
Spring Cloud內(nèi)可選的服務(wù)注冊與發(fā)現(xiàn)Starter很多,這里簡單聊下Eureka和Consul。
- Eureka
- 提供REST接口
- 支持多點(diǎn)的同步(支持集群實(shí)現(xiàn)高可用,P2P的注冊信息同步)
- 支持客戶端緩存(CAP原理中,它保證AP)
- 自注冊的方式(服務(wù)實(shí)例使用 POST 請求來注冊網(wǎng)絡(luò)地址,每三十秒使用 PUT 請求來刷新注冊信息)

- Consul
- 來自Hashicorp公司(旗下知名產(chǎn)品很多,e.g
vagrant,valut) - 提供REST接口(從服務(wù)注冊,查詢存儲(chǔ)鍵值對(duì)到健康檢查,都提供RESTful接口,使得集成不同的技術(shù)棧變的很容易)
- 提供現(xiàn)成的DNS服務(wù)器
- 第三方注冊 - 服務(wù)管理器模式(服務(wù)注冊器會(huì)通過查詢部署環(huán)境或訂閱事件的方式來跟蹤運(yùn)行實(shí)例的更改;一旦偵測到有新的可用服務(wù)實(shí)例,會(huì)向注冊表注冊此服務(wù);服務(wù)管理器也負(fù)責(zé)注銷終止的服務(wù)實(shí)例)
- 來自Hashicorp公司(旗下知名產(chǎn)品很多,e.g

- 其他幾個(gè)主流競品對(duì)比圖:

熔斷器
Hystrix記錄那些超過預(yù)設(shè)定的極限值的調(diào)用。它實(shí)現(xiàn)了circuit break模式,從而避免了無休止的等待無響應(yīng)的服務(wù)。如果一個(gè)服務(wù)的錯(cuò)誤率超過預(yù)設(shè)值,Hystrix將中斷服務(wù),并且在一段時(shí)間內(nèi)所有對(duì)該服務(wù)的請求會(huì)立刻失效。Hystrix可以為請求失敗定義一個(gè)fallback操作,例如讀取緩存或者返回默認(rèn)值(想象一個(gè)場景,一個(gè)下游系統(tǒng)響應(yīng)非常慢,即使我們設(shè)置了超時(shí),也需要等待很長的時(shí)間才能得到錯(cuò)誤返回,假如現(xiàn)在是請求高峰,大量的等待,大量的消耗系統(tǒng)資源,從而讓我們的整個(gè)系統(tǒng)變得非常慢。當(dāng)我們使用斷路器時(shí),或超時(shí),或者返回錯(cuò)誤碼,達(dá)到一定閾值后,它會(huì)自動(dòng)停止向它發(fā)送消息,并調(diào)用相應(yīng)的fallback函數(shù),等同于啟動(dòng)了快速失敗。當(dāng)它恢復(fù)健康后,他會(huì)自動(dòng)重新發(fā)送消息到下游服務(wù))

配置管理
我們?nèi)绾巫雠渲霉芾砟兀?2軍規(guī)里面有描述:將配置一定要從代碼中分離,原因很明顯, 配置是最容易改變的部分, 比如不同regions, 像dev,sys,prod他們連接的第三方服務(wù)地址可能是不一樣的, feature toggle也可能是不一樣的。難道我們每更改一次配置,就需要重新部署嗎?

Spring cloud推薦用配置服務(wù)器做配置管理:
- 默認(rèn)使用GIT,在版本控制之下
- 支持PROPERTY和YAML
- 中心化的動(dòng)態(tài)配置
- 當(dāng)配置改變時(shí),一些BEANS會(huì)被重新初始化,無須重啟,但需要調(diào)用/POST /refresh觸發(fā)
Spring cloud config server可以與Spring cloud bus(基于Spring cloud stream)配合使用,實(shí)現(xiàn)集群配置文件的動(dòng)態(tài)更新:



API網(wǎng)關(guān)
-
客戶端與服務(wù)端直接通信又有那些弊端?
- 客戶端為了獲取某個(gè)數(shù)據(jù)集,可能需要多次請求。
- UI端和微服務(wù)直接耦合在一起。
-
API網(wǎng)關(guān)的好處?
- 減少API請求次數(shù)
- 限流量
- 緩存
- 認(rèn)證
- 監(jiān)控
- 對(duì)外提供統(tǒng)一的接口,使背后的微服務(wù)對(duì)UI端來說是透明的
Spring Cloud提供的組件是ZUUL看門人,一般它負(fù)責(zé)請求轉(zhuǎn)發(fā)、聚合返回的數(shù)據(jù)集,所有來自客戶端的請求都要先經(jīng)過API Gateway,然后路由這些請求到對(duì)應(yīng)的微服務(wù)。
分布式鏈?zhǔn)阶粉?/h4>
Spring Cloud里面對(duì)應(yīng)的組件是Sleuth(埋點(diǎn)和發(fā)送) + zipkin(收集和展示),其實(shí)現(xiàn)原理都來至于Google Dapper: http://bigbully.github.io/Dapper-translation/

以下的操作都會(huì)被自動(dòng)追蹤:

案例演示
之前準(zhǔn)備的一個(gè)用于演示的代碼庫,它采用了常見的微服務(wù)組件,比如我們講過的服務(wù)注冊與發(fā)現(xiàn),負(fù)載均衡,分布式配置服務(wù),網(wǎng)關(guān),hystrix,并使用docker-compose來進(jìn)行服務(wù)的編排,可以下來感受下。
Repo: https://github.com/qinnnyul/spring-cloud-with-docker-demo