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

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

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

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

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

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

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

- 其他幾個主流競品對比圖:

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

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

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



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

以下的操作都會被自動追蹤:

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