一、背景介紹
1、在微服務時代,服務與服務之間的調用關系錯綜復雜,某一服務出問題可能會導致整條鏈路雪崩。
2、微服務的請求鏈路長、涉及服務多、排查問題難,我們如何快速的定位到異常服務,盡快解決生產問題
3、我們保持對業界方案關注的同時,如:zipkin、skywalking、ELK等,如何結合自身項目的特點,搭建一套高可用、可擴展的錯誤歸因系統?
目前的zipkin和ELK也存在一些問題沒有解決:
zipkin主要是告訴我們請求報錯了,但是並不能發現運行時異常,例如:業務系統捕獲了一個Exception,返回了一個異常碼,這是上游調用鏈不會上報錯誤信息。對於鏈路平均請求時間沒有提供統計功能。
ELK使用於已經知道錯誤的情況下去查找具體發生了什么?但是對於發生的頻率,接口調用次數、錯誤率沒有很直觀的展示。另外頻繁的在zipkin和ELK之間切換也是很不好的體驗。
開始想在zipkin的基礎上進行改造,后來發現自己實現更加靈活、更容易擴展。
二、架構圖
數據采集:
基本是過濾器和aop思想在請求前后埋點、收集請求信息。
數據傳輸層:
收集完可以選擇發送kafka或打印日志到本地,從日志中收集請求信息類似ELK。
數據過濾與轉換:
可采樣、去重復、去ELK中查詢運行時異常信息等分析。可以自己擴展。處理完可以選擇存儲方式、包括做一些優化、例如:列儲存、每天建立一個索引。
數據存儲:
Elasticsearch和mysql等,可以自己擴展。
三、調用鏈數據(span)
1、調用鏈本身數據
2、本地服務信息
3、遠程服務信息
4、參數、協議等
5、異常信息
{ "traceId": "cc43026d3e04462fb7fd488fab860891", "id": "i6pmhdzdw6sln8vr", "parentId": "7n01ym82zzvmfquj", "traceType": "http-client" "name": "http://127.0.0.1:8090/doNormal", "duration": 53, "start": 1543034698671, "resultType": "success", "localHost": "172.22.51.117", "localPort": 80, "localServiceName": "sscj-games-server-entrance", "remoteHost": "127.0.0.1", "remotePort": 8090, "remoteServiceName": "sscj-games-server-entrance", "tagMap": { "rest.method": "getForObject", "result": "resp_normal", "http.reqHeader": "{user-agent=Java/1.8.0_51}", "args[1]": "'java.lang.String'", "args[0]": "http://127.0.0.1:8090/doNormal", "http.method": "GET", "http.code": "200", "args[2]": "[]" }, "exceptionMsg": "", "exceptionType": "", }
1、調用樹結構
2、調用過程
3、采集校驗流程
四、數據過濾和存儲
1、數據過濾與存儲
過濾器可橫向擴展多個、自己實現的過濾器更加靈活;可以根據需求去做統計、分析、預警等。
2、數據查詢與展示
由Elasticsearch聚合api做統計分析。
五、效果展示
調用鏈列表頁面:
調用鏈樹:
調用鏈詳情: