餐飲圈APP後端容器化實踐
專案介紹
簡單介紹一下餐飲圈專案規模,以及團隊配置,用以作為技術選型和實踐的參考條件。
餐飲圈介紹
餐飲圈是專注於餐飲行業社交,招聘的APP。 後端採用微服務的設計思想,將不同的業務放在不同服務中。 隨著業務的發展,目前後端服務有20多個。
容器化之前,採用的是傳統的負載均衡(阿里雲負載均衡)、多臺伺服器(阿里雲ECS)、資料庫(阿里雲RDS)模式。
團隊規模介紹
研發團隊3~5人,同時負責前端APP和後端的研發和運維。日常的開發流程採用敏捷開發的Scrum方法。
一個簡單的目標——不斷提升生產力
不斷提升生產力是促使團隊嘗試容器化後端的主要動力。
隨著後端服務的增多,在服務管理方面投入的時間增多, 團隊注意到用於釋出,除錯和監控服務的時間越來越多。 因為之前採用的是單一Tomcat執行所有服務,導致每一個服務的變更都需要重啟整個Tomcat。 Tomcat也佔用了大量的伺服器記憶體。
於是,列出了希望提升的幾個點:
- 更簡化的釋出部署方法
- 更靈活管理服務對資源的使用
- 更高效的管理伺服器資源,實現快速彈性伸縮
基於以上三點,團隊開始考慮容器化後端,使用容器編排平臺來管理服務。
注意:容器化後端,並不是解決上面問題的唯一選擇。後來的實踐中也漸漸體會到,容器化後端是很重大的決定,改變的是整個後端的基礎架構。之所以沒有過多猶豫就選擇容器化方案,是因為團隊內有人熟悉容器,而且現有後端基礎架構相對簡單。
第一張架構總覽
專案後端在阿里雲上,持久化儲存用的全部是阿里雲的服務。 資料庫使用RDS, 圖片等靜態檔案使用OSS, Redis使用雲資料庫Redis,所以容器化過程不存在應用伺服器有持久化資料的問題, 只需要保證容器平臺可以順利連結阿里雲伺服器即可。
注:應用伺服器無狀態化是容器化之前很關鍵的點,如果應用伺服器上存有資料,例如圖片、快取等,需要先將這些資料轉移到雲平臺的儲存服務中, 可以參考12 Factor App(https://12factor.net/zh_cn/)這篇文章。
下面是第一張架構總覽,簡單的從邏輯層面描述了容器化後的後端架構。
可以看到容器編排平臺是架構的核心,所以選擇一個適合的容器編排平臺是容器化後端的關鍵。
容器編排平臺的選擇
我們選擇了三個容器編排平臺作為備選方案:
- Docker Swarm
- Kubernetes
- Rancher
Docker Swarm作為Docker自家出品的容器編排服務,和Docker無縫連線,實施簡單,學習曲線平滑,瞭解Docker使用的程式設計師可以很容掌握。而且,阿里雲容器服務也採用了Docker Swarm作為基礎。
Kubernetes,很多大廠用它實現了PaaS服務, 在企業級解決方案中Kubernetes也經常被採用作為PaaS平臺的基礎,可以側面體現出Kubernetes的可靠性,穩定性等優勢。作為Google自家叢集管理工具的開源版本,Kubernetes有很高的呼聲。
Rancher相對於前兩個選擇,有著開箱即用的特性,提供了完整的UI控制檯。在叢集管理方面有多種選擇,可以選擇Kubernetes,Docker Swarm來做容器編排。 但是因為國內相關實踐例子不多,很快就被從選項中去掉。
嘗試阿里雲容器服務——Docker Swarm
第一個POC是在阿里雲容器服務上做的,因為阿里雲容器服務採用Docker Swarm基礎, 而且提供了一套完成的UI控制介面。 藉助官方提供的文件,一天內完成了三臺伺服器節點的測試叢集搭建,併發布了幾個測試服務。一切進行的很順利。第二天,陸續將全部服務都部署上去,並開始效能和壓力測試。
阿里雲容器服務架構如下(來自官方文件):
第一個問題
在測試過程中,遇到了第一個問題,響應時間不穩定。 有些服務第一次請求響應時間在幾千毫秒到幾百毫秒波動, 並不穩定。
翻閱了路由部分的文件,找到了請求如何在平臺內路由的示意圖如下:
可以看到Routing容器起到了服務發現和路由轉發的作用, 負載之後所有請求都會經過Routing容器。 容器內是HAProxy做請求轉發。
因為請求經過負載,又經過Routing容器,然後由虛擬網路層在叢集內轉發到提供服務的容器。 此過程,在請求到達服務容器之前都沒有日誌可以跟蹤,始終無法知道延遲出現在哪一步。
再後來的實施中這個問題隨著增加服務容器例項的個數得到緩解,但是始終沒有找問題的根本原因(並不能排除應用層本身有的問題的可能)。
雪崩
壓力測試過程中,叢集出現了第一次雪崩,三個節點全部掉線,並且無法SSH登入。
調查雪崩原因有兩個:
- 沒有限制容器使用資源,導致容器過載後瞬間吃掉系統記憶體 (參考阿里雲文件解決,https://help.aliyun.com/document_detail/26017.html)。
- Tomcat官方映象並不能很準確的計算出JVM的最大使用記憶體是多少,導致服務容器過載後不斷重啟(具體解決辦法可參考這篇文)。
結論
優勢
- 阿里雲容器服務,提供了類似Rancher的開箱即用的特性,只需要將雲伺服器配置到叢集中就可以自動完成叢集的部署。 並且可以通過控制檯介面,快速完成阿里雲日誌服務,雲監控等功能的整合。 對於沒有專門運維人員的小團隊,能節省很多維護時間。
- Docker Swarm作為基礎架構,開發團隊學習曲線平滑,只需要掌握docker基本知識就可以上手使用。
有待解決的問題
- 叢集使用的etcd作為一個外部服務獨立提供,對於使用者不可見,也不可控。
- 請求鏈路不完全透明,鏈路跟蹤有難度。
- 技術支援需要在群裡喊。 當然群裡管理員很負責,阿里雲工程師都很專業,問題基本可以很快解決。但感覺技術支援的流程還不是太規範。
嘗試Kubernetes叢集
雖然Kubernetes提供了在AWS等雲上的部署的驅動,但是對於阿里雲,目前並沒有整合進去。 所以,我們參考了阿里雲初揚的《當 Kubernetes 遇到阿里雲 之 快速部署1.6.1版本》(https://yq.aliyun.com/articles/73922)做POC。
對於剛剛接觸Kubernetes的人來說,這很有挑戰。
依然從三節點的測試叢集開始,但馬上遇到了虛擬網路層的問題, 在經典網路模式下始終無法在叢集內聯通虛擬網路。 幾次嘗試未果後,轉移到VPC網路,成功建立了叢集,並打通了虛擬網路。
叢集成功執行——只是個開始
經過兩天的折騰,Kubernetes叢集搭建完成。 但是還有很多東西需要完善, 控制檯UI介面、服務發現、日誌、監控。 很顯然這些都不在Kubernetes的核心中。 所有都需要藉助其他開源專案來搭建,需要投入更多的人力和時間去完善。 對於小團隊來說,希望將Kubernetes用於微服務架構的生產環境,挑戰很大。諮詢過一些前輩後,瞭解到在Kubernetes上部署Spring Cloud是一個用於微服務的選擇,但是並沒有繼續嘗試。
結論
優勢
Kubernetes優勢很多,比如大廠都在用, 社群很活躍。 但我們最終並沒有完整實踐Kubernetes,所以沒有辦法談對這些優勢的體會。
對於小團隊來說的挑戰
- 阿里雲上部署需要了解很多Kubernetes的基礎元件,其中『虛擬網路層』搭建挑戰很大。
- 如果希望用於生產環境,需要自行搭建高可用架構,並且搭建控制檯,服務發現, 日誌等應用。 (可以參考《在阿里雲上部署生產級別Kubernetes叢集》<https://yq.aliyun.com/articles/71037>瞭解部署高可用叢集的方法,但文章中也沒有提到微服務相關的工具如何搭建)
- 微服務平臺相關元件都需要自行部署和配置。
選擇——阿里雲容器服務
經過對兩個平臺的POC,我們最後選擇了提供了更多工具的阿里雲容器服務作為容器化後端的方案。
對於小團隊來說,容器化是為了提高生產力,開始選擇容器編排平臺時,我們忽略了微服務平臺這個概念,將容器編排平臺等同於了微服務平臺。 在POC階段,逐漸認識到了兩者的不同,微服務平臺可以構建在容器編排平臺之上,也可以直接在雲伺服器上部署。
選擇阿里雲容器服務,其實是選擇了一套微服務平臺,並不單單是Docker Swarm。
堅持容器化後端,也是因為基於Docker的DevOps可以不侷限於某種後端技術,更靈活的隔離應用執行環境,和控制應用對資源的使用。
第二張 Architecture Overview
目前實施的架構總覽:
後記
在容器化後端過程中到我們底在選擇什麼
最初我們希望通過容器化後端架構來實現提高生產力這一目標。 在技術選型的開始階段,“選擇一個適合的容器編排平臺”被定義為關鍵技術問題。 但隨著POC的深入,只選擇容器編排平臺並不能解決提高生產力的目標,甚至容器編排平臺本身並不能直接提高生產力,對於小團隊來說反而需要投入更多的人力去維護。 我們認識到, 對於一個3~5人的小團隊來說,我們更需要的是一套微服務治理平臺,這個平臺是建立在IT基礎架構之上的應用平臺。而容器編排平臺更像是IT基礎架構針對容器的一層抽象,並不能直接滿足小團隊提高生產力的目標。 下圖大概說明了,應用、微服務平臺、容器編排平臺、IT基礎架構的關係。
所以,在容器化後端技術選型的後半程,我們更多的考量的是如何選擇一個適合的微服務平臺。最後基於阿里雲容器服務,實現了我們的後端容器化的第一階段。 因為Docker Swarm和Docker的無縫連線, 開發團隊並沒有花費太多精力去學習新的概念,快速的將釋出運維一系列工具遷移到了容器上。 在一個月之內,保證日常業務變更的前提下,完成了後端容器化,實現了提高生產力的目標。
還沒做的事情
- 繼續調研微服務平臺
- 測試彈性伸縮
文章來自微信公眾號:Docker