微服务实战之扩展性
任何微服務的容量都是有限的, 但是理想情況下一般的微服務應該只局限于服務器的數量(計算能力), 存儲的容量和網絡的帶寬.
當用戶的請求和用量增加時, 只要財務預算上沒有問題, 理論上是可以接近無限地擴展的.
實際上, 這個假定往往并不成立, 更大的數據量, 更多的請求, 更高的并發量, 你的服務會撐不住.
你會想到加內存, 加存儲, 加帶寬, 加服務器, 然而事情沒那么容易, 你的應用的服務能力必須能夠隨著資源的增加而線性增加
由于單機的內存, CPU 及帶寬畢竟有限, 所以盡量把你的服務設計成由多個相對獨立的, 無狀態的自治節點組成, 這樣你可以輕松地增加節點來應對不斷增長的服務請求
術語
- Scale up: 向上擴展或垂直擴展
- Scale out: 向外擴展或水平擴展
- Failover: 快速切換從 primary 節點或分區切換到 slave 節點或分區, 以減小對用戶的影響
- Stateless: 無狀態的, 服務器節點本身不存儲狀態, 好處在于可以隨時增加和減少節點, 有利于水平擴展
- Stateful: 有狀態的, 狀態總是存在的, 就看你把它放在哪里, 服務器內存, 數據庫, 或共享的緩存服務器
- Sharding: 根據數據的分布特點以及用途, 將數據集分布在多個數據庫上來存儲, 以避免單機處理能力及存儲限制
要點
服務分離 Separation of services
從自給自足的小農社會到現代化的社會化大分工, 單個人掌握的技能變少了, 不同的人有不同的分工和專長, 社會的生產效率大幅度提高了
微服務就是要把服務做小,做精, 專注于一個相對獨立的領域, 以利于分散風險, 和重用組合, 也有利于服務的擴展, 哪塊是瓶頸, 就優化和擴展哪一塊,而不是所有服務器都要一起升級.
例如我要做一個網絡會議服務器,需要支持文字聊天,音頻視頻對話,桌面共享,文件分享,遠程控制,會議錄制等等,既有控制信令的處理,又有媒體的傳輸,編碼解碼和混音處理,如果都放在一起,可想而知,系統的復雜性大大增加不說,調優和擴展很難做,音視頻的編碼解碼是極其耗費CPU 資源,允許丟包,而控制及文字聊天則不同,必須保證消息可靠傳達,所以還是各自分開為不同的服務為好
無狀態 Stateless
狀態總是存在的, 關鍵看你把它放在哪里, 內存里, 文件里, 數據表里, 還是緩存里?
假如我們把狀態放在單個服務器的內存或文件系統中, 擴展起來就會非常麻煩, 高可靠性也有問題.
狀態需要在不同的服務器之間同步, 才能做到避免單點失敗, 每個服務器保持一致顯然不可能應對海量請求和數據.
- 單臺獨有狀態
- 多臺同步狀態
- 外置共享狀態
只有第三種,你的服務器才可以隨意增加,線性擴展
數據分片 Data sharding
根據地理位置, 用戶組織或數據中心及服務區集群都可以進行數據分片, 假設你有多個客戶, 這些客戶分布在不同的地域, 不同的客戶服務請求和數據大小也不同, 如何進行數據分片呢?
假設你提供的服務是在線教育平臺, 域名是天天向上 www.day-day-up.com, 客戶是各個大大小小的補習班,以及一些在線的教育機構。
你可以根據為不同的客戶(租戶tenant )進行數據分片
- 東方補習學校 https://east-school.day-day-up.com, 這個學校比較大, 有兩個大校區:
- 大中華區
- 東南亞區
- 西方補習學校 https://west-school.day-day-up.com, 這個學校比較小, 只有一個主校區
于是, 我們有如下配置數據表, 放在一個中央數據庫中, 并緩存在 Redis 中
- Tenant 表
| d423b7f7-aa2f-40ee-afe7-6b4e5a245ff3 | 東方補習學校 | 2018-12-31 |
| c5ae1066-522b-4cf3-aba7-923f72f7f07d | 西方補習學校 | 2018-12-31 |
- Org 表
| b30bae13-75ca-4b3c-8998-2d46ba6f74ff | 大中華區 | d423b7f7-aa2f-40ee-afe7-6b4e5a245ff3 |
| c3cd2f82-dde6-481d-b441-d7e4e50e3eb6 | 東南亞區 | d423b7f7-aa2f-40ee-afe7-6b4e5a245ff3 |
| b18dde72-de20-4952-b33c-73da44ebe95a | 主校區 | c5ae1066-522b-4cf3-aba7-923f72f7f07d |
- Sharding 表
| d423b7f7-aa2f-40ee-afe7-6b4e5a245ff3 | b30bae13-75ca-4b3c-8998-2d46ba6f74ff | ajpc_a1 |
| d423b7f7-aa2f-40ee-afe7-6b4e5a245ff3 | c3cd2f82-dde6-481d-b441-d7e4e50e3eb6 | us_a1 |
| d423b7f7-aa2f-40ee-afe7-6b4e5a245ff3 | b30bae13-75ca-4b3c-8998-2d46ba6f74ff | ajpc_b1 |
- DbPool 表
| ajpc_a1 | mysql://username:password@hosta1/mysqldb_name | mysql://username:password@hosta2/mysqldb_name |
| ajpc_b1 | mysql://username:password@hostb1/mysqldb_name | mysql://username:password@hostb2/mysqldb_name |
| us_a1 | mysql://username:password@hosta1_us/mysqldb_name | mysql://username:password@hosta1_us/mysqldb_name |
小貼士 -- 快速生成 UUID
python -c 'import uuid; print uuid.uuid4();'
如何自動擴展和收縮
基本要求:
- 高峰期增加服務器,快速提供服務
- 低谷期減少服務器,提高資源效率
- 而增減服務器由監控和分析程序來觸發
下面這個傳統結構顯然不夠
根據Monitor 和 Metrics 系統所得出的結果決定, 實時增加服務器, 注冊到類似 Consul 的服務發現系統中, 利用它的服務發現和健康檢查功能, 用 consul-template 來刷新更改 HAProxy, Nginx 這樣的軟件負載均衡系統的配置文件并重載 ( F5 , NetScalar 這樣的硬件負載同理), 減少服務器也是一樣的過程.
如圖所示
當然, 你的服務器最好是無狀態的, 否則就很麻煩, 增加服務器時可能要做狀態同步, 關閉服務器時要先將服務器設為 suspend 狀態, 不再接受新的服務, 等到所有服務在這臺服務器已經結束了, 才能關機
參考資料
- Cloud Architecture Patterns for Mere Mortals by Bill Wilder
- Web Scalability for startup engineers
- https://cloud.google.com/solutions/autoscaled-load-balancing-using-haproxy-and-consul-on-compute-engine
作者:瓦爾特有范
鏈接:https://www.jianshu.com/p/3a7d9d34126f
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。
總結
- 上一篇: java xms512m_安装版的tom
- 下一篇: imx6 android快速启动,fre