自從實現(xiàn)微服務(wù)化后,我們碰到了很多問題身坐。其中最大的問題就是如何排查故障盏袄,服務(wù)化后的接口通常會依賴多個服務(wù),依賴接口的緩慢會直接影響接口的服務(wù)質(zhì)量葱她。
這種依賴導(dǎo)致的緩慢情況在線上很常見撩扒,但是并不好排查,究其原因是線上都是通過日志進行跟蹤的大量的日志開發(fā)人員并不是很直觀吨些,且有的公司開發(fā)人員是看不到線上具體執(zhí)行情況搓谆。一般來說線上這些小概率故障代表著系統(tǒng)的隱患,當(dāng)流量增大后這些隱患會被放大甚至直接導(dǎo)致線上大規(guī)模故障豪墅,為了避免類似的事情我們需要做很多事情泉手,最直觀的就是用分布式跟蹤系統(tǒng)去統(tǒng)計分析。
我們常見到大牛在講線上性能怎么優(yōu)化偶器,怎么提高性能斩萌,其實有個重要的還環(huán)節(jié)他們并沒有提及,他們是如何發(fā)現(xiàn)低概率故障屏轰?分布式跟蹤系統(tǒng)在大型互聯(lián)網(wǎng)公司是很常見颊郎,但是中小型公司是沒有技術(shù)實力去實現(xiàn)這個系統(tǒng)的。而從我們角度來看即使流量很小但是對于公司仍舊很重要的系統(tǒng)是我們需要強化的霎苗,能夠發(fā)現(xiàn)問題才能解決問題這是我一直貫徹的宗旨姆吭。
分布式跟蹤系統(tǒng)具體的實現(xiàn)是有一定技術(shù)難度的,要實現(xiàn)性能的捕捉唁盏、日志寫入内狸、日志收集整理、日志傳輸厘擂、日志存儲昆淡、日志索引、日志實時分析刽严、最后合并展示昂灵,要求系統(tǒng)能夠應(yīng)對大流量系統(tǒng)的沖擊。如每次請求每個接口產(chǎn)生1k的日志,那么QPS 2000 的服務(wù)器就會產(chǎn)生2M的日志倔既,如果是一次請求依賴5個接口那么就是每秒10M的日志恕曲,當(dāng)線上業(yè)務(wù)更復(fù)雜流量更大的時候鹏氧,這個數(shù)值還會增加渤涌。
大型互聯(lián)網(wǎng)公司有很多分布式跟蹤系統(tǒng),能夠承受幾十億流量把还,但是對于小公司來說這種架構(gòu)負擔(dān)很大实蓬,其中很多環(huán)節(jié)如依賴分布式消息系統(tǒng)、分布式存儲吊履、分布式計算安皱,光這幾個至少會使用6臺以上服務(wù)器,對于一般小型公司性價比不高艇炎。
這次我們開源的分布式跟蹤是有兩款酌伊,一款是給中小型互聯(lián)網(wǎng)公司使用的單機版他可以支撐PV 2000w的業(yè)務(wù)系統(tǒng)(如支付系統(tǒng))。另外還有一款支持分布式幾十億PV的分布式跟蹤系統(tǒng)缀踪。目前剛剛開放Fiery單機版(https://github.com/weiboad/fiery)這個版本是針對中小型企業(yè)使用而設(shè)計的居砖,整個項目就是一個Jar包開箱即用,只要有Java8runtime即可直接使用驴娃,當(dāng)然系統(tǒng)需要簡單的做一個埋點工作奏候。而C++分布式版本依賴東西較多對運維人員有一定能力要求,后續(xù)看單機版情況后續(xù)放出唇敞。這些完全開源內(nèi)部有敏感數(shù)據(jù)的核心交易系統(tǒng)也完全可以使用蔗草。
目前市面上是存在著多個方式的分布式跟蹤,有的是公司自己內(nèi)部使用疆柔,有的是小規(guī)模免費大規(guī)模付費的服務(wù)咒精。常見的分布式跟蹤是通過統(tǒng)計方式去記錄每一個Block的性能情況。目前我們提供的方式和市面的方式并不完全一樣旷档,我們通過不斷的實驗做了大量的簡化模叙,只保留我們認為真正實用的功能,我們將系統(tǒng)設(shè)計為關(guān)鍵系統(tǒng)分布式監(jiān)控彬犯。如支付系統(tǒng)向楼、交易系統(tǒng)。
我們記錄了每個請求的具體情況谐区、返回值湖蜕、具體的性能等信息,通過表格分析可以快速的發(fā)現(xiàn)線上依賴接口性能(第三方或者未埋點的接口性能統(tǒng)計)宋列、做埋點的接口也獨立做了性能排行分析昭抒。通過查看分析表格后我們可以快速的找到最慢的接口請求回放,以此分析線上性能緩慢的原因。通過實踐我們發(fā)現(xiàn)很多情況下都是PHP依賴的數(shù)據(jù)資源緩慢導(dǎo)致了php接口性能不佳灭返。所以埋點的重點都是在依賴資源上盗迟。其他信息用戶可以根據(jù)自己需要增加,這樣可以減少大量無用日志熙含,可以更節(jié)儉一些罚缕。
這次開源的Fiery主要有三個部分、PHP侵入式埋點庫怎静、精簡的日志監(jiān)控推送模塊邮弹、服務(wù)端。這三個就實現(xiàn)了一個PV2000w以下的網(wǎng)站分布式跟蹤蚓聘。
埋點庫會在入口產(chǎn)生Traceid(UUID)這個Traceid內(nèi)隱藏著入口服務(wù)器的IP地址腌乡,請求時間,所有后續(xù)產(chǎn)生的日志都會用這個UUID作為標示夜牡。在日志收集后所有相關(guān)日志都會按這個UUID進行存儲与纽。埋點庫會在運行時負責(zé)接收其他請求發(fā)來的Traceid和發(fā)送產(chǎn)生維護RPCID,RPCID是一個有層級的計數(shù)器塘装,通過它我們可以將調(diào)用關(guān)系次序及層級直接進行還原展示給開發(fā)人員急迂。另外在PHP運行過程中如果產(chǎn)生Exception也會被埋點庫捕獲記錄下來,供服務(wù)端進行去重統(tǒng)計氢哮。最后會將這些日志落地到服務(wù)器本地磁盤袋毙,由于一些原因多個PHP進程同時寫一個文件的時候偶爾會出現(xiàn)亂序情況,我們現(xiàn)在是按進程ID加上項目名稱作為文件名進行落地的冗尤。
Fiery日志抓取傳輸我們實現(xiàn)了一個簡單的版本听盖,這么做是為了簡化使用運維人員的工作,目前確實有很多開源提供類似的功能裂七、但是需要依賴其他環(huán)境皆看,這對于運維來說有一定負擔(dān)。我們還有個實驗性的PHP的日志抓取傳輸服務(wù)背零,但是還是實驗的功能腰吟,預(yù)計會有一定的缺陷各位用戶可以參與調(diào)試改進。
Fiery的服務(wù)端我們做了很多工作徙瓶,內(nèi)置了Lucene和Rocksdb毛雇,分別對請求進行索引和存儲。并且做了一些內(nèi)存統(tǒng)計的工作侦镇,目前我們的統(tǒng)計維度是固定的灵疮,只針對本地接口,依賴接口壳繁,MySQL震捣、Curl的響應(yīng)情況進行統(tǒng)計荔棉、另外提供調(diào)用關(guān)系回放、錯誤日志警報去重統(tǒng)計蒿赢。通過這些功能可以快速的發(fā)現(xiàn)線上關(guān)鍵點的性能故障润樱,系統(tǒng)異常。目前只是單機版羡棵,后續(xù)需要我可以將它進一步擴展成更簡單的分布式方式壹若。
以上這些服務(wù)并不僅僅服務(wù)于線上,目前我們內(nèi)部還用他做了很多有意思的嘗試晾腔,如QA測試的環(huán)境接入一套舌稀,測試完畢后把故障接口產(chǎn)生的Traceid直接發(fā)給開發(fā)啊犬,開發(fā)能夠通過Traceid找到此次請求所有調(diào)用經(jīng)過灼擂、參數(shù)、返回情況觉至、性能都可以直觀看到方便分析.上線之前的單元測試也可以這么做剔应。前段時間我發(fā)微博推廣Fiery的時候有人還提到可以用它做蜜罐,查看黑客入侵的過程语御,具體細節(jié)峻贮。后續(xù)功能還待大家繼續(xù)發(fā)掘和改進,這個系統(tǒng)就是為了填補PHP生態(tài)空缺而做的应闯。
后續(xù)還會提供更多的功能纤控,敬請期待……