王者榮耀背後的實時大資料平臺用了什麼黑科技?

ApacheFlink發表於2020-09-21

大家好我是許振文,今天分享的主題是《基於 Flink+ServiceMesh 的騰訊遊戲大資料服務應用實踐》,內容主要分為以下四個部分:

  1. 背景和解決框架介紹
  2. 實時大資料計算 OneData
  3. 資料介面服務 OneFun
  4. 微服務化& ServiceMesh

一、背景和解決框架介紹

1、離線資料運營和實時資料運營

首先介紹下背景,我們做遊戲資料運營的時間是比較久的了,在 13 年的時候就已經在做遊戲離線資料分析,並且能把資料運用到遊戲的運營活動中去。

但那時候的資料有一個缺陷,就是大部分都是離線資料,比如今天產生的資料我們算完後,第二天才會把這個資料推到線上。所以資料的實時性,和對遊戲使用者的實時干預、實時運營效果就會非常不好。尤其是比如我今天中的獎,明天才能拿到禮包,這點是玩家很不爽的。

現在提倡的是:“我看到的就是我想要的”或者“我想要的我立馬就要”,所以我們從 16 年開始,整個遊戲資料逐漸從離線運營轉到實時運營,但同時我們在做的過程中,離線資料肯定少不了,因為離線的一些計算、累計值、資料校準都是非常有價值的。

實時方面主要是補足我們對遊戲運營的體驗,比如說在遊戲裡玩完一局或者做完一個任務後,立馬就能得到相應的獎勵,或者下一步的玩法指引。對使用者來說,這種及時的刺激和干預,對於他們玩遊戲的體驗會更好。

其實不單單是遊戲,其他方面也是一樣的,所以我們在做這套系統的時候,就是離線+實時結合著用,但主要還是往實時方面去靠攏,未來大資料的方向也是,儘量會往實時方向去走。

2、應用場景

■ 1)遊戲內任務系統

這個場景給大家介紹一下,是遊戲內的任務系統,大家都應該看過。比如第一個是吃雞裡的,每日完成幾局?分享沒有?還有其他一些活動都會做簡歷,但這種簡歷我們現在都是實時的,尤其是需要全盤計算或者分享到其他社群裡的。以前我們在做資料運營的時候,都是任務做完回去計算,第二天才會發到獎勵,而現在所有任務都可以做到實時干預。

遊戲的任務系統是遊戲中特別重要的環節,大家不要認為任務系統就是讓大家完成任務,收大家錢,其實任務系統給了玩家很好的指引,讓玩家在遊戲中可以得到更好的遊戲體驗。

■ 2)實時排行版

還有一個很重要的應用場景就是遊戲內的排行榜,比如說王者榮耀裡要上星耀、王者,其實都是用排行榜的方式。但我們這個排行榜可能會更具體一些,比如說是今天的戰力排行榜,或者今天的對局排行榜,這些都是全域性計算的實時排行榜。而且我們有快照的功能,比如 0 點 00 分 的時候有一個快照,就能立馬給快照裡的玩家發獎勵。

這些是實時計算的典型應用案例,一個任務系統一個排行榜,其他的我們後面還會慢慢介紹。

3、遊戲對資料的需求

再說一下為什麼會有這樣一個平臺,其實我們最初在做資料運營的時候,是筒倉式或者手工作坊式的開發。當接到一個需求後,我們會做一個資源的評審、資料接入、大資料的編碼,編碼和資料開發完後,還要做線上資源的申請、釋出、驗證,再去開發大資料計算完成後的服務介面,然後再開發頁面和線上的系統,這些都完了後再發到線上去,做線上監控,最後會有一個資源回收。

其實這種方式在很早期的時候是沒有問題的,那為什麼說現在不適應了?主要還是流程太長了。我們現在對遊戲運營的要求非常高,比如說我們會接入資料探勘的能力,大資料實時計算完成之後,我們還要把實時的使用者畫像,離線畫像進行綜合,接著推薦給他這個人適合哪些任務,然後指引去完成。

這種情況下,原來的做法門檻就比較高了,每一個都要單獨去做,而且成本高效率低,在資料的複用性上也比較差,容易出錯,而且沒有辦法沉澱。每一個做完之後程式碼回收就扔到一塊,最多下次做的時候,想起來我有這個程式碼了可以稍微借鑑一下,但這種借鑑基本上也都是一種手工的方式。

所以我們希望能有一個平臺化的方式,從專案的建立、資源分配、服務開發、線上測試、獨立部署、服務上線、線上監控、效果分析、資源回收、專案結項整個綜合成一站式的服務。

其實這塊我們是借鑑 DevOps 的思路,就是你的開發和運營應該是一個人就可以獨立完成的,有這樣一個系統能夠去支撐這件事。當一個服務在平臺上呈現出來的時候,有可能會複用到計算的資料,比說實時的登入次數或擊殺數,那這個指標在後面的服務中就可以共用。

而且有了這樣一個平臺之後,開發者只需主要關注他的開發邏輯就行了,其餘兩條運維釋出和線上運營都由平臺來保證。所以我們希望有一個平臺化的方式,把資料計算和介面服務統一起來,通過資料的標準化和資料字典的統一,能夠形成上面不同的資料應用,這個是我們的第一個目標。

其實我們現在都是這種方式了,第一是要在 DevOps 的指導思想下去做,尤其是騰訊去做的時候資料服務的量是非常大的,比如我們去年一共做了 5、6 萬的營銷服務,在這種情況下如果沒有平臺支撐,沒有平臺去治理和管理這些服務,單靠人的話成本非常大。

4、思路

3 個現代化,大資料應用的 DevOps。

我們的思路也是這樣,三個現代化,而且把大資料應用的 DevOps 思路實現起來。

  • 規範化:流程規範、資料開發規範和開發框架;
  • 自動化:資源分配、釋出上線、監控部署(這是 DevOps 裡不可缺少的);
  • 一體化:資料開發、資料介面開發、測試釋出、運維監控。

所以我們針對大資料的應用系統,會把它拆成這樣三塊,一個是大資料的開發,另外一個是資料服務介面的開發,當然介面後面就是一些頁面和客戶端,這些完了後這些開發還要有一個完整的開發流程支援。

這樣我們就能夠為各種資料應用場景提供一站式的資料開發及應用解決服務、統一的活動管理、資料指標計算開發管理和各種資料應用介面自動化生產管理的一站式的服務。

這樣的系統能保障這些的事情,而且我們這裡也合理拆分,不要把大資料和介面混到一塊去,一定要做解耦,這是一個非常關鍵的地方。

5、資料服務平臺整體架構

■ 1)計算儲存 

這個框架大家可以看一下,我認為可以借鑑,如果你內部要去做一個資料服務平臺的話,基本上思路也是這樣的,底層的 Iass 可以不用管,直接用騰訊雲或者阿里雲或者其他雲上的服務就可以了。

我們主要是做上層這一塊的東西,最下面的計算儲存這個部分我們內部在做系統的時候也不是 care 的,這塊最好是能承包出去。現在 Iass 發展到這個程度,這些東西在雲上可以直接像 MySQL 資料庫或者 Redis 資料庫一樣購買就行了,比如 Kafka、Pulsar、Flink、Storm。

儲存這塊我們內部的有 TRedis、TSpider,其實就是 Redis 和 MySQL 的升級版本。基礎這塊我建議大家如果自己構建的話,也不需要太過於關注。

■ 2)服務排程

系統核心主要是在中間的服務排程這個部分,它是統一的排程 API,就是上層的一些服務能發下來,然後去統一排程。另外一個就是流程的開發,我們有一個不可缺少的排程系統,這裡我們使用的是 DAG 排程引擎,這樣我們可以把離線任務、實時任務、實時+離線、離線+函式介面的服務能夠組合起來,來完成更復雜實時資料應用場景。

比如我們現在做的實時排行榜,把實時計算任務下發到 Flink 後,同時會給 Flink 下發一個 URL,Flink 拿到 URL 後,它會把符合條件的資料都傳送到 URL,這個 URL 其實就是函式服務,這些函式服務把資料,在 Redis 裡做排序,最終生成一個排行榜。

再往下的這個排程器,你可以不斷地去橫向擴充,比如我可以做 Storm 的排程器、Flink 的排程器、Spark 的排程器等等一系列。在這塊可以形成自己演算法庫,這個演算法庫可以根據場景去做,比如有些是 Flink 的 SQL 的分裝,也就是把 SQL 傳進來,它就能夠計算和封裝的 Jar 包。另外比如一些簡單的資料出發、規則判斷也可以去做,直接把演算法庫分裝到這塊就行。

其實這塊和業務場景沒有直接關係的,但演算法庫一定是和場景是有關係的,另外下層我們會有寫檔案通道,比如說一些 Jar 包的分發,這裡騰訊用的是 COS,能夠去做一些資料的傳輸和 Jar 包的提交。

還有一個命令管道,它主要針對機器,比如提交 Flink 任務的時候一定是通過命令管道,然後在一臺機器去把 Jar 包拉下來,然後同時把任務提交到 Flink 叢集裡去。資料管道也是類似的一個作用。

■ 3)各種管理

另外還要將一個蠻重要的內容,右邊綠色這塊的運營監控、叢集管理、系統管理(使用者許可權管理,業務管理,場景管理,選單配置管理等等),還有訊息中心、幫助文件,這些都是配套的,整個系統不可缺少的。

還有一部分是元件管理,包括大資料元件管理、函式管理、服務的二進位制管理都可以在這裡能夠做統一的管理。

資料資產,比如我們通過 Flink 或者 Storm 能夠生成的資料指標,它的計算邏輯的管理都在這裡面,包括我們計算出來後,把這些指標打上標籤或者劃後,我們也作為資料資產。

還有一個最重要的是資料表的管理,我們無論是 Flink 或 Storm,它的計算最終的落地點一定是通過一個資料表能算出來的。其他都還好,資料包表,比如每天計算多少資料,成功計算多少,每天有多少任務在跑,新增多少任務,這些都在裡面可以做,包括我們版本的釋出變更。還有一個是外部管理端,這個根據業務場景去做就行了,等會演示我們管理端的時候大家就可以看到,其實我們的選單相對來說比較簡單,根據比如我們的資料接入,從源頭把資料接入到 Kafka 或者 Pulsar 裡去。然後資料指標基於接入的資料表,進行資料指標的計算,比如一些特性的 Jar 包,它是多張表的資料混合計算,或者是加上的表的混合計算,等等一系列通過硬場景做的一些分裝。

我們最終把這些做完後,所有的大資料都是通過對外的服務 API 暴露出去的,比如最終遊戲任務是否完成,使用者 ID 過來後我們能看這個使用者的任務是否完成,這樣的一些應用場景可以直接使用 API 去操作。

這是整個流程,講得比較細後面大家才會更清晰。

二、實時大資料計算 OneData

1、資料開發流程

這是我們整體的資料應用流程:

我們的 Game Server 先把資料上傳到日誌 Server(資料接入部分),日誌 Server 再把資料轉到 Kafka 或者 Pulsar,就是訊息佇列裡。

接進來後是資料表,資料表是描述,基於描述的表去開發指標、資料。比如我們這裡一共有三類,一類是 SQL,另外一類是我們已經分裝好的框架,你可以自己去填充它的個性程式碼,然後就可以線上完成 Flink 程式的編寫。

還有一種是自己全新的在本地把程式碼寫好,再發到系統裡去調測。之前說了在大資料計算和資料介面一定要做解耦,我們解耦的方式是儲存,儲存我們用 Redis。它這種做法是把 Redis 和 SSD 盤能夠結合起來,然後再加上 RockDB,就是 Redis 裡面它 hold 熱點資料,同時它把這些資料都通過這個 RockDB 落地到 SSD 盤裡去,所以它的讀寫性非常好,就是把整個磁碟作為資料庫儲存,而不像普通的 Redis 一樣再大資料情況下智慧把記憶體作為儲存物件。

在大資料把資料計算儲存進去後,後面的就簡單了,我們提供查詢的服務有兩種,一種是計算的指標,點一下就可以生成介面,我們叫規則介面;然後我們另外一種,也提供特性化的儲存到介質裡,我可以自己去定義他的 SQL 或者查詢方式,然後在資料進行加工處理,生成介面 。

還有一種方式,是我們在 Flink 和 Storm 直接把資料配置我們這邊的一個函式介面,比如我剛才講的排行榜的方式,就給一個介面,他直接在 Flink 這邊處理完成之後,把資料吐到函式介面裡面,函式介面對這個資料進行二次處理。

這個是整個處理方式,所以我們前面講的就是,基於 Flink 和 Storm 構建一個全面的、託管的、可配置化的大資料處理服務。主要消費的是 Kafka 的資料,Pulsar 現在在少量的使用。

這樣做就是我們把資料的開發門檻降低,不需要很多人懂 Flink 或者 Storm,他只要會 SQL 或者一些簡單的邏輯函式編寫,那就可以去完成大資料的開發。

2、資料計算統一

其實我們之前在做的時候,有一些優化的過程,原來每一個計算任務都是用 Jar 包去寫,寫完之後就是編輯、打包、開發、釋出。後來我們劃分了三種場景,一種是 SQL 化,就是一些我們能用 SQL 表示的我們就儘量分裝成 SQL,然後有一個 Jar 包能去執行這個提交的 SQL 就可以了。

還有一種是線上的 WebIDE,是處理函式的邏輯,舉例子 Storm 裡可以把 blot 和 spout 暴露出來,你把這兩函式寫完後,再把並行度提交就可以執行。但這裡我們具體實現的時候是基於 Flink 去做的。

另一個是場景化的配置,我們個性化的 Jar 包能夠統一排程,根據排程邏輯去執行。

3、資料計算服務體系

這是我們整個 OneData 計算體系的過程,支援三種,一種的自研的 SQL,一種是 Flink SQL,還有是 Jar 包。

我們自研的 SQL 是怎麼儲存,最早是使用 Storm,但 StormSQL 的效率非常低,所以我們根據 SQL Parser 做的 SQL 的分裝,我們對 SQL 自己進行解析,自己形成函式,在 SQL 提交之後,我們用這樣的方式直接把它編譯成 Java 的位元組碼,再把位元組碼扔到 Storm 裡去計算。

Flink 這塊我們也繼承了這種方式,後面會講一下兩種方式有什麼區別。其實我們自研 SQL 在靈活性上比 Flink SQL 要好一點。

這裡是做平臺化,不能說直接放一個 FlinkSQL 去跑,因為我們想要在裡面統計整個業務邏輯的執行情況,比如 SQL 處理的資料量,正確的和錯誤的,包括一些衰減,都是要做統計。

這是基本的過程,完了後我們在上面形成的一些基本場景,比如實時統計的場景,PV,UV,用獨立的 Jar 包去算就行了,配置一下表就可以去計算。另外實時指標的服務,比如殺人書,金幣的積累數,遊戲的場次,王者榮耀裡下路走的次數,這種資料都可以作為實時指標。

還有一種是規則觸發服務,表裡的某個資料滿足什麼條件時,觸發一個介面。還有通訊實時排行榜和一些定製化的服務。

■ 1)自研 SQL

接下來說我們自研 SQL 的過程,我們早期為了避免像 Hive 一樣(函式棧呼叫),而我們自己通過 SQL Paser 的語法抽象後,把它生成一段函式,就不需要這麼多的對賬呼叫。

這個是函式生成過程,最終生成的就是這樣一段程式碼,它去做計算邏輯,一個函式完成,不需要函式棧的呼叫,這樣效率就會大大提升。我們原來單核跑八萬,放在現在可以跑二十多萬。

整個處理的時候,我們把 SQL 編譯成位元組碼,Flink 消費了資料後,把資料轉化成 SQL 能夠執行的函式,就是 roll 的方式。然後把 Roll 整個資料傳到 class 裡去執行,最後輸出。

這種場景適合於,比如 FlinkSQL 它有狀態值,我們要統計某個最大值的話,要一直把使用者的最大值 hold 到記憶體裡去。而我們自研的 SQL 呢,自己寫的函式,它把資料藉助第三方儲存,比如剛才說的 TRedis 儲存。每次只需要讀取和寫入資料即可,不需要做過多的記憶體的 hold。

當前做到狀態的實時落地,就算掛掉也能立馬起來接著去執行,所以超過 10G、100G 的資料計算,都不成問題,但是 FlinkSQL 如果要算的話,它的狀態值就一直要 hould 到記憶體裡去了,而且掛掉後只能用它的 check point 去恢復。

所以這是這兩種 SQL 的應用場景。

■ 2)SQL 化

另外 SQL 裡我們還可以做些其他的事情。我們的資料是持久化儲存在儲存裡的,那儲存裡如果是同一張表,同一個緯度,比如我們都是用 QQ,在這個緯度上我們配置了兩個指標,那能不能一次算完?只消費一次把資料算完,然後儲存一次。

其實這種在大資料計算裡是很多的,目前在我們在做的平臺化就可以,比如一個是計算登入次數,另一個是計算最高等級,這兩個計算邏輯不一樣,但是消費的資料表是一樣的,然後聚合緯度也是一樣的,聚合關鍵字也是一樣。那這個資料就可以進行一次消費,同時把資料計算出來同時去落地,大大減少了儲存和計算成本。

我們現在整個遊戲裡面有一萬一千多個指標,就是計算出來的,儲存的緯度有兩千六百多,實際節省計算和儲存約有 60%以上。

兩個 SQL,甚至更多的 SQL,我們一張表算十幾個指標很正常,原來要消費十幾次現在只需要一次就可以算出來。而且這種情況對使用者是無感知的。A 使用者在這張表上配了指標是 A 緯度,B 使用者在這張表上配了指標也是 A 緯度,那這兩個使用者的資料,我們在底層計算的時候就消費一次計算兩次儲存一次,最終拿到的資料也是一樣的。

**■ 3)線上實時程式設計

**

  • 無需搭建本地開發環境;
  • 線上開發測試;
  • 嚴格的輸入輸出管理;
  • 標準化輸入和輸出;
  • 一站式開發測試釋出監控。

再介紹下剛才提到的線上實時程式設計,其實很多時候對開發者來說,搭建一個本地的 Flink 叢集做開發調測也是非常麻煩的,所以我們現在就是提供一種測試環境,上層的程式碼都是固定的,不能修改。比如資料已經消費過來了,進行資料的加工處理,最終往儲存裡去塞就可以了。

通過這種方式,我們可以對簡單邏輯進行分裝,需要函式程式碼,但比 SQL 複雜,比自動的 Jar 包開發要簡單一些,可以線上寫程式碼,寫完程式碼直接提交和測試就能完成結果的輸出。而且這種的好處是,資料的上報邏輯,資料的統計邏輯,我都在這裡面分裝好了。只要管業務邏輯的開發就好了。

4、Flink 特性應用

  • 時間特性:基於事件時間水印的監控,減少計算量,提高準確性;
  • 非同步化 IO:提高吞吐量,確保順序性和一致性。

我們最早在 Storm 裡做的時候,資料產生的時間和資料進到訊息佇列的時間,都是通過這種訊息裡自帶的時間戳,每一個訊息都是要對比的。有了 Flink 之後,有了 watermark 這個機制之後,這一部分的計算就可以減少了。

實際測試下來的效果也是比較理想的,我們原來在 Storm 裡單核計算,大概是以前的 QPS,加上讀寫和處理效能,單核五個執行緒的情況下。但是 Flink 的時候我們可以到一萬,還加上 Redis 儲存 IO 的開銷。

另一個我們原來資料想要從 Redis 裡取出來,再去算最大值最小值,完了算了再寫到 Redis 裡,這個都是同步去寫的,但是同步 IO 有一個問題就是效能不高。所以我們現在在把它改成非同步 IO,但是非同步 IO 也有個特點就是整個一條資料的處理必須是同步的,必須先從 Redis 裡把資料取出來,然後再把值計算完,再塞到裡面去,保證塞完後再處理下一個統一的資料。

我們再做這樣的一些優化。Flink 這裡有些特性可以保證我們資料的一致性,而且提升效率。

5、統一大資料開發服務—服務案例

接著介紹下更多的案例,如果大家玩英雄聯盟的話,那這個任務系統就是我們設計的,下次玩做這個任務的時候,你就可以想起我。還有天龍八部、CF、王者榮耀 LBS 榮耀戰區(通過大資料實時計算+LBS 的資料排行)、王者榮耀的日常活動(實時資料+介面+規則計算)、有哪些好友是實時線上的,跟你匹配的。

三、資料介面服務 OneFun

1、資料應用的出口

下面介紹下函式,我們原來在做的時候也是存在著一些問題,把資料存到儲存裡面,如果儲存直接開放出去,讓別人任意去使用的話,其實對儲存的壓力和管理程度都是很有問題的。所以後來我們採用了一種類似於 Fass 的的解決方式。我們把儲存在裡面的後設資料進行管理,完了之後介面再配置化的方式,你要使用我這個 DB,這個 DB 最大 QPS 多少,我就進行對比,允許你之後才能使用這個量。

比如我這個 DB 的最大 QPS 只有 10 萬,你要申請 11 萬,那我就給你申請不了,我就只能通知 DB 把這個 Redis 進行擴容,擴容後才給你提供使用。所以這裡面牽扯到我們的指標資料的後設資料管理和介面之間的打通。

2、一體化函式執行引擎—OneFun

這個和剛才 OneData 的方式是一樣的,比如這塊提供了快速的函式,還有一些線上函式程式設計的方式的介面,你可以在上面寫一點 JavaScript 或者 Golang 程式碼,然後就生成介面,介面裡面可以直接對外提供服務,把他形成產品化的包裝,在上層根據介面衍生出更多其他的一些應用系統。

3、基於 ssa 的線上 Golang 函式執行引擎

這裡重點介紹下 Golang,其實我們是基於 Golang 語言本身 ssa 的特點去做的,我們有一個執行器,這個執行器已經寫好的,它的作用就是可以把你寫的 Golang 程式碼提交過來,載入到它的執行器裡。

並且我們可以把我們寫的程式碼作為函式庫,積累下來然後放進去,它可以在執行的時候去呼叫這些函式庫,而這裡面寫的程式碼語法和 Golang 是完全一樣的。

同時我們在這裡面執行的時候,指定了一個協程,每一個協程我們規定它的作用域,就是以沙箱機制的方式來去執行,最先實現的就是外部 context 去實現的,我們就可以實現 Web 化的 Golang 開發,這種有點像 Lua 那種指令碼語言一樣,你線上寫完語言直接提交執行。

4、基於 V8 引擎的線上函式服務引擎

這是我們的 Javascript 的執行引擎,我們主要是做了 V8 引擎的池子,所有 Javascript 寫完之後,丟到 V8 引擎上去執行,這應該大家都能夠理解,如果大家玩過 JS 的可以理解這種方式,就是 V8 引擎裡直接去執行。

5、一體化函式執行引擎--函式即服務

這是我們的線上函式編寫過程:

右下角是我們的函式程式碼編寫區,寫完後左邊的黑框是點選測試,輸出可以在這裡寫,點選測試就會把結果輸出出來,通過這種方式,我們極大地擴張了我們資料平臺的開發能力。原來是本地要把 Golang 程式碼寫完,然後除錯完再發到線上環境去測試,而現在我們可以很大的規範化,比如說資料來源的引入,我們就直接可以在這裡去規定了,你只能引入申請過的資料來源,你不能隨便亂引入資料來源,包括你資料來源引入的時候,QPS 放大我都可以通過這種方式知道。

  • 降低啟動成本;
  • 更快的部署流水線;
  • 更快的開發速度;
  • 系統安全性更高;
  • 適應微服務架構;
  • 自動擴充套件能力。

這個是我們一站式,把函式開發完後,直接提交,我們用 Prometheus + Grafana 可以裡面看到實時報表。

6、案例介紹

這是一個典型的應用,Flink 裡面去計算的時候,他對這個資料進行過濾,完了之後進行一個遠端的 call,這個遠端呼叫執行函式程式碼,大多數這種情況就是一個開發就可以完成大資料的開發和這個函式介面的開發,就可以完成這樣一個活動的開發,整個活動開發的門檻就低了很多,真正實現了我們 DevOps,就是開發能夠把整個流程自己走完。

四、微服務化 & ServiceMesh

1、資料應用必走之路—微服務化

上面講的是 OneData 和 OneFun 的實現原理和機制,我們在內部是怎麼去應用的,這套系統我們在遊戲內部是大力推廣。

這裡尤其是介面這塊,其實如果說要微服務化的話,大資料我們能做的也就是那樣了,能夠用 yarn 或者 K8S 去做資源的管控,和任務的管控,但真正去做服務治理還是在介面這塊。目前我們上下介面大概是三千五百個,每週新增 50 個介面。

所以我們在做的時候也考慮到。原來我們服務是一個個開發,但是沒有治理,現在我們加上服務還是一個個去開發,甚至有些服務我們會把它變成一個服務,但是我們加入了這個服務的治理。

好多人在提微服務,微服務如果沒有一個平臺去治理的話,將會是一種災難。所以微服務化給我們帶來便利的同時,也會給我們帶來一些問題,所以在我們的場景裡面,微服務是非常好的,每一個介面就可以作為一個服務,這種是天然的微服務。

2、一體化服務治理設計

但是這種微服務的治理將會是我們很大的一個問題,所以我們花了很大的精力去做了一個微服務的治理系統,從專案註冊的時候,他就把專案註冊的微服務中心,並且把 API 註冊上來,然後在服務釋出的時候,發到叢集裡的時候,這些服務都要主動的註冊到我們的名冊服務,就是 Consoul。

但註冊到服務裡不是作為服務路由來用的,而是到服務裡後,我們在普羅米修斯這塊去做它的健康檢查和狀態採集,只要註冊上來,我立馬就能感知和把狀態採集過來,然後主要做實時報表和告警。

首先在服務的穩定性和健康度這塊我們有一個保障,另外一個就是服務的資訊註冊到 Consul 裡去後,我們有一個服務的閘道器,我們用的是 envoy,其實內部我們還把它作為 SideCar 使用,後面會介紹。

註冊完了之後,envoy 會把這個所有的負載進資訊載入到這塊來,它去做它服務的路由,同時我們會把整個日誌上報到日誌中心去,包括閘道器的日誌也會上傳到日誌中心去,日誌中心再去做離線的報表和實時的一些報警監控。

所以這裡面我們還加了一個基於 Consul 的一個配置,就是我們包括 server 的實時控制都可以通過 Consul 去配置,配置完了後立馬能夠 watch 到,然後去執行。

這個是基本的服務治理,但現在我們的服務治理升級了,比這個要更好一點,基本的原理是這樣。

3、南北流量+東西流量的統一管控

並且我們在這裡面實現了一個對 envoy 的管控,我們說是服務治理,主要是對流量的一些治理,比如貧富負載策略,路由策略,熔斷,超時控制,故障注入等等一系列。

我們是通過 Consul 的配置管理,通過它能夠下發到我們的 Agent,這個 Agent 再把這個資料能夠通過 Istio 的介面和 K8s 的 API 能夠下發到 envoy,這裡面就是 API GeteWay 和 SideCar 都是 envoy,所以我們通過 Istio 對他的 XDS 的介面寫入,就可以把所有的配置資訊下發到這裡。

這套系統能夠整個去管控整個叢集,南北流量和東西流量的統一管控。這套系統我們未來準備開源,現在主要是內部在使用,而且這裡面我們也做了圖形化的配置,所有 envoy 和 Istio 的配置我們都經過 YAML 轉 Istio 再轉 UI 的方式,把它圖形化了,在這塊能夠做統一的管控。

而且我們把 Agent 開發完了之後就是多叢集的支援,就是多個 K8s 叢集只要加入進來,沒問題可以去支援,我們管理 API GeteWay。

還有一塊是 SideCar 的管理,就是 ServiceMash 裡的 SideCar 管理。我們剛才說的函式介面也好,規則介面也好,是一個 server。

當然這裡面還提到一個 chaos mesh 的功能,我們現在還在研究,我們準備在這套系統裡把它實現了。

4、基於 ServiceMesh 的全鏈路流量分析

這是一個我們通過 ServiceMesh 做的分析,我們雖然可以巨集觀地看出來我們介面對 DB 的壓力有多大,但實際上我們把流量導進來是我們對壓力的監控是不夠的,所以這種情況我們通過 ServiceMesh,他對出口流量和進口流量的管控,然後可以把流量進行詳細的統計,統計完後可以生成一個快照,這次快照和下次快照之間的資料對比,入流量有多少的時候,對下面各個流量壓力有多少。

這是整個展示圖,我們有多個測試用例,這兩個測試用例之間我們可以算出來對下游的壓力的流量分析,後期對下游壓力的分析和下游資源的擴容、縮容都有非常大的價值。

5、案例介紹

最後再介紹下我們目前用這套系統實現的一些案例,大資料的遊戲迴歸,比如做一個遊戲資料的回顧 (生涯回顧)、任務系統、排行榜。

Q & A

Q1:ServiceMesh 是怎麼部署的?主要用來解決什麼問題?

目前我們在使用的 ServiceMesh 技術實現是 Istio,版本是 1.3.6。這個版本還不支援物理機方式部署,所以我們是在 K8s 中部署使用,部署方式有 2 種,可以是直接使用 istioctl 命令安裝,或者是生成 Yaml 檔案後使用 kubectl 進行安裝。

Servicemesh 的架構主要解決的問題是叢集內東西流量的治理問題。同時 Servicemesh 的 Sidercar 作為協議代理服務和可以遮蔽後面的服務開發技術棧, Sidercar 後面的服務可以是各種語言開發,但是流量的管理和路由可以有統一的管控。

Q2:微服務治理架構能介紹一下嗎?

微服務治理架構在我看來可以分為兩類:

  • 服務例項的治理,這個在目前的 K8s 架構下,基本都是由 K8s 來管理了,包含了服務例項的釋出,升級,闊所容,服務註冊發現等等;
  • 服務流量的治理,這一個大家通常說的服務治理,目前主要是由微服務閘道器和服務網格兩種技術來實現。服務閘道器實現叢集內和叢集外的流量治理,服務網格實現了叢集內的流量治理。

Q3:開發人員主要具有什麼樣的技術背景?

針對大資料開發人員,要使用我們這套系統只需要會 SQL 語句和基本統計知識就可以了。

針對應用介面開發人員,要使用我們這套系統只需要會 JavaScript 或者 Golang,會基本的正規表示式,瞭解 HTTP 協議,會除錯 HTTP 的 API 介面就可以了。

Q4:實時計算,Flink 與 Spark 選擇上有沒啥建議?

Spark 在 15,16 年的時候我們也在大規模使用,也在實時計算中使用過,但是當時的版本在實時計算上還是比較弱,在 500ms 的批處理中還是會出現資料堆積,所以在實時性上會有一定的問題,Spark 擅長在資料迭代計算和演算法計算中。但是如果實時性要求不高而且有演算法要求的場景中 Spark 還是不錯的選擇。

Flink 在設計之初就是一種流失處理模型,所以在針對實時性要求較高的場景中 Flink 還是比較合適的,在我們內部測試發現 Flink 的流失計算吞吐確實要比 Storm 好很多,比 Spark 也是好很多,而且 Flink 目前的視窗機制針對實時計算中的視窗計算非常好用。所以一般實時計算或者對實時性要求較高的場景 Flink 還是比較推薦的。

Q5:遊戲回放資料服務端儲存場景有麼?

這種場景也是有的,遊戲回放一般有 2 種方式,一種是錄屏傳輸回放,這種成本非常高,但是簡單且及時性比較好,另外一種是控制指令發回 Server,在另外的服務中去恢復當時的場景,這種方式在成本相對較小,但是使用複雜。

Q6:回放場景下客戶端走什麼協議將資料傳送到服務端?

一般是遊戲的私有協議。

相關文章