微服务设计简单实践---从一个简单需求学习微服务思想
從一個案例來看,如何在做架構設計時利用微服務的思想來幫我們解決問題。
?
背景介紹
公司對產品服務的管理目前還停留在物理機的那種理念,雖然阿里云、AWS、騰訊云、OpenStack等云平臺用的不亦樂乎,但仍然停留在針對hostname和ip的管理上。如果想發布一個新版本,需要將設計到的所有機器的ip整理到一起,然后借助Ansible將產品更新上去。
這種現狀的形成,并不只是技術上的落后,還有成本上的限制,畢竟包年付費模式要比按需付費便宜一大半。但是給運維團隊帶來的困擾也很大,畢竟遇到高峰期還是需要多備一套擴容組來扛流量,運維工程師除了要維護“靜態的”云實例,還要維護這部分“動態的”云實例,運維成本很大。產品迭代后,包年的實例通過Ansible更新好后,運維工程師還要登陸到云平臺上,選中一個更新后的實例,導出鏡像,再將這個鏡像更新到伸縮組的伸縮規則,這樣才能保證伸縮組擴容出來的新實例運行的是新版本的應用。
?
需求下發:
開發一個系統可以直接從Ansible那邊傳來IP和伸縮組ID后,我的系統要把阿里云中伸縮組的鏡像更新為該IP對應實例的鏡像。
?
設計階段:
產品的定位和擴展性
如果單單只實現這一點功能,可以寫個python或者SpringMCV項目,調用阿里云的SDK就可以搞定。當我分析公司現有的資源和軟件產品時發現,目前并沒有一款這種對接云平臺的輔助系統,所以我們可以把項目的定位抬高一些,做成對接所有云平臺,甚至是對接運維所有輔助系統的這么一個項目。
最終選定用SpringFramework微服務架構來開發,雖然前期投入比較大,但是會帶來很多優點:
1,?每個邏輯節點可以配置多個物理節點達到高可用性。?
2,?自動的服務發現和注冊機制?
3,?節點間松耦合,新增和修改擴展靈活?
4,?統一的API網關,提供轉發和過濾功能?
5,?可以添加Spring Config(統一配置中心)、Spring Bus(配置熱修改)、Spring Sleuth(日志追蹤)等輔助節點滿足大批量節點管理?
?
現階段:?
開發了4個節點:服務注冊中心(Register)、對外服務網關(Gateway)、云總控(CloudCenter)、云分控(AliyunClient),架構圖如下:
?
其中注冊中心是基礎運維研發關心的節點,用來觀察服務節點的健康狀況;Gateway是對外提供服務的入口,采用Restful協議,可定制安全規則(目前采用IP白名單);其它節點為內部服務節點,不對外暴漏,不允許直接訪問。
?
再階段:
后續與云平臺相關的新功能,與阿里云有關的可以繼續修改阿里云分控節點的代碼,如果涉及到其它平臺,新添加節點。?
這樣設計的優點:1 某個云平臺API升級、SDK更新等不會影響到其它節點代碼的可用性;2 每個云平臺根據自己的壓力單獨擴展資源。
?
終極形態:
對接更多的系統,擴展更多的組件
除開與云平臺相關的功能,后續如果有其它模塊需要開發的部分,也可以放到該項目中來。隨著項目復雜度的增加,物理節點達到一定規模后,靠基礎運維人工管理整套系統將會變的非常困難,需要引入Spring Cloud輔助工具。
?
API核心步驟
1 DescribeInstances:通過基準實例的內網ip查詢對應實例id
2 CreateImage:使用實例id創建一個新鏡像,記錄鏡像id
3 DescribeImages:通過鏡像id查詢鏡像狀態及progress,直到available為止
4 DescribeScalingGroups:通過伸縮組id查詢到生效中的伸縮配置,記錄ID
5 ModifyScalingConfiguration:修改伸縮配置,指向新的鏡像
?
提高用戶體驗體驗
阿里云基于實例制作鏡像的過程幾分鐘至幾小時時間不等,用戶通過RESTFul的POST請求通過Json體傳入實例IP和伸縮組ID后,將會陷入漫長的等待過程,所以操作請求和狀態返回需要設計成異步形式避免等待。
異步又有兩種可選的實現方式:1,后端任務完成后通過Queue通知客戶;2,提供狀態和進度的查詢接口供客戶端調用。兩種方式各有利弊,對于請求者來說前者是被動的等待,不知道中間狀態,甚至不知道死活;后者需要請求者通過get不斷來輪詢,但是可以拿到任務的進度。
所以,最終的設計是當收到任務請求后,經過簡單校驗直接轉交后臺處理,同時將查詢進度的url通過http的response返回給請求端。
客戶對自己的鏡像可以有自定義的命名規則,方便后期維護和在云平臺的查詢,所以添加一個可選參數,讓客戶可定制鏡像名稱的前綴。
?
細節考慮
1 異步任務線程池
因為任務是異步執行的,而且前面也說過,一次任務的執行從十幾分鐘到幾小時不等,如果不做控制很有可能線程數爆掉,所以處于安全和效率的考慮,需要增加任務的線程池。如果線程池扛不住并發數,只能擴展物理節點。
?
2 任務狀態緩存
因為無法控制客戶端調用狀態查詢接口的頻率,如果完全透傳給阿里云會嚴重影響我自己系統的性能。所以在設計中增加一層緩存,客戶端接口只查詢緩存中的狀態,緩存層每1min調用一次阿里云的鏡像狀態接口更新一次緩存中的狀態。
?
3 阿里云API容錯機制
這個是上線后遇到的問題,由于網絡的問題從我的系統到阿里云的服務并不能保證100%的問題,所以當輪詢制作鏡像任務狀態時有極小概率會失敗,但其實在阿里云端制作鏡像的任務仍在運行中,但是在我的系統里卻認為以失敗結束了。
所以對于特定的API需要增加容錯機制,連續3次API調用失敗后才認為真正失敗。
?
部分源碼分享:
https://github.com/yejingtao/ci-register.git
https://github.com/yejingtao/ci-gateway.git
https://github.com/yejingtao/ci-cloudcenter.git
https://github.com/yejingtao/ci-aliclient.git
注意:因為我使用的JVM本地緩存,所以當前的服務需要java -jar部署到一臺機器上,后續我會把本地緩存改造為共享緩存。
?
總結:
微服務開發是一個循序漸進的過程,只要開始把架構搭建好,隨著功能一點點的添加,跟搭積木一樣可以慢慢構建出一個龐大的系統,而且添加新功能模塊對現有功能沖擊很小。
原文鏈接:https://blog.csdn.net/yejingtao703/article/details/84961510
總結
以上是生活随笔為你收集整理的微服务设计简单实践---从一个简单需求学习微服务思想的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言动态规划和文件操作练习——通讯录
- 下一篇: 2020_7_31