個推基於 Docker 和 Kubernetes 的微服務實踐
2016年伊始,Docker無比興盛,如今Kubernetes萬人矚目。在這個無比需要創新與速度的時代,由容器、微服務、DevOps構成的雲原生席捲整個IT界。在近期舉辦的QCon全球軟體開發大會上,個推應用平臺基礎架構高階研發工程師王志豪,基於他在基礎架構方面多年的經驗,分享了《個推基於Docker和Kubernetes的微服務實踐》。全文3405字,但優秀的你一定要看完,文末有彩蛋喲~
-個推應用平臺基礎架構高階研發工程師王志豪-
一、微服務化
微服務架構
微服務 是將單一的應用程式拆分成多個微小的服務,各個小服務之間鬆耦合,高內聚,每個小的服務可以單獨進行開發,不依賴於具體的程式語言,也可以使用不同的資料儲存技術,各個服務可以獨立部署,擁有各自的程序,相互之間通過輕量化的機制進行通訊(如基於HTTP的API介面),所有的服務共同實現具體的業務功能。
客戶端與服務端通訊有2種方式,第一種是客戶端直接與各個微服務進行通訊,這樣的架構有4個缺點:
(1)多次服務請求,效率低;
(2)對外暴露服務介面;
(3)介面協議無法統一;
(4)客戶端程式碼複雜,服務端升級困難。
第二種方式是由API閘道器統一代理各個服務,對外提供統一的介面協議,該架構有3 個優勢:
(1)封裝服務介面細節,減少通訊次數;
(2)統一通訊協議,減少客戶端程式碼耦合;
(3)統一鑑權,流控,防攻擊;
在該架構下,閘道器也有可能成為系統瓶頸。
相應地,這2種架構也帶來了2種服務註冊發現的方式,第一種是客戶端通過向服務的註冊中心查詢微服務的地址與其通訊,第二種是增加統一的API閘道器來查詢。前者會增加客戶端的複雜度,開發成本高,第二種操作會顯得更加簡潔,因此我們在實踐的時候選擇了第二種架構方式。
微服務數量增加以後,服務之間的呼叫關係易產生耦合,甚至出現迴圈呼叫的情況,最好的應對方法是對服務進行分層,即將相互依賴的服務通過訊息佇列等技術進行非同步解耦,減少服務間的依賴。
-服務分層-
微服務的具體實踐
1. 技術選型
在實踐中,我們的API Gateway使用的是OpenResty, OpenResty基於Nginx並擴充套件了對Lua的支援,可構建高併發的Web服務。我們通過HTTP介面實現客戶端通訊,資料基本封裝成JSON格式,服務間的通訊介面也是基於HTTP,並利用訊息佇列進行非同步解耦;至於服務註冊發現,我們使用的是Consul;我們選擇了Lua(擴充套件API Gateway的功能),Node.js(用於開發後端服務),Java(用於密集計算和與大資料通訊的場景)作為主要的開發語言。
2.具體實現過程
在實踐過程中,我們使用Lua開發了自己的微服務框架——WebLua,其封裝服務之間的通訊協議和訪問外部資源(如Mysql、Redis等)的方法和依賴,同時提供了應用插槽。我們可以將每一個APP看成一個功能模組,每個APP都需要插到WebLua中才能執行。WebLua可以方便地將模組進行組合,既可以一個APP執行一個微服務,也可以多個APP一起對外提供服務。如此,開發者只需關注業務APP開發,很大程度上提高了開發效率。上圖右側是具體的程式碼目錄結構,每個APP可分為Action,Page,Data三層,Action層在請求處理前後進行攔截,可做某些特殊處理,如請求前進行許可權校驗等;Page層主要對請求的引數進行解析和校驗;Data層負責具體業務處理,同時提供了Shell指令碼,可實現APP打包和部署安裝。
二、 API閘道器
在架構中一個重要角色就是API閘道器,下面來做一個介紹。
從上面的對比圖中可以看到,左側是沒有API Gateway的,很多的模組如Auth,Logging等,這些程式碼都需要自己去實現,造成了模組的重複建設,同時侵入了服務,功能擴充套件比較困難;右側的圖是使用了API Gateway之後的架構圖,所有通用模組均在API Gateway實現,維護簡單,一處建設,各處受益。在這種情況下,對API Gateway也提出了更高要求——其功能必須可以很方便地擴充套件。
為了實現這樣的API閘道器,我們基於 OpenResty,借鑑了Kong和Orange的外掛機制,通過外掛來擴充套件API閘道器功能。
從上面的API Gateway架構圖中可以看到,閘道器安裝諸多外掛,每個外掛會在請求的一個或多個階段發揮作用。外掛配置會在Consul上更新,實時生效,外掛規則可靈活配置。在操作中,我們為外掛開發者提供了更多的自由,開發者可以自己定義格式。
三、容器化
在微服務落地實踐時我們選擇了Docker,下面將詳細介紹個推基於Docker的實踐。
首先網路元件選擇的是Calico,服務註冊發現和配置管理選擇的是Consul。Consul-Template可實時監測Consul配置和服務的變化。
個推映象體系是以CentOS為基礎系統映象,安裝OpenResty,Nodejs,JDK,由此得到環境映象,再在這個基礎上安裝微服務框架,獲得Gorp映象。再在這個基礎上安裝具體應用服務,得到應用服務映象。
-服務註冊發現和配置更新流程-
在API閘道器中,服務註冊通過Consul-Agent來實現,配置更新通過Consul-Template實現。Consul-Template主要更新3類配置,包括:Services:代理的所有微服務的服務地址;Products:簡言之即請求到微服務的對映表,如左上所示,所有請求都有統一個規範,從Host中可以獲取Prod,從URI中可以獲取APP,這 2個資訊可將請求動態路由到具體服務;Nging-Conf:產品的Nginx配置。
應用服務容器,服務註冊的方式跟API閘道器一致。首先,服務通過容器內部執行的Consul Agent將服務註冊到Consul上,其次通過Consul-Template來監測觀察 Consul上配置的變化,並更新配置檔案。OpenResty或者WebNode配置的更新是直接覆蓋相應的配置檔案,然後重啟對應的服務。
上圖是個推基於Docker的叢集架構,從中可看到,Docker叢集包括3個節點,整個微服務分為3層,最上層是API Gateway,中間是業務層,最下層是一些多產品公用的基礎的微服務。
四、Kubernetes實踐
微服務雖然有很多好處,但也帶來了很多問題,其中一個就是運維複雜。以前運維只需要面對一個單體應用即可,現在可能面臨的是幾十甚至上百的微服務。在這種情況下,我們需要藉助Kubernetes來解決問題。Kubernetes是Google開源的一個容器編排工具,可用於協助管理容器。
一開始,我們將容器向Kubernetes叢集遷移時,沒做任何改變,只是採用Pod將所有的服務體系在Kubernetes叢集執行。但隨著深入使用Kubernetes,我們對微服務做了一些改變。
1.首先我們換成用Deployment的方式來部署服務,Deployment會保證服務時刻有一定的副本存活,提高了服務穩定性。
2.其次,我們使用了Service,它可以代理Pod實現負載的均衡。
3. Kube-DNS可以將Service名解析成具體的ClusterIP,並且當Service沒有刪除重建時,其ClusterIP不變,如此DNS解析的快取就不存在失效問題。基於Kube-DNS和Service的特性,後續我們改造了服務註冊發現體系。
上圖是我們當前的服務部署方式,Pod用Deployment的方式建立,用Service來進行代理。
在實踐過程中,我們還遇到了另一個問題,即配置管理問題。
(1)微服務化後配置檔案多而分散;
(2)不同環境之間有很多不必要的差異,如資料庫名;
(3)在很多不同環境中,相同的配置項暴露給測試和運維;
(4)沒有版本控制,回滾比較麻煩;
(5)基於Consul的Web UI無法對非法的輸入進行校驗。
針對這些問題我們做了以下調整:
(1) 統一不同環境間不必要的差異;
(2) 對配置檔案進行模板化,只暴露差異部分,同時可實現不同配置檔案集中配置;
(3)基於Consul開發配置中心,對產品配置集中管理;對輸入進行合法性校驗;增加版本控制,方便回滾。
-配置中心流程圖-
關於日誌服務,我們在應用容器中集成了Fluent-Bit,配置了2個輸入源,TCP和tail, 輸出也有2個,一個是Elasticsearch,所有的日誌都會上傳到ES通過Kibana展示查詢,另一個是日誌審計服務,有些需要進行審計的操作日誌會發送到日誌審計服務進行進一步的分析處理。
微服務數量增加以後,請求鏈路可能延長,開發者在追蹤問題和排查效能瓶頸時會很不方便,因此我們引入了Zipkin,其主要用於分散式鏈路追蹤,在API Gateway實現了一個外掛進行Span收集,後端服務則通過開源的中介軟體來實現。
上圖是個推目前的整體架構圖,最底層是K8S叢集,上面部署了Kube-DNS,Consul用於服務註冊發現和配置管理,再者是我們分層的微服務體系,右側是一些輔助的管理系統。
五、總結
上述是個推基於Docker和Kubernetes的整個微服務實踐過程,我們在實踐微服務過程中做了9件重要的事情, 簡化了操作流程,提高了工作效率 。個推設計實現了自己的微服務框架,完成微服務的容器化部署,自研API閘道器,並基於Consul的服務註冊和配置管理,使用Kubernetes對容器進行編排,基於Service和Kube-DNS對服務註冊和發現體系進行改造,搭建了自己的配置中心,優化了日誌服務,實現了Zipkin鏈路追蹤。
彩蛋
《個推基於Docker和Kubernetes的微服務實踐》已被收錄到 《網際網路企業容器技術實踐》 一書中。該書通過容器技術領域的實踐者分享實踐案例,介紹常見業務痛點、實現方式、方案的選型、遇到的問題和解決方案等,幫助讀者瞭解、認識和玩轉容器。
《網際網路企業容器技術實踐》囊括多家網際網路公司實戰案例,個推的微服務實踐也被收錄其中。
《網際網路企業容器技術實踐》即將出版上市,屆時個推也會給各位小夥伴送上福利,請密切關注個推微信公眾號哦~~
你以為福利到這兒就沒了嗎 ? NO NO NO! 一年一度的 1024程式設計師日 即將到來,悄咪咪地告訴你,個推君為廣大程式設計師們準備了 超級大禮 ,絕對出乎你的意料 哦
一切就位,只待官宣! 10月24日10點24分 ,守住個推的微信公眾號推文,驚喜等你來!

關於個推:
個推(www.GeTui.com)是獨立的智慧大資料服務商,致力於用資料驅動產業新未來。公司成立於2010年12月,總部位於杭州,在北京、上海、廣州等均有本地團隊。
主要業務:
開發者服務: 為移動開發者提供一站式服務,包括“個推”訊息推送、“個數”應用統計和“個像”使用者畫像,全方位打造資料智慧和場景驅動的精細化運營服務體系。
使用者增長服務: “雲發”幫助APP全渠道精準獲客、“個啟”實現APP的定向喚醒,從而驅動使用者的優質拉新與全面促活。
精準營銷服務: “個燈”為品牌提供包括精準人群定向、媒體策略優化和智慧流量監測等在內的DMP資料服務,“個信”為廣告主提供精準廣告投放服務。
大資料服務: 個推大資料中心為各行各業提供資料智慧解決方案,推出“個旅”智慧旅遊和“個真”金融風控等產品,並在社會公共服務等領域作出積極實踐和探索。