告別爛代碼,一文理解微服務中的模式和反模式
部署模式
如何部署服務是微服務中的一個重要問題,微服務的部署方式非常靈活,有以下的不同選項可供選擇 (參考 open-open.com/lib/view/)
- 多服務共享主機/虛機
- 單服務部署單一主機/虛機
- 單服務部署單一容器(Docker)
- 無服務部署(serverless),例如AWS Lambda
- 使用服務部署平臺 (Kubernetes,Docker Swarm,Mesos, AWS ECS)
不同的部署方式各有優缺點,重點推薦使用容器編排系統的服務部署平臺,能夠提供各種靈活的部署方案。
橫向關注點
微服務的開發過程中常常會花很多時間來處理一些各個服務都會遇到的問題,例如
- 如何管理配置信息,例如用戶名和口令,服務器的網絡地址,等等
- 日志管理
- 健康檢查
- 業務度量數據(Metrics)的收集和分析
- 分布服務的追蹤
- 這里推薦使用一個穩定的微服務框架來處理這些問題,例如基于Java的spring boot,基于Golang的Micro等
API網關
API網關類似服務代理,所有的客戶端都通過API網關提供的統一服務API來消費服務內容。
下面是幾個開源的API Gateway
- Kong ( github.com/Mashape/kong )
- APIAxle ( http://apiaxle.com/ )
- Tyk ( tyk.io/ )
- apiGrove ( http://apigrove.net/ )
- WSO2 API Manager ( http://wso2.com/products/api-manager/ )
服務發現
服務發現是指API網關或者客戶端如何獲得微服務的地址,主要有以下幾種發現方式:
- 客戶端發現
- 服務器端發現
這種方案中的Router可以并入API網關,客戶端直接和網關通信。
兩種方案需要用到服務注冊,,區別在于是否把服務注冊直接暴露給客戶端使用。常見的提供服務發現的注冊開源解決方案有:
- Apache Zookeeper
- Consul
- Etcd
斷路器
當微服務系統中的某個服務出現問題的時候,或者網絡出現時延的時候,調用客戶端會被阻塞,導致大量的調用占用大量的資源。這時候需要引入類似斷路器效果的代理,當出現不健康的服務的時候,斷路器會返回出錯,阻止更多的客戶端掉用,直至服務的健康狀態恢復。
netflix的hystrix提供了類似的服務 github.com/Netflix/Hyst
數據管理
在設計微服務的時候要考慮是否每一個服務擁有自己的數據庫或者是共享數據庫
- 每個服務擁有自己的數據庫
- 共享數據庫
這兩種方式各有優缺點:
- 獨立數據庫使得各個服務完全解耦合,并且可以根據需要選用不同種類的數據庫,但是沒有辦法或者很難在服務之間共享數據
- 共享數據庫能簡化維護和技術棧,但是數據庫成為所有服務的依賴,系統更多的耦合,帶來了不靈活,沒有辦法根據業務需要選擇不同的數據庫種類。
微服務中的反模式
相對于《設計模式》,《反模式》一書可能知道的相對少一點,其實同樣的道理,反模式歸納總結了一些常見的容易犯的設計問題,那么,微服務中有哪些反模式呢?
聚合混亂
軟件設計的一個主要思想“高內聚,低耦合”同樣適用于微服務,隨著系統的發展,應該避免某一個服務變的一場龐大,或者服務之間不必要的過多依賴。
不認真對待自動化
持續集成和交付和微服務相輔相成,自動化的測試,集成,交付和部署是微服務成敗的關鍵。一個自動化程度不高的微服務是很難成功的。
層級的軟件架構
在設計微服務的時候,應該盡可能避免分層的架構,服務之間更多應該是流式調用。例如為所有的服務提供一個數據接入層的數據服務,似乎不是一個好的選擇,因為這樣的化就使得所有的服務依賴該數據服務。微服務更多應該基于業務來設計,每個服務應該自包含。
以下的架構雖然是一種層級架構,但也是可以采用的,條件是不同的服務不應該共享數據。
依賴客戶簽核
當服務有不同的客戶渠道來消費的時候,不應該依賴客戶的簽核,自動化的測試應該覆蓋所有的使用場景。
手工化的配置管理
應該盡量避免手工化地配置管理,實現自動化
避免版本管理
在微服務中,如果你的系統只有一個版本,那么這肯定是有問題的。前向兼容是一個需要支持的目標,也就是說不同的客戶端版本不應該收到服務升級的影響。這也就意味這API一旦發布,就不應該有不兼容的修改。
為每一個服務創建網關
這個就不用多說了,看著就很傻
參考
- microservices.io/patter
- infoq.com/articles/seve















































