從一個案例來看,如何在做架構設計時利用微服務的思想來幫我們解決問題。

 

背景介紹

公司對產品服務的管理目前還停留在物理機的那種理念,雖然阿里雲、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