你所不知的TARS,卻幫閱文集團完成技術架構變革! ——TARS開啓閱文集團技術架構變革之門

| 博客文章java

你所不知的TARS,卻幫閱文集團完成技術架構變革!
——TARS開啓閱文集團技術架構變革之門git

做者簡介|歐樑
後端研發架構師,現任職於閱文集團技術部基礎服務研發組,一直致力於Java應用架構設計以及業務架構演進研發,對分佈式系統架構有深刻理解。 github

0x00 什麼是TARS
TARS是騰訊從2008年到今天一直在使用的後臺邏輯層統一應用框架(Total Application Framework)的開源版本,目前支持C++,Java和NodeJs三種語言。
該框架爲用戶提供了涉及到開發、運維、以及測試的一整套解決方案,幫助一個產品或者服務快速開發、部署、測試、上線。 它集可擴展協議編解碼、高性能RPC通訊框架、名字路由與發現、發佈監控、日誌統計、配置管理等於一體,經過它能夠快速用微服務的方式構建本身的穩定可靠的分佈式應用,並實現完整有效的服務治理。
目前該框架在騰訊內部的各大核心業務都在使用,頗受歡迎,基於該框架部署運行的服務節點規模達到上萬個。內外部版本在代碼結構、功能上基本相同。本文基於私有云版本的TARS,部分功能可能與目前開源及公有云TARS版本有所區別。windows

0x01 使用TARS的起因
一年半前,公司後端服務技術棧是.net加上各類Oracle存儲過程,就着當年頂級服務器,裝配着windows server前先後後浩浩蕩蕩300多臺。不論好壞,撐起了10多年網絡文學的情懷。
現今,隨着IP熱潮的涌動以及公司業務的飛速擴展,什麼都不用說了,必須重構。
因而乎,咱們選擇了90%的人會選擇的,擁有成熟技術圈的JAVA來作這件事情。秉承快速構建、共性開發、持續集成、快速迭代的理念,咱們瓜熟蒂落地開始了。
去年年初的某日,運維側力薦TARS。一時掀起波瀾,「這個東西學習成本如何?」,「和騰訊側用的是一套嗎?」,「用於線上合適嗎?」。揣着疑惑和擔憂,看了內部使用資料和壓測報告(現在官方立碑於此https://github.com/Tencent/TA...),開始了TARS之旅。後端

0x02業務集的現狀
公司TARS業務服務集每日接口調用最大值近百億,單業務峯值可在數萬每秒,近300種業務服務。對於常規的開發部署方式,必然會花費大量成本進行編碼、部署以及運維的統一。使用TARS則輕鬆不少,正是TARS優秀的服務表現,爲公司的APP抗住了515書友粉絲節,百萬紅包,除夕手Q線上聯動等過億級用戶量的活動。
![圖片描述][2]
業務集結構api

0x03 TARS哪裏好
TARS是個大而全的分佈式應用。拋開對開發部署習慣的改變,用了TARS以後,確實省卻了不少且又方便了不少。
服務容錯方面,TARS擁有基本的容錯和負載均衡,讓咱們能夠忽略間歇、偶發、永久的設備故障,任何一臺服務器down掉都不影響業務訪問,同時提供對網絡異常,超時節點屏蔽,定時重試和流量導回的切換能力。
高性能方面,TARS運用Reactor模型以及可以高效支持百萬級別的句柄監聽——Epoll ET。爲TARS框架提供高達41w/s吞吐量。
伸縮性方面,擴容是業務發展必不可少的過程,TARS對平滑擴容提供良好支持,流程化的配置可完成無感知的服務擴容升級。
管理和運維方面,TARS自帶監控模塊,對主調反饋作了實時統計,在管理界面提供了多維度性能數據圖。供開發及運維判斷當前服務狀態,並可配置參數閾值進行短信或微信告警通知。服務器

0x04 TARS的具體使用方法
圖片描述
TARS開發流程微信

01.開發TARS,必須知道如何撰寫JCE接口文件
JCE接口文件借鑑了ICE[1] ,引入代碼生成的思路,並結合無線側手機的應用場景,作到了編解碼效率和網絡帶寬使用的權衡考慮。TARS的JCE接口描述語言文件是以.tars後綴結尾的。
下圖爲JCE文件:
[1] ICE是什麼:ICE ,Internet Communications Engine,是一個面向對象,適用於異構環境的中間件平臺。
圖片描述
JCE文件網絡

對於一個上層業務服務,調用5-6個基礎TARS是常有的事情。摸清產品業務後,分別找到對應服務的開發。因爲每一個服務基本是一個TARS服務,因此溝通一個服務只需3步:一、「××服務的JCE能給我下嗎?!」;二、傳來一個JCE文件;三、「Thanks」;
JCE的內容都是約定俗成的,對應的結構體和接口也有相應註釋。因此,溝通就是那麼簡潔明瞭。架構

02.JCE與TARS服務端的實際開發
經過jce-maven-plugin編譯,可生成特定Servant接口。繼承接口就可實現業務邏輯。
圖片描述
Servant接口
圖片描述
繼承類

在遵循TARS規範的java項目裏面,services.xml中配置此繼承類。
圖片描述
services.xml
TARS項目有特定目錄結構,具體結構以下圖gateway。service項目爲一個普通java project,可在本地開發經過後,發佈jar類庫引入gateway中,TARS容器只需編譯gateway便可。
圖片描述
TARS目錄結構

TARS的目錄結構以及嚴格maven化,省去了開發邏輯代碼單獨打包的過程。同時嚴格的區分了開發及上線測試流程,對規範研發管理流程有極大的幫助。

03.TARS客戶端調用流程
獲取Communicator實例
CommunicatorConfig cfg = CommunicatorConfig.load("config.conf");
Communicator communicator = CommunicatorFactory.getInstance().getCommunicator(cfg);

獲取ServantProxyConfig實例並配置
ServantProxyConfig proxyConfig = new ServantProxyConfig(taf.serverName);
圖片描述
TARS config對象經常使用參數設置

調用Communicator的stringToProxy方法並傳入ServantProxyConfig實例,最後返回Jce生成的動態代理對象,並調用對應的方法。
communicator.stringToProxy(api, proxyConfig);
圖片描述
ServantProxyFactory中建立動態代理對象

TARS支持接口同步或異步調用,經過對config對象超時時間的設置,能夠實現軟件層面的服務過載保護。
同步調用:
HelloPrx prx = c.stringToProxy("TestApp.HelloServer.HelloObj");
//發起遠程調用
prx.hello(1000, "hello word");
異步調用:
HelloPrx prx = c.stringToProxy("TestApp.HelloServer.HelloObj");
//發起遠程調用
prx.async_hello(new HelloPrxCallback() {

@Override
    public void callback_expired() { }
    @Override
    public void callback_exception(Throwable ex) { }
    @Override
    public void callback_hello(String ret) {
        System.out.println(ret);
    }
}, 1000, "hello word");

從去年到如今,公司遷移改造如火如荼的進行。主要目標是從.net代碼中閱讀邏輯,用JAVA改寫成一個個TARS服務。同時提供更高的可用性,爲公司app相關的新需求迭代保駕護航。
在這個過程當中,對於app的接口提供層(Tomcat部署)改動極大,從原來直接訪問數據持久層到調用一個個TARS微服務,其中不乏一些問題。
曾經一段時間,對於TARS的接入採起了最簡單有效的同步方式,並利用TARS提供的客戶端同步超時配置來處理接口超時。結果,一個訪問頻繁的讀取接口因爲網絡傳輸的不穩定,會致使連鎖的處理線程獨佔,從而下降整個服務吞吐能力,並伴有重啓等現象。
通過jvm,gc等分析,改用TARS提供的異步方式獲取接口返回以及編碼層面細粒度的超時控制,基本解決了上述問題。目前,業務層調用總量也翻了番(峯值從當時120W左右到目前250W),節省了一半的設備。
TARS被調方式的多樣性也對不一樣業務場景支持更加全面。

  1. JCE-WUP協議
    TARS除了支持客戶端經過JCE生成類的調用方式,還能夠發起WUP數據包協議調用。

什麼是WUP:
WUP(wireless uni-protocol)無線統一協議
基於JCE編碼的命令字(Command)層協議封裝
UniPacket實現請求與迴應包對象的封裝
支持協議動態擴展
序列化的數據可用於網絡傳輸或者持久化存儲
支持直接調用TARS的服務端

JAVA版本封包方式
TafUniPacket uniPacket = new TafUniPacket();
uniPacket.setTafVersion(Const.VERSION_WUP3);
uniPacket.setEncodeName("UTF-8");
uniPacket.setServantName("TestApp.HelloServer.HelloObj");
uniPacket.setFuncName("hello");
uniPacket.put("word", "Hello World");
byte[] sendPackect = uniPacket.encode();
隨後本身使用Socket發包,調用信息爲TARS服務物理機URL,而非主控URL。
TARS經過輪詢或者健康統計來選擇可用URL。
具體邏輯可查看tars-core源碼,com.qq.TARS.client.cluster.DefaultLoadBalance類:
圖片描述
對應於WUP,TARS有相同的概念TUP。相關工具類爲TARSUniPacket,封包、解包、調用TARS服務方式徹底同樣。
https://github.com/Tencent/TA...

05.結合版本控制工具編譯和發佈
TARS支持經常使用版本控制管理工具的關聯編譯:SVN/GIT。錄入SVN路徑,可掃描到該路徑下有效的分支。錄入GIT路徑,可掃描該目錄下有效TAG分支。
圖片描述
TARS編譯界面

發佈的相關日誌管理也集成在平臺中,可實時肯定發佈狀況。
圖片描述
TARS發佈界面

全部的TARS項目用的編譯發佈都是一套,經過必定隊列分配進行做業。編譯後會生成惟一的發佈版本。存儲了歷史發佈記錄,可追溯,方便回滾。
團隊中有不少業務開發並行進行,會建立不少分支。有時你想學習別人的代碼,但又發現有不少分支沒法肯定目前線上運行的版本,經過發佈日誌就可查詢最近發佈的版本分支。

06.TARS提供了容器接口測試功能
服務正常發佈後,遵循TARS自定義入參出參的格式,便可調用JCE中定義的方法進行自測。
圖片描述
TARS接口測試

對於一個接口的開發,本地測試完,只能說接口邏輯通了。放到線上可能會出種種問題,環境配置、接口性能、接口未能符合分佈式的考慮等等。這個測試功能無疑是能夠驗證線上是否正確的良好手段。
加上TARS的接口能夠轉換暴露成HTTP形式,因此,QA與咱們達成一致,每次提測的接口必須提供HTTP的調用。這樣既方便的了功能驗證,又能夠遵循原先的壓測形式。

07.服務多維度監控
服務調量和性能指標監控直觀反應服務運行狀況,經過不一樣維度的設置和查詢,可迅速評估流量高峯、定位響應異常、查看調用路徑以及優化調用毛刺。

圖片描述

TARS監控已經成爲咱們定位問題的第一入口。流量抖動和耗時增長基本能夠一目瞭然。監控還細化到接口維度,爲「閒暇時間」接口優化提供了參考。

08.TARS提供了豐富的參數配置
TARS的默認配置對於平日開發維護基本夠用。對於特殊業務的特定配置,TARS一樣支持,可經過調節各類參數來增長服務表現。舉例TARS-JAVA,可經過節點服務管理增長Reactor模型工做線程數,亦可經過修改配置模板調優jvm參數或服務超時等特性。
記得某業務服務從Tomcat改用TARS。緣由沒必要多說,主要是默認了TARS的高吞吐以及容錯等特性。可運行一天後,忽然收到了短信告警,平均耗時超過閾值。打開TARS監控觀察,調用量沒有明顯上漲,調用曲線也符合以前業務特性。
「怎麼耗時一直在慢慢上漲」。當時第一反應是否是代碼層面問題,排查了一圈,基本肯定和原有「湯姆貓」上運行的代碼一致,除了適配TARS入口調用的代碼。再查看了物理機的監控,CPU/IO/MEM均沒有特別異常。
經過對TARS特性監控的查看,注意到相關監控中req.queue.waitingtime(請求在隊列中等待時間),jvm.thread.num(jvm當前線程總數) 確有異常。等待時間曲線階段性增加,線程數卻很少。初步斷定應該與服務器處理線程有關。
「都是應用服務器,處理能力怎麼那麼低,若是是Tomcat會器調整maxConnections,acceptCount等等」。
倒騰了半天,原來TARS也支持容器性能細粒度的修改。因而把工做線程數,從默認配置的5改爲了32,重啓觀察一陣,現象沒有再發生。
TARS同時提供私有模板功能,可作更細粒度的配置,甚至jvm層面的調優。把配置能力沒有保留的提供給使用者也是個優秀架構易用性的重要體現。

0x05 TARS的展望
Tencent已於2017年04月10日正式在github上對外開放了TARS的開源版本,同時提供了技術討論羣(qq技術交流羣:579079160),並表示會內部一直使用和對外一直維護。
圖片描述

能夠預見,TARS將可以支持更多天馬行空的產品需求,對於業務支撐和線上極端狀況的容錯度將愈來愈大。但願這篇科普能夠勾起各位的興趣,幫助你們早日加入使用TARS的行列。

相關文章
相關標籤/搜索