腾讯游戏数据应用微服务实战
作者注:本文是作者在GIAC全球互聯網大會上的一個分享整理成稿子,介紹了微服務以及騰訊游戲數據應用在微服務中的實踐,整理時間倉促,如有偏頗,請聯系小編修正。
? ? ? ? ? ? ? ? ? ? ? ? ? ??
各位架構師們,大家下午好。我是來自于騰訊游戲數據中心的張志歡, 今天主要給大家分享的是微服務在騰訊游戲數據應用場景中的實踐。
本次分享大致會分為以下幾個內容:
第一小結會介紹下微服務的一些理念以及應用微服務帶來的問題;
第二小結會介紹騰訊游戲數據應用datamore是什么,我們是如何在游戲數據領域中應用微服務架構解決一系列問題;
第三小結會介紹我們微服務架構中,mock體系的架構以及應用;
第四小結介紹如何設計devops模塊,幫助提升服務的開發運維效率;
最后一個小結會結合一些我們在應用微服務架構碰到的一些難題和初步的解決方案,包括性能優化,調用跟蹤優化 以及 容量評估等問題。
總的來說,這次分享是想給大家介紹一些場景,讓大家了解為什么我們使用微服務,以及如何利用一些架構解決服務化帶來的諸多問題。
從2014年微服務的具體的理念被提出以來,以其業務高度靈活性和強大的解耦設計,越來越多的軟件企業,特別是互聯網企業都在研究和應用這種架構理念, 對于微服務的落地都相繼研發了自己的開發框架和服務化套件。
我們看看國外,像netfilx 的spring cloud, google,ibm,lyft ?基于service mesh的istio框架 以及 微軟的微服務框架ServiceFabric, 國內的大公司同樣也緊隨潮流相繼推出或開源了自己的微服務解決方案。
比如騰訊的 tars, 阿里的dubbo 華為的servicecomb等等。
總之微服務的熱度一直持續到了現在,而國內的互聯網公司更是蜂擁而至的宣稱自己的底層都已經使用了微服務架構。
這些年也和一些公司和團隊進行過一些微服務的交流,發現了一個共性。就是有些團隊對于微服務的理念的理解還是僅限于它的字面意思,微小化,服務化。導致一些團度根據這樣的理念強制對自己的架構進行了字面化的改造,最后也導致了一系列的問題。
最經典的改造方案莫過于以下這種:
把微服務理解成“接口化”,這類團隊的做法是將自己的系統進行接口化封裝,將所有的業務模塊之間調用改成rpc調用(有一些還會遵循restful的標準)。最夸張的是我有見過一個團隊,硬生生的把自己代碼中的一些函數調用變成api調用。
這樣的改造不僅讓系統復雜性加倍,系統的性能也被嚴重的影響,后續帶來的巨大的維護和運營成本也極大的消耗開發者的精力。
那么,我們這里就要提出一個問題,什么是微服務? 業務一定使用微服務就好嗎?
想要理解這個問題, 還是要從互聯網架構的歷史著手。
?
最早的互聯網web1.0年代,大部分的應用其實都是一些靜態網站或者低訪問量的服務,此時互聯網架構大部分是單體服務架構,一臺機器+一套應用運行環境+應用服務搞定一切,這種架構的優點是開發更加快捷簡單,一個開發人員往往兼職運維人員,一站式完成程序的開發,發布,運維和運營。開發以及調試的效率都比較高,不過一般需要開發人員掌握一些運維的知識。
對于這種應用,存在一個致命的缺點。就是性能瓶頸依賴于單臺機器服務的極限。雖然也可以通過不斷的優化程序的性能,但是始終都有一個極限。
隨著互聯網業務的發展,越來越多的應用都要支撐成千上萬的用戶訪問,單機服務已然無法支持互聯網的爆發式的增長,這時候發展出集群服務架構。以代理為中心,聚合多種無狀態可平行擴容的服務,從而擴展服務能力,支持更高的并發服務。
當然這樣的架構下,帶來了一系列需要解決的問題需要開發人員去處理。
如:為了支持平行擴容,需要服務進行無狀態改造(包括存儲(如session)需要用中心化存儲代替本地存儲,文件,甚至日志都不能單純在本地存儲)。同時,由于多機服務存在單服務不可用的問題,開發者需要制定合理的容災和負載均衡策略以保障整體服務的穩定性。
上面兩種架構的發展針對的主要是服務的性能上面的優化,而互聯網的發展,也讓互聯網的業務變得越來越復雜,特別是企業內部的一些服務,各種邏輯越來越復雜,邏輯之間也互相交錯,各個邏輯也由不同團隊開發和維護(語言和環境都不盡相同)。
這種情況下,面向業務的服務架構,SOA架構誕生。通過對系統進行面向業務的拆分,通過esb總線進行集成,讓服務之間更加獨立,而ESB層則專注于服務的集成與連接。這種架構讓企業架構有更好的擴展性,各個服務提供者也更加專注于自身服務的優化。
當然,帶來便利的架構,一定會帶來一些問題需要程序員去解決,這種總線架構下,其實會讓所有的業務集成中心化,很多服務都依賴總線的集成開發,從而讓這個總線邏輯越來越復雜,極大的增加了維護和學習的負擔。而中心化的架構也讓所有的業務邏輯流量都經過總線,帶來比較大的性能問題。
微服務架構其實是對SOA架構的衍生和優化,不僅具備soa架構的優點,同時將總線層弱化,以服務組合各個服務,達到更加好的擴展性。
相對于soa架構,微服務帶來的問題更加明顯:我們例句幾個問題:
1. 服務管理的問題,這么多服務進行錯綜復雜的調用,如何去管理他們(比如流量的管理,服務間的權限控制,路由管理等等);
2. 服務集成問題,使用何種方法可以快速將服務進行組合,同時提供何種工具,讓這些服務開發者快速將應用開發上線;
3. 問題排查,不同于單應用可以使用各種調試工具,服務間大部分通過rpc調用結合,各個服務甚至連開發語言都完全不一樣,如果除了問題,怎樣定位;
4. 容量管理,由于每個上游服務都會調用海量下游服務,服務之間存在各種請求放大,當一方服務進行擴容時,如何對后面的服務進行容量估算;
5. 測試問題,等等。
?
所以總結起來,越是簡單的架構,管理維護起來越簡單。但是簡單的架構未必能夠解決復雜的問題,而復雜架構的出現,是為了解決特定場景下的問題而生,但是你卻要花費更多的時間去維護這份復雜。
對微服務概念的,我的理解是,如果你宣稱你們的業務實現微服務化,除了服務化屏蔽語言差異,除了對業務的拆分,還需要解決微服務帶來的一系列問題(高效集成部署,海量服務治理,快速問題排查,服務柔性可用,服務測試,容量管理),這些也是信通院組織國內微服務應用廠商推出微服務標準的原因。
我們可以看下標準里關于微服務化的描述,包括分布式事務,服務注冊,服務契約,CI/CD,CO,服務治理,熔斷隔離,鏈路跟蹤,網關等等),如果完全按照標準去自己實現,那實現微服務架構也未免太難了,所以,企業可以根據自己的實際應用場景,選擇性實現一些個性化的服務,而一些標準化的服務,可以依賴于業界開源的一些產品。
感謝業界底層技術的發展,我們不需要對于上面每一項的技術都要自己獨自去實現。
K8s+ Docker技術讓我們可以對服務進行更快的部署、更細粒度的資源分配以及更快的擴縮容,pipline極大的提升的服務開發和集成的效率,微服務網關幫我們干了大部分的服務治理的活兒,分布式事務組件解決了服務事務依賴, consul解決了服務注冊發現以及服務治理策略的存儲下發問題,微服務開發框架集成了調用跟蹤,日志等服務。
所以大家可以看到,實現一整套微服務架構并不是簡單的進行api拆分,或者業務邏輯拆分就夠了。了解完微服務的概念后,我們還需要知道另一個重要的點,就是究竟微服務解決了什么樣的問題?什么場景下使用這種架構?
終于要到我們的正題了也是本次分享需要重點闡述的,我會以騰訊游戲數據應用DataMore為場景,以實踐為例,給大家解釋這個問題。
?
騰訊在游戲最早是使用以hadoop, spark等離線計算引擎,基于離線計算能力,我們設計和創造了騰訊游戲數據分析平臺 iData,包括數據報表功能,提供海量的,通用的數據報表。多維分析功能,能夠讓用戶自助化完成數據的透視分析操作,便于定位運營問題。用戶畫像服務則提供游戲畫像分析能力,讓業務能夠精準的了解游戲人群。最后的數據提取服務支持快速海量用戶多條件的提取。
這一系列的服務為我們的游戲業務提供了決策輔助以及通過數據發現和定位運營問題的能力。市場上的一些數據產品像神策,talkingdata,thinking data等都是提供此類服務的。
隨著大數據技術的發展,以storm為代表的各種實時計算框架也相繼推出,相比于離線計算,實時計算無法做更加復雜的數據加工,但是卻可以對數據進行更快的加工。這一點非常吸引我們。
我們一直在研究這類計算是否可以讓大數據產業發生更大的變化,特別是在游戲行業中,是否可以體現更大的價值。
為此我們針對騰訊游戲大數據實時應用的場景進行了一系列的調研,最終提出datamore數據應用服務,目標是利用實時數據和離線數據,為業務提供更具價值的服務。
我們知道,游戲的服務分為兩部分,一方面是游戲server服務,另外一個是游戲運營活動服務。
游戲server服務一般負責游戲核心邏輯的開發(比如副本系統,聊天系統,社交系統等),而運營活動服務一般是一些特殊節點的活動(如一些節日促銷,抽獎等活動)。
游戲運營活動非常依賴于游戲服務器提供的各種接口,如用戶數據接口,發貨接口等。運營活動端一般根據一定的邏輯組合這些接口。
這樣帶來的一系列的問題:
1. 運營對研發側的依賴非常大,很多個性化的接口(一般都是數據相關的接口,比如查詢xx用戶的數據,查詢XX資格,查詢排行之類的),都需要研發側封裝。而研發側封裝完成后需要通過版本發布。這樣對于運營來說,節奏不可控(有些活動可能要等待版本發布);
2. 是運營的特點就是變更頻繁,而為了保障游戲服務穩定性,服務變更都是走版本,甚至停機維護;
3. 是游戲的計算能力有限,一般游戲內都是存儲一些最終值,計算也相對簡單,對于一些復雜的計算,比如任意時間段的和,他們需要做非常多的工作。同時,更加海量的數據加工也會影響游戲服務器本身的效率;
4. 精細化運營能力有限,由于很多精細化能力依賴于大數據的復雜離線計算(比如:用戶畫像與標簽,推薦能力)等,所以游戲業務一般只能做標準化通用的運營服務支持。
為了解決這種問題,我們構建了datamore數據應用服務的架構,核心在于兩點:
1. 數據存儲方面,提供游戲標準化日志服務,讓業務能夠通過日志的形式或者我們主動采集游戲日志的形式,將數據上報到數據中心;
2. 標準化游戲服務接口:統一全業務的發貨接口,將接口服務能力接入到datamore服務中心,底層我們通過日志,將整個游戲數據計算能力搬離出游戲。同時與業務對接標準化的營銷觸達能力。打造了數據應用服務標準集。
在這些標準服務上,我們構建了datamore應用中心,它由一系列的標準化數據應用系統構成應用集合,讓游戲運營能夠自助化的使用這些系統進行快速高效的運營。系統之上,我們沉淀了海量的運營方案,業務用戶可以選取這些方案,而每個方案都會對應一個或多個應用系統,用戶選擇方案后,方案自動給系統填充內容。
比如你選擇了一個用戶關懷方案。方案會自動選擇用戶關懷系統,并自動選取易受挫用戶以及受挫指標(如連敗xx局,勝率低于XX),并在這些用戶實時達到這些條件后給予用戶獎勵或者干預,提升用戶的留存。
這樣,我們打造了一整套獨立于游戲的數據營銷應用引擎,由于系統底層通過游戲日志與游戲解耦,使得建構在datamore平臺上的應用都具備不依賴游戲版本(配置化計算),超強數據計算能力,更加豐富的計算內容(比如游戲內走了多少步)以及精準化能力。
?
這個是datamore的產品架構,我們可以看到,datamore分為三層,最底層是我們的基礎能力包括用戶觸達,分析,實時&離線計算,營銷服務?;谶@些服務能力,我們建構了三大方向工程化服務應用。
包括用戶實時運營系統,游戲數據功能以及創新數據玩法。這些應用通過對底層能力的封裝為業務提供了一系列數據服務。
那這套架構和我們今天的主題,微服務有什么關系呢?
大家可以看到,我們所有的工程化的系統,都是依賴于底層能力去構建的,上層應用都來自于底層能力的組合和集成,這些底層服務天然是獨立的,非常符合微服務架構。
設計這些底層服務,在我們的場景下需要解決幾個問題:
1. 這些底層能力是由不同團隊開發的,他們的開發語言,開發環境各不相同(比如實時計算服務使用java開發,數據分析服務使用c++,用戶觸達使用go開發);
2. 由于上層系統會相對復雜,他們會整合越來越多的底層能力,如何管理這些龐大的能力(如游戲內一個任務系統會同時用到實時計算,游戲營銷(獎勵能力),用戶觸達能力,畫像能力等數10種能力);
3. 單個服務面臨的是騰訊游戲千萬級的用戶訪問,如何能夠更安全,更低成本的支撐?
這些問題都指向了一個方案,就是微服務化,將這些能力以微服務的形態組合在一起,同時提供微服務支撐全套服務以及治理能力,以restfu其他形式統一服務接口,為上層提供高效,穩定的服務。
一般要將模塊進行服務化改造,使用一些開源的微服務框架,比如springcloud,dubble等就可以了,這些框架底層會集成微服務的基礎中間件(如負載均衡,服務發現與注冊,流控等),使用這些框架以及框架自帶的一些工具,可以快速將系統以微服務的架構落地。
對于我們來說,使用這套框架的成本比較大,原因有幾個:
1. 數據運營相關的支撐團隊比較多,各種團隊的開發語言,開發環境都不一樣,如果使用開發框架的方式,無疑需要準備多種語言和環境下的開發框架,對于我們來說成本比較高;
2. 對于那些已經使用另外的一些框架開發的服務來說,遷移成本比較高,需要將代碼遷入新框架;
3. 框架的維護,升級是一個比較大的工程,侵入式太強。
?
基于這種情況,我們采用的是servicemesh架構,在我們的devops模塊中,當你服務發布時,會自動創建一個代碼網關sidecar部署在目標服務同一個pod中,通過iptables等方式劫持流量,將所有的流量管理的能力都放置于網關中。后面有一個大的服務治理中心負責管理所有網關的行為。
對比了目前市場上的一些網關服務(如linkerd,envoy等),我們最終選擇了開源支持度較高,插件比較豐富、并且性能較好的envoy作為服務網關并對其進行了一系列優化(性能,插件等),使用他為微服務提供(服務監控告警,調用跟蹤,日志服務等)。
同時,也開發了一個相輕量的微服務框架Dori組合成微服務基礎。
同時,我們以consul為基礎,搭建了一整套的微服務配置中心,負責管理和下發微服務策略。
剛才我講的是利用微服務的理念,對底層的可復用的能力進行服務化改造,通過使用微服務的能力,為上層提供了統一的,健壯的公用服務支撐,利用這些獨立的微服務,我們可以開發各種各樣的應用,可以更低成本且不用重復建設。
現在我們需要面對的一個問題就是,如何能夠更快的組合這些微服務成為一個業務應用,這個就需要提到服務集成的概念了,只有將服務集成與服務治理搭配起來,才可以為開發者提供一站式,高效率的微服務體系建設能力。
傳統的方案類似于SOA的方案,各個業務邏輯獨立以api服務的方式為集成中心提供服務,而應用開發人員通過一個統一的業務集成中心通過開發或者配置的方式組合這些業務邏輯,將業務邏輯開發完成后,通過統一的網關提供服務。
這樣的平臺在傳統的企業架構中非常常見,優勢也非常明顯,不僅通過業務集成中心和業務邏輯的拆分讓企業業務單元解耦,同時集成中心提供了統一的開發方式和對外接口使得前端對接更加標準化和規范。
但是對于互聯網或者我們的場景中,這種架構其實存在一定的問題。
1. 是隨著業務集成中心中的業務邏輯越來越多,其中的功能也錯綜復雜,集成的業務和業務之間甚至會存在不規范的互相調用,導致業務集成中心任何一個業務的變更或者平臺本身的變更,都會影響上層大批應用;
2. 是開發成本高,往往集成中心會指定開發的語言和環境,同時為了兼容廣大的開發者,這些集成系統會越來越復雜,開發人員的上手成本也會更高;
3. 上手成本高,意味著維護成本也很高,同時由于業務的興衰,導致集成中心存在大量不會使用的代碼,想要清理需要考慮里面的錯綜復雜的關聯,基本上日積月累,平臺會變得更加臃腫;
4. 第四個也是對于互聯網公司的一個很大的問題,就是這種中心化的部署,在互聯網應用的響應快,高并發的場景中,性能堪憂。
我們對于這種soa架構進行了優化,參考了云平臺的設計方式,進行了更加細致的分層:
底層是iaas層,對接各種存儲,網絡,計算資源,具體來說就是各種云iaas服務。第二層是paas層,以微服務的形式存在的paas,它不僅僅是一個api,為了讓上層開發人員使用他們,他必須滿足paas的標準,即需要提供標準的接口描述文檔,資源申請流程,控制臺用于配置api,權限控制等,這樣開發人員可以以“服務”的形式使用他們。
在上層就是我們的核心層,我們稱之為ipaas,即integration paas。我們對這一層的定義是:一站式的微服務開發和組合的平臺,提供從開發,運維到運營和治理的一站式服務,我們可以看到,這個平臺應用具備devops的能力,服務編排,代碼管理,自動化測試,治理等能力,利用他,我們可以開發我們的paas服務,同時也可以將paas組合起來成為saas應用,利用ipaas開發的服務都是以微服務的架構存在的,用戶無需關注微服務的具體實現細節,平臺測會幫助完成。
這樣的分層我們可以看到,ipaas 開發的應用都是以獨立的微服務存在,他們通過sidecar的方式直接連接paas,服務治理能力都幾種在網關當中,項目之間完全獨立且去中心化,非常符合我們的互聯網應用的場景。同時paas+ipaas方式可以讓開發人員更低成本,低門檻的開發復雜應用,讓更小的團隊通過這樣的架構更快的進行創新迭代,提升創造力和創新能力。
剛才我們講了微服務的架構,應用場景以及需要解決的問題,我們也看到,市面上針對這些問題都有比較好的解決方案或者開源框架來支持。
這些都是基于某個特定問題給出的解決方案。一般都是直擊痛點,而且研究深度都不錯。
但是在實際中,我們解決問題一般是以場景的方式來考慮的,我們可以通過建立一整套架構并且結合市面上的一些開源框架或者軟件,搭建一套面向場景的解決方案。
所以下面,我會以場景化為主線,告訴大家,如何組合一些能力,解決實際問題。
第一個場景化是我們搭建的一套基于mock的架構,用于提升開發效率,測試效率;
第二個場景是我們搭建的一套devops架構,用于幫助不同語言和環境開發者完成他們微服務架構落地。
Mock這個詞大家都非常了解,在一些前后端開發分離的團隊,后臺開發經常會使用一些mock數據去偽造接口返回,從而達到前后端并行開發的目的。
往深里來看,數據模擬這個功能,遠不止用于前后端開發,下面是在我們的微服務架構下,mock能夠幫忙解決的問題。
開發階段(并行開發,開發自測)測試階段(多分支測試,故障注入) & 運營階段(服務容量評估以及服務降級)。
那就有人會問了,不對呀,mock還能做容量評估?這個不是全鏈路壓測做的事情嘛。某種意義上,是的。其實我們在搭建整套基于mock的體系中發現,只需要添加一些模塊,就可以復用mock架構的鏈路,實現更多的功能。
我們可以看下單一的mock功能如何解決我剛才提出的問題。mock僅僅是數據模擬服務,一般用于開發之間(如前后端)由于協議文檔對接的一種方式。后端開發人員在未開發完接口之前,通過一個mockserver配置自己的模擬接口以及返回,提前提供給前端,前端人員開發按照這個模擬數據開發完后,后面只需切換到正式環境的域名即可完成前置開發。
當然mock機制還可以用于在測試場景當中,比如一個服務需要同時調用3個子服務,我們可以使用mock策略強制讓其中兩個服務返回固定的數據,這樣就可以完成對第三個服務的單元測試而無需修改你的代碼。
第三種是用于線上運營過程中,mock可以用于服務降級當中,由于mock數據大部分是靜態化或者存儲在redis中的數據,所以它自身能夠抵御高并發的讀取。我們可以為一個服務配置一個mock降級數據,如果某一個服務出現不可用,通過網關可以路由到mock數據。比如 你的服務一個分類列表服務不可用,可以配置一個常用的默認分類,用于返回默認分類,即可完成降級。
上面是mock使用的一些場景,如果自己獨立開發市面上都有一些組件供大家使用,但是如果是集成到我們的ipaas平臺中,就需要解決一系列的問題了。比如怎么樣才可以讓開發者無需修改自己的代碼就可以使用Mock功能,海量服務組合的場景下如何能夠使用mock完成多鏈路的測試,如何讓降級服務配置化自動化。
達到這些可以讓開發者更加簡單的使用mock完成他的開發,測試以及運營。但更加高階的玩法是使用了這些mock的能力后,如何才能更加直觀和全面的觀察結果,比如使用mock進行全鏈路測試后,如何才能根據測試結果找到系統的性能瓶頸,找到服務的能力便捷。這些都需要一系列的工具鏈支持。
這個是我們mock體系架構:
核心是依賴于servicemesh中的微服務網關來完成各種mock策略的執行,配合幾個部分:
1. mock中心:
上層是mock構造器,通過圖形化配置mock數據,上面支持幾種策略的配置,如數據模擬配置,故障注入配置以及 mock降級配置。這些配置文件會存儲起來,模擬數據會通過mock標準化接口提供對外服務。
故障注入以及降級配置會通過配置中心下發到相關服務的網關當中。
最上層是壓測中心,和mock中心一樣,他也是基于ipaas開發的微服務,擁有獨立的資源管理能力。上層有幾大功能模塊,包括數據錄制與重放,數據構造(使用mock管理端配置),數據引流模塊以及數據導入模塊。
通過頂層的壓力輸入與流量控制模塊,將數據塞入微服務鏈路當中。
不同的是,構造的數據會連同自動嵌入到header頭中的mock策略(故障注入與路由策略)進入微服務調用鏈條中,各個微服務會根據預先配置的mock策略,自動選擇哪些服務使用模擬數據,哪些服務需要模擬故障,整條鏈路的所有數據反饋會通過統一日志上報到數據分析中心。
數據分析中心有三大分析利器:
第一個是基于ES與strom的調用跟蹤服務,用于觀察整條鏈路的調用情況;
第二個是基于storm+durid的性能統計服務,用于進行業務重要指標的統計;
第三個是基于promtheus以及grafana的實時監控,用于監控服務粒度
的指標,如QPS,延遲等。
這三大數據分析利器可以全方位的幫助我們觀察,定位以及分析整體服務的穩定性,更好的是,由于配置和執行都是基于sidecar執行,讓所有的服務都無需做任何的代碼修改,通過配置化即可完成,提升了效率。
這邊講下這套體系的應用,其中一個是用于我們服務的單鏈路的快速測試,實際我們的場景中,我們經常需要單獨測試服務的某一條鏈路,比如我做了一個報名排行發獎的服務,他會按照一個流程分別調用報名服務,排行榜服務以及發獎服務。
由于報名服務是一個經過測試的穩定服務,我需要觀察的是排行榜和發獎的邏輯是否正常。這個時候,通過mock策略中心結合壓力中心,我們將mock策略配置好并將在請求入口中配置mock策略。
我們的請求在途徑報名服務的微服務網關時自動路由到mock數據,返回已報名。然后在請求另外的服務。這樣就完成了單鏈路的測試。與此同時,前面的請求數據都會通過sidecar上報到回放服務中。只需點一個按鈕,在你修改了業務邏輯后,壓測中心將會回放您在一段時間內的所有請求。
這樣的架構下,測試變得更加方便,無需侵入,僅需配置即可完成mock策略的下發,執行以及重放。通過mock策略可以屏蔽一些你不需要測試的服務。
這套體系衍生出一個比較方便的應用,借助這套鏈路,我們開發了用于測試數據的自動化清理模塊。
這個場景是這樣的,開發人員經常要對已經集成的服務進行測試,而測試過程中往往會產生很多的測試數據,這些測試數據在使用過后往往需要清理,一般清理的過程比較繁復,比如找到服務負責人清理,或者編寫邏輯腳本等,為了解決這個問題。
我們這邊在我們的服務網關上做了一層透明數據代理,所有的對于數據存儲的請求都會攔截下來(比如redis,mysql,hbase),每次進行數據庫插入刪除或者修改都會自動記錄undo日志,存儲到測試數據清理中心(當然,對于一些比較復雜協議的存儲,我們也提供sdk的方式– 這種方式的好處就是無需對協議解析壞處就是有一定的侵入性),測試數據清理中心接收清理命令,可以按照時間段,存儲類型以及一些自定義的規則自動去清理測試數據。
這樣,我們的開發人員在進行測試時候就無需關注如何清理數據了(特別是redis這樣的kv存儲,清理起來確實很費事)。
第二個在微服務平臺中需要關注的地方是devops,這個是我在wiki上摘錄的關于devops的經典的解釋和圖。
我們可以看到,所謂的devops是建立一套快速,頻繁,穩定的構建測試,發布軟件的文化與環境,個人愚見,任何的文化或者流程都比不上有一套好的系統,讓大家使用過程中就能感受到這個流程,從而最大化的發揮流程的作用。我們可以看到,一個標準的devops流程包括 代碼編寫,持續集成與構建,測試,部署,運營和監控。
那為什么微服務需要這一套機制呢?
1. 微服務化場景下,開發一個應用等于組合這些強有力的微服務的過程,這讓更小的團隊能夠開發更大規模和難度的應用,低成本的同時,也保持了小團隊的創新力。最終的影響是,服務的迭代和發布更加頻繁。
這種情況下,傳統的集中式的運維場景無法滿足這種需求;
2. 由于微服務之間使用標準rpc,如http接口進行交互,導致不同團隊之間,開發環境和開發語言不同,一套標準化的,統一的運維系統無法滿足這種需求
3. 是在互聯網快節奏的產品開發場景下,開發和運維的界限更加模糊,一個業務開發人員往往需要兼顧開發和運維運營整個流程,這個時候,需要有devops,讓他們能夠一站式完成微服務生命周期
4. devops相比于傳統的開發運維場景,他們提供標準化安全和質量工具(如代碼掃描,安全掃描),可以實現更加自動化和低門檻的安全保障。
對于復雜的大型互聯網應用,他的集成和發布一般是非常復雜的,各種子系統的相互配合,上下依賴以及大量的配置文件同步,甚至人工介入到發布中,動輒從晚上發布到第二天。為了提升集成的效率,同時,更為了規范集成&發布流程,很多大型互聯網團隊都會開發類似這樣的復雜的構建集成部署系統。這類系統的優勢在于將很多業務封裝成一個個模塊,以流程化的方式調度。同時也便于讓運維了解系統的集成部署的流程。
但是它也存在許多的問題:
1. 上手比較困難,各個模塊都需要特別了解;
2. 由于系統非常復雜,需要很多人工參與的部分,往往這類系統無法做到完全自助化,需要專門運維配合才能集成部署;
3. 此類系統往往和業務結合比較緊密,一般沒有通用的標準化流程,可能換一種業務整合系統都需要修改,同時擴展性也比較差。
?
而在微服務場景下,事情就變得大不一樣了。我們可以看一個經典的微服務架構。
我們在做一個游戲內的排行榜的服務,這個服務由許多微服務組成,比如報名服務,排行榜服務,獎勵服務等等。這些服務之間相對獨立,單個服務職責單一簡單,一般都是以http-restful形式提供對外服務。
只要服務之間對接上,單個服務發布對其他服務依賴較少。各個服務開發語言,環境不相同, 服務的變更頻繁。
這種情況下,使用原來的方案,效率非常低下,表現為:
1. 各個服務集成,發布相對簡單,不需要這么多組件干預;
2. 各個服務環境不一樣,一套系統不能對所有服務通用;
3. 服務發布頻繁,需要自動化以及開發自助化。
所以在這種場景下,我們需要拋棄以往復雜的ci/cd系統, 擁抱微服務的devops。
我們的devops方案本質上也是以微服務為基礎搭建的解決方案。大家可以從上往下看。
最頂層是我們的devops原子服務,包括構建服務,代碼掃描服務,部署服務等,這些服務都是以微服務方式組織,對外提供restful的接口。
下層的是我們的調度引擎,我們以jekins定義的pipline為標準調度語言,實現了一套調度框架。可以根據標準Yaml文件進行調度devops原子。所有的產出都會在devops的產出模塊輸出(比如度量數據,監控數據,日志數據以及生成報告的服務)。
在下層是我們實現了一整套的編排UI,利用這個UI可以拖拽devops原子服務,通過連線的方式完成調度語言的生成。開發者可以在這個截面上自定義屬于自己微服務的devops模版(如php項目模版,go項目模版等)。
根據這個模版創建的項目實現自動化構建,以及部署。
這個是我們整個平臺的devops的架構,基本上滿足了wiki上關于devops的定義,實現平臺的集成部署的自助化和自動化。
持續集成和交付我們使用pipline實現,從代碼拉取,質量管理,編譯,測試 到最后的通知階段,每個階段都有多種插件讓用戶自定義。完成CI/CD TEST后,平臺將會將程序打包成鏡像。
然后在CD模塊中 通過K8S 將鏡像部署到現網環境中(期間會有一些自動化的操作,比如路由呀,自動灰度來支持)。發布完成后,整個CO模塊將會提供基于日志的實時監控,日志模塊,告警模塊以及擴縮容模塊的支持。
在這里我們有一個和業界的有一點不同,那就是CD模塊我們并沒有放在pipline中,理論上一個設計比較好的pipline應該可以覆蓋整個 集成到部署。我們這么做的原因還是因為業務場景限制,因為我們的所有的服務其實都和數據有關,服務之間和其他服務調用也非常復雜,一個發布可能涉及到別的服務的調整(最復雜的就是容量的評估),所以其實我們并沒有完全做到自動化部署。所有的服務部署都會通過另外一個評估的系統,在評估完成后還有一些資源的確認以及發布的協同才可以部署。所以我們這邊將CICD,test實現了基于piplie的自動化,而部署和運營我們都以獨立的模塊支撐。
這一章,主要是給大家介紹我們做微服務化面臨的幾個問題以及預期的一些解決方案。
第一個是我們采用service mesh架構場景下,對這種架構做的一些性能優化;
第二個是對于調用跟蹤的設計和一些優化。
這兩個場景都是我們實踐中經常用到的場景,由于騰訊游戲的數據應用是針對所有游戲業務,并發量和性能都要求很高,對于網關性能要求就非常高,同時由于數據量大,調用跟蹤服務因此產生大量數據從而承擔更大的壓力。這些都是高并發服務下必須面對的問題。
在上面的分享中,我們有給大家提到service mesh的概念,為了降低微服務治理的開發成本,我們使用sidecar模式部署envoy網關到各個服務中,所有服務之間的通訊都會經過網關。這樣使得網關的負擔也增加了許多。目前來看,影響網關性能主要分為幾個部分:
1. 我們為網關添加了許多插件,比如鑒權服務,代理服務,路由服務等,這些插件會讓服務性能受損;
2. 通過配置中心會給網關同步許多配置(比如名字服務,熔斷配置,路由配置等),這些配置越來越多,經常也會有變更,嚴重影響envoy的性能;
3. envoy本身在服務轉發上也存在一定的性能開銷。
所以這幾塊的問題加在一起,其實影響了微服務的性能,
這里我們針對這三個方面都做了一定的優化以及有一些預期的方案在探索:
1. 我們的中間件實現按需編譯,每個服務的部署都會根據他在平臺上選擇的服務編譯到envoy中,和服務邏輯同時發布;
2. sidecar中的策略按照 全局配置,服務配置以及業務配置進行分級,通過配置中心進行分級策略發布,做到精準策略推送;
3. 嘗試使用dpdk 或者 ebpf + xdp的方案對底層進行優化,減少數據在內核態到用戶態的復制。(可以提升超過50%的性能);
4. 還有可能就是協議的優化,比如使用quic協議代替TCP+TLS。
?
另外一個比較常用的就是調用跟蹤模塊,和大部分調用跟蹤功能類似,基于opentracing標準提供api和各種語言的sdk開開發者,開發者通過sdk自動生成traceid+ spanid 以及附加的信息上報到隊列中。一個實時計算服務消費隊列并將數據丟入es中,前端使用開源UI jaeger提供查詢聚合。
一般這種架構可以適應大部分的情況,不過很多市面上的文章或者分享對于其中的一些細節沒有做詳細的闡述,其實在高并發場景下,調用跟蹤的設計還是有很多優化的地方。
一般集中在兩個優化方向:
1. 是請求量過大帶來的數據量,帶來查詢的延遲或者需要大量的機器來存儲這些數據(特別是對于es這種全索引的存儲,寫入的性能比較差,導致結果大量延遲);
2. 由于調用跟蹤侵入式比較強,需要修改許多代碼才能使用這個功能,提高了使用這個能力的成本。
目前我們有幾個地方的優化:
1. 是入口進行采用,采用一定的算法(算法也可以通過離線計算得到一個模型,對于重要性比較高的采樣率要調高一些)或者按照百分比+ 最低采用條目進行采用,提高有效信息采集成功率;
2. 提供一套標準存儲日志協議,服務打印日志到本地,angent負責采樣。一方面angent可以進行一定的優化(比如 錯峰上報,滿足條目上報等),另外一方面agent也可以采集一些自身其他信息上報;
3 是在開發層面統一業務的開發框架,這樣可以在框架層面上實現自動trace傳遞。當然,我們也在探討其他的方式,比如類似于pinpoint或者c#注解的方式,在我們的devops模塊的代碼編譯插件中進行自動調用跟蹤替換;
4 是設置一個開關,只對錯誤信息進行上報。
當然,這些多是為了提升調用跟蹤的吞吐量以及查詢效率,但是個人認為,根據調用跟蹤查服務間的問題只是調用跟蹤很小的一個方向,真正調用跟蹤能夠發揮他大的作用的地方,還其實單純的調用跟蹤查詢服務只是調用跟蹤的一個很小的應用場景,調用跟蹤發揮更大的地方應該在于對于數據的統計和分析,如:
服務運營中,目前我們對于調用跟蹤的應用有以下幾個方面:
1 性能分析;
2 異常調用分析;
3 路由分析;
4 容量校正;
5 等等等。
這些會在后續相關的分享中給大家介紹。
總結
以上是生活随笔為你收集整理的腾讯游戏数据应用微服务实战的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2019可信云云计算开源产业大会:腾讯云
- 下一篇: 腾讯开源再获OSCAR 5项大奖,全国首