騰訊QQ團隊開源分佈式後臺毫秒服務引擎全解析:引擎架構、RPC、灰度……

騰訊QQ團隊將於12月4日開源一個服務開發運營框架,叫作毫秒服務引擎(Mass Service Engine in Cluster,MSEC),它集RPC、名字發現服務、負載均衡、業務監控、灰度發佈、容量管理、日誌管理、Key-Value存儲於一體,目的是提升開發與運營的效率和質量。程序員

毫秒服務引擎的創做衝動和構建經驗,來自QQ後臺團隊超過10年的運營思考。它是一整套解決方案,但也能夠拆分來使用其中的監控、Key-Value存儲單品。算法

典型用戶羣體

毫秒服務引擎很是容易搭建和上手,使用它,初學者從零開始開發一個分佈式後臺demo並運行起來,只須要2個小時。基本上是一個小時完成框架搭建,一個小時完成開發上線,特別適合互聯網初創公司。shell

功能與優點

模塊間訪問採用RPC的方式,開發者不用關注網絡與報文格式,像寫單機程序同樣開發分佈式服務。緩存

  1. 負載自動均衡與容錯,對於單機故障、局部網絡波動等情況自動應對,服務高可用性。
  2. 支持C/C++、Java、PHP語言,立刻還會推出支持Python語言;若是選擇C/C++語言,支持協程,兼具開發和運行效率。
  3. Web化的管理界面,在Web界面完成配置、發佈、監控、日誌、Key-Value存儲集羣管理等全部操做。
  4. 須要複雜部署的服務器都採用Docker鏡像的方式安裝,使得部署與上手很是容易。
  5. 相比使用其餘開源組件拼湊起來的解決方案,毫秒服務引擎更加的體系化,對團隊的規範更加到位。

毫秒服務引擎設計背景

對於互聯網服務後臺團隊,開發框架的選擇是很是關鍵的問題,10年的海量服務經驗和教訓使得咱們團隊深入認識到:服務器

  1. 要儘早規範團隊的開發服務框架,避免到了後期,各類開發語言混雜、各種存儲組件充斥、重複編碼、每一個模塊形態不統1、文檔缺失、監控癱瘓、人員離職形成大量信息丟失,最後積重難返、痛苦不堪;
  2. 沒有框架來規範,團隊的隨意性就太大,合做效率就大打折扣,甚至於內耗、反覆的挖坑填坑,系統的成敗過於依靠人的意識和水平;
  3. 規範,不能靠文檔、不能靠勞動紀律、不能靠苦口婆心、不能靠人員意識、不能靠運動式的整頓,要靠技術框架上切實的限制與貼心保護。

若是有機會從零開始定義一個理想的開發框架,咱們以爲須要考慮下面9點。網絡

  1. 同步編碼異步執行。兼顧運行效率和編碼效率,但願代碼寫起來是同步和順序的,而執行的時候是異步的。
  2. IDL/RPC。支持IDL(接口描述語言)和RPC,減小網絡協議相關的重複工做,協議有比較好的擴展性;遠程調用友好且高效,作到覆蓋主要的開發語言。
  3. LB。對服務間的調用選路進行統一的管理,對單機故障和網絡波動等常見狀況有自動容錯,咱們簡稱load balance(LB)。
  4. 存儲服務化。這個其實和開發框架關係不太緊密,這裏提一下,強調存儲應該有統一的組件且由專業的團隊運維,就像共有云同樣。
  5. 過載保護。框架必須有成熟自帶的過載保護機制,不須要業務開發人員關注或者關注不多。
  6. 基礎的監控和告警。RPC調用、機器的CPU/網絡活動、任務併發度、時延、進程監控和秒起等基礎信息,要有上報、統計和告警,不須要業務開發人員關注。
  7. 完整的業務流轉呈現。統一日誌,在一個地方可以清晰的呈現某次業務處理過程的流轉詳細狀況:通過了哪些模塊間調用,調用參數是怎樣的,每一個模塊處理的重要分支和結果是怎樣的,最好圖形化呈現。支持染色和不一樣的日誌詳細級別。
  8. 中央總控。整個系統的配置和文檔等重要信息,例如每一個模塊有哪些機器,分佈在哪些機房、容量冗餘狀況、模塊間調用關係、訪問控制的配置動態管理甚至電子流,都但願能統一在一個地方Web化的管理起來,而且與運營的系統是直接聯繫直接生效的。
  9. 雲調度。容量的自動調度。例如要進行某個運營活動須要大量的擴容,只須要把設備放進去,就能自動的擴縮容。當某個城市機房故障,可以自動調度容量到其餘城市。

毫秒服務引擎架構

整個系統由下面幾部分組成,如圖所示。 數據結構

**Web Console:**整個系統的運營管理中心,包括:

  • Tomcat提供Web管理界面,管理的數據保存在MySQL裏。架構

  • LB是名字發現服務和負載均衡,remote_shell是遠程文件傳輸與遠程命令執行服務。併發

**Log服務器:**提供業務Log的存儲和查詢服務。Log存儲在MySQL表裏。負載均衡

**Monitor服務器:**提供業務上報信息的存儲和查詢服務。業務上報信息存儲在內存裏,推薦內存8G~16G。定時dump到磁盤的方式防止數據掉電丟失。

**業務運營服務器:**部署開發框架和業務邏輯代碼,處理業務請求。

**key-value存儲服務:**相對整個框架比較獨立,按需選用。

服務標準化運營

一套互聯網後臺服務的開發和運營涉及很是多的細節。

  1. 訪問其餘服務模塊,服務端IP如何管理?網絡報文格式是怎樣的?

  2. 有哪些配置文件? 用到哪些第三方的庫?

  3. 業務邏輯和基礎框架是如何分離的?

  4. 對外提供怎樣的網絡接口?怎麼對外提供接口API和文檔?

  5. 運營機器上的安裝目錄準備怎麼安排? 有哪些運維腳本和工具?

  6. 應該監控哪些指標?應該記錄哪些日誌?

  7. 還有不少…

上面種種細節,每一個程序員實現起來都有不一樣的作法。經驗證實,若是後臺各個模塊沒有標準化和規範化,可能致使:同一個團隊開發的服務,千差萬別千奇百怪,負責運維的同事面對的多個模塊「長」的都不同,程序框架徹底不同,安裝目錄亂七八糟,沒法規模化的高效運維。

服務的質量徹底依賴團隊成員的技能和意識,有的成員可能會作得比較好,配置文件命名易懂、文檔及時更新與代碼保持一致、有對服務作細緻的監控上報和日誌記錄,提供了運維腳本,可是也有的成員的工做讓人抓狂。

每當有團隊成員離職和工做交接,交接自己就是工做量很大,交接時間長,交接質量很差,文檔缺失,不少信息在交接過程當中丟失,運營事故每每頻發。

經驗難以獲得傳承,一塊石頭反覆絆倒各個成員和業務模塊,運營事故雷同、頻出,團隊挫折感倍增、服務可用性低下。

也曾經有過作事比較規範的時候,可是這些規範一般靠耳提面命、人口相傳,靠管理者運動式的整頓,有時候管理焦點沒有持續跟進,或者隨着人員更替,團隊又把這些寶貴的經驗丟棄了,變得無序。

因此服務標準化是後臺技術團隊組建開始的第一要務。

兩個誤區

**誤區一:**找幾個開源的組件用起來就行了唄。

  • 一般的開源的組件,只是在某一方面上規範了服務,有的是規範了網絡調用,有的是規範瞭如何監控,有的是規範瞭如何記錄遠程記錄,其實這還遠遠不夠,例如配置文件、接口定義、使用到的外部庫、安裝目錄的結構等很是多的細節,必須統一管理、有惟一出處。

**誤區二:**你說的我都懂,咱們團隊剛起步,業務需求多,時間緊,先野蠻生長,打破條條框框,後面再規範再改。

  • 一開始沒有標準化,後面當代碼和模塊都多起來了,且都處於運營狀態,再改再標準化,難度很是大,成本很是大,風險很是大;另外工欲善其事必先利其器,一開始就標準化好,其實可讓業務跑的更快。

如何實現服務標準化?

首先,每一個服務的配置都Web化、集中管理起來。

部署在哪些IP上?

有且只有一個配置文件。
Protocol buffer的接口定義文件。
引用了哪些外部庫?例如openssl。
業務邏輯和基礎框架分離,業務邏輯以插件形式提供。
而後,每一個業務模塊部署的目錄結構都是肯定的。
如上圖所示:

  • 業務部署的目錄都是/msec/一級業務名/二級業務名;

  • 都包含bin etc log 等幾個目錄;

  • bin裏面是啓停腳本、業務插件msec.so和外部庫(若是有);

  • etc裏面是配置文件config.ini;

  • Log裏面是本地的日誌文件。

另外,程序員不能隨意打破上面的方式。例如臨時的另外搞一個本身配置文件什麼的,他若是這樣作,那下次發佈的時候目錄會被覆蓋,個性化的東西會被刪除掉。

後臺服務的RPC和路由管理

互聯網服務的後臺,硬件一般是由大量的廉價機器組成;軟件架構一般採起大系統小作、分而治之的思想。這就決定了業務邏輯涉及到大量的網路IO,同時單機故障、網絡局部故障是運營的常態。那麼,RPC和路由管理就顯得尤爲重要了。毫秒服務引擎爲此提供了一個完整的解決方案。

  • RPC的概念其實出現已經好久了,記得筆者讀大學的時候,接觸到RPC的概念,總以爲不重要,畫蛇添足。 我掌握好Socket通訊這個利器和TCP/IP協議族原理,什麼功能不能實現?

  • RPC就跟本地函數調用同樣寫代碼,確實開發效率比較高;我本身把Socket相關函數好好封裝一下,讓代碼複用起來,開發效率也很高。

  • 不懂或者不關注網絡通訊底層原理,光會函數調來調去,這樣的程序員太沒有出息了!

後來,筆者開始帶團隊,親身經歷了一些團隊協做和IT服務運營過程當中的故事,才發現RPC很是關鍵。若是沒有很好的實現RPC和路由管理,IT系統服務質量會過分的依賴人的意識,而這個一般成本很是高、效果也很差。

毫秒服務引擎是怎麼作的?

首先,毫秒服務引擎將每一個服務部署在哪些IP上這些信息集中管理起來,即便是調用外部的非標準服務(咱們叫異構服務),也須要將該外部服務的接口IP配置到毫秒服務引擎管理系統裏。這樣涉及到的IP信息就不會散落在代碼和各類配置文件裏了。

服務之間的調用,統一採用CallMethod()函數的方式,避免代碼千奇百怪;按服務名字調用和接口名調用。
RPC背後的路由算法對於單機故障、網絡局部波動等異常,自動容錯。簡單的說,路由算法按必定的規則輪轉的選擇被調用模塊的接口機,並統計過去一段時間的調用成功率、時延信息,根據這些信息調整該接口機被選擇到的比例。若是某個接口機故障了,那麼就不會發送請求給它,從而實現自動容錯。

毫秒服務引擎框架自己,在RPC執行的時候,就上報了不少基礎屬性和日誌,這樣保證了服務監控和告警等運營措施不依賴與人的意識。下圖是叫作getMP3List這樣一個RPC調用的請求數和成功數,這些是不須要業務開發者工做就自動上報。

每一個請求有惟一ID來標識,經過該ID,毫秒服務引擎能夠在框圖中直觀的呈現該請求通過的模塊、模塊間的RPC名字等信息,這個一樣不須要業務開發者的工做就自動實現。

後臺服務的灰度發佈與監控

灰度發佈和監控是互聯網海量服務必備的兩大利器,可以極大提升後臺服務可用性和運營水平,背後的哲學是持續交付、用戶測試和盡在掌控。

在騰訊,有一個課程系列,叫作《海量服務之道》,包含十多門課程和方法論,是技術同事必修和必知必會的,其中兩門課程就是《灰度發佈》和《全方位監控》。

筆者在加入騰訊QQ後臺團隊以前,曾經在電信行業、金融行業作過幾年開發工做。剛進入騰訊時,以爲技術上不少地方讓人耳目一新。

  • 後臺系統都是部署在很是多的廉價服務器上,每一個人都會管理很是多的機器,讓人以爲頗有成就感很富有。

  • 有比較精確的設備預算計算模型,每一個服務器的性能在考慮容災冗餘的前提下,一般被壓榨到剛恰好,負責人會深刻的洞悉整個系統的性能、容災、柔性等方方面面。能負責一個海量的系統是很榮耀的一件事情。

  • 沒有專職的測試人員,通過開發者自測後,灰度發佈加詳細的監控,主要的系統幾乎每兩週都會被髮布一輪,做爲後臺技術人員,本身的工做直接影響數以億計的用戶,有點手握核彈處於上帝視角的感受。

  • 監控系統(咱們內部一個叫monitor的系統)真的是太方便了,一條條曲線直觀的展現整個系統運做的各類指標,若是有異常短信和電話就會響起來,讓人以爲一切盡在掌控,有一種面對着大量儀表盤操控着航母遊弋或者是戰鬥機掛着核彈翱翔的感受。

好了,趕忙結束程序員意淫的美好感受,我想說的重點是:灰度發佈和監控真的是互聯網海量服務必備的兩大利器,可以極大的提升後臺服務可用性和運營水平。

固然,灰度發佈不僅是一部分一部分的發佈新代碼,監控也不僅是繪製曲線和告警短信那麼簡單,這裏面深究下去會有不少東西,背後的哲學是持續交付、用戶測試和盡在掌控。

毫秒服務引擎是怎麼作的?

#####灰度發佈 在服務配置管理頁點擊「制定發佈計劃」。

選擇這一次灰度要發佈的目標機器和發佈類型。
在接下來的嚮導中選擇正確版本的配置文件、外部庫、業務插件等,這樣就完成了發佈計劃的製做。
接着,點擊菜單 「運維->發佈」,能夠查詢全部發布計劃,對於已經發布的計劃,能夠作回滾操做。點擊詳情能夠查看發佈計劃更詳細信息,並執行發佈。

監控

關於監控,在「RPC和路由管理」那裏講得已經比較詳細了,這裏不贅述。只說明一下:除了RPC和框架自己自動上報的一些信息,還支持業務自定義上報信息(例如我想上報第28級VIP用戶登陸的次數),且支持對於關鍵指標的波動、最大值、最小值設置告警。

KV存儲集羣的設計要點

Key-Value存儲系統,是很是廣泛的需求,幾乎每一個在線的互聯網後臺服務都須要KV存儲,咱們團隊在KV存儲方面,經歷過幾個時期,我本身深感要作好不容易。

第一個時期,很早期的時候,咱們的數據存儲在MySQL表裏,按照用戶帳號簡單的分庫分表,爲了保證訪問高併發,利用每一個MySQL服務器的內存作數據緩存;主備兩套分佈在不一樣IDC,業務邏輯本身作副本同步。當時主要的問題是:內存的數據結構擴展困難、運維工做瑣碎、數據同步機制自己的缺陷致使不能作異地IDC部署,這些缺點對於業務飛速發展、一地機房已經不夠用的局面很是被動。

第二個時期,咱們設計了新的KV存儲系統,其用戶數據結構容易擴展、具有能夠多地部署的數據同步機制,很好的應對了新時期業務發展的須要。爲了設備成本考慮,咱們把數據作冷熱分離,訪問頻繁的數據會加載到專門的Cache層,且對於不一樣的訪問模型,掛載不一樣架構的Cache,另一個File層專門作數據持久化。這樣的設計,使得架構太複雜,bug收斂速度慢,運維工做相比之前甚至更復雜了。

第三個時期,爲了應對廣泛的KV存儲需求,咱們以公共組件的形式從新設計了KV存儲,做爲團隊標準的組件之一,獲得了大規模的應用。結合同期抽象出來的邏輯層框架、路由管理等其餘組件,團隊的公共基礎組件和運維設施建設的比較完備了,整個業務的開發和運維實現了標準化。但這個階段就用了咱們團隊足足2年多時間。

不一樣於無數據的邏輯層框架,KV存儲系統的架構設計會更復雜、運維工做更繁瑣、運營過程當中可能出現的情況更多、bug收斂時間會更長。一句話:團隊本身作一個KV存儲系統是成本很高的,並且也有比較高的技術門檻。

設計一個KV存儲,須要考慮至少這些方面。

  1. 如何組織機器的存儲介質,一般是內存、磁盤文件;例如用hash的方式組織內存。

  2. 如何設計用戶的數據結構,使得通用、易於擴展、存儲利用率高;例如PB序列化、Json、XML方式。

  3. 友好的訪問接口,而不僅是get/set一整個value。

  4. 如何作集羣分佈、如何sharding、如何作到方便的擴縮容;例如一致性hash算法。

  5. 如何作數據冗餘、副本間如何同步、一致性問題;副本間如何選舉master。

  6. 備份與恢復、數據校驗與容錯。

  7. 讀寫性能。

  8. 其餘可能的特殊需求:例如咱們設計過一個KV存儲,用於存儲一些公衆號的個數不受限粉絲列表。

上面8點,業內的KV存儲組件通常都會考慮到,或者各有特點,各自優點在伯仲之間。可是綜合過去的經驗教訓,咱們以爲有一點很容易被忽視:可運維性、運維自動化、黑盒化運維。

舉一個例子,前面提到的咱們第二個時期的KV存儲系統,剛開始應用的時候,一次擴容過程會有10多步的運維操做,包括load數據、作增量同步、屢次修改機器狀態、數據比對等等,須要運維同事以高度的責任心來完成。另外就是運維同事必須如該KV存儲架構設計者同樣深入理解系統背後的原理和細節,不然就不能很好的執行運維操做,這個要求也很是高,新老交接週期長,還容易出運維事故。

基於上面的考慮,同事爲了讓用戶更容易學習和接受,毫秒服務引擎在Redis Cluster的基礎上,實現了運維Web化,並加上了集羣的監控。

經過Web界面方便進行

集羣概要狀態查看。

能夠在Web上方便的完成平常的運維操做:新搭集羣、擴縮容、故障機器的恢復。
請求量、內存使用、CPU等各類狀態信息可直觀監控,也能夠按IP粒度查看。
相關文章
相關標籤/搜索