日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

技术分享 | jaeger链路日志实现

發(fā)布時(shí)間:2023/12/4 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 技术分享 | jaeger链路日志实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

源寶導(dǎo)讀:隨著企業(yè)應(yīng)用越來越復(fù)雜,內(nèi)部的調(diào)用鏈條越來越長,性能問題也變得越來越難以定位和排查,為了應(yīng)對此問題,我們在移動(dòng)平臺(tái)中引入了“jaeger調(diào)用鏈追蹤工具”,幫助我們高效定位云端服務(wù)的性能問題。本文將分享我們相關(guān)的技術(shù)實(shí)踐。

一、背景

? ? 大家好,很幸運(yùn)代表團(tuán)隊(duì)和大家分享一下,天際-移動(dòng)平臺(tái)團(tuán)隊(duì)在實(shí)現(xiàn)分布式鏈路日志追蹤過程的心路歷程。移動(dòng)應(yīng)用的后臺(tái)服務(wù),其內(nèi)部調(diào)用鏈路往往很復(fù)雜,一旦發(fā)現(xiàn)性能問題,很難快速精準(zhǔn)的定位,嚴(yán)重影響研發(fā)小伙伴們的幸福感。具體問題表現(xiàn)在這幾個(gè)方面:

  • 容器內(nèi)日志簡單,某些前后端數(shù)據(jù)不一致導(dǎo)致的的問題無法定位。

  • PaaS小程序微服務(wù)化,服務(wù)之間調(diào)用雖然有嚴(yán)格規(guī)定,但是出現(xiàn)問題時(shí)還是無法快速定位問題的出處。

  • 測試人員登記bug需要粘貼詳細(xì)的請求、響應(yīng),開發(fā)通過創(chuàng)造數(shù)據(jù),模擬這個(gè)請求來慢慢排查問題所在。

二、技術(shù)選型

移動(dòng)平臺(tái)中關(guān)于PaaS小程序后端的現(xiàn)有架構(gòu):

? ? 從上圖中可知,我們當(dāng)前同時(shí)支持了PHP、Go、Nodejs三種編程語言構(gòu)建的應(yīng)用,如果要做日志的鏈路追蹤,起碼需要兼容多編程語言。

? ? 通過分析,我們總結(jié)出“日志追蹤工具”應(yīng)滿足的條件:

  • 支持多語言。保證PHP、Go、Nodejs都可以接入日志,才能形成完整鏈路。

  • 一定是無侵入式的。這樣在多個(gè)服務(wù)中埋點(diǎn)比較方便,日志服務(wù)升級維護(hù)成本也不會(huì)高。

  • 對于特定標(biāo)簽的日志可以通過微信、郵箱甚至短信的方式通知到開發(fā)或者運(yùn)維同學(xué)。

  • 能夠?qū)PI接口的性能統(tǒng)計(jì)分析。

  • 由于我們使用的阿里云日志,日志服務(wù)最好可以將阿里云日志作為數(shù)據(jù)存儲(chǔ)。

三、jaeger工具介紹

3.1、簡介

? ? Jaeger是由Uber開源的分布式追蹤系統(tǒng),一套完整的Jager追蹤系統(tǒng)包括Jaeger-client、Jaeger-agent、Jaeger-collector、Database和Jaeger-query UI等基本組件。

3.2、Jaeger的優(yōu)勢

  • 采用Open Tracing標(biāo)準(zhǔn),支持跨語言。

  • 分布式上下文傳播。

  • 分布式是鏈路追蹤。

  • 服務(wù)依賴性分析。

  • 性能延遲監(jiān)控。

3.3、jaeger的技術(shù)原理

架構(gòu)圖:

  • jaeger-client:jaeger 的客戶端,實(shí)現(xiàn)了opentracing協(xié)議。

  • jaeger-agent:jaeger-client 的一個(gè)代理程序,client將收集到的調(diào)用鏈數(shù)據(jù)發(fā)給agent,然后由agent發(fā)給collector。

  • jaeger-collector:負(fù)責(zé)接收jaeger client或者jaeger agent上報(bào)上來的調(diào)用鏈數(shù)據(jù),然后做一些校驗(yàn),比如時(shí)間范圍是否合法等,最終會(huì)經(jīng)過內(nèi)部的處理存儲(chǔ)到后端存儲(chǔ)。后端存儲(chǔ)是一個(gè)可插拔的組件,Jaeger on Aliyun Log Service 增加了對阿里云日志服務(wù)的支持。

  • jaeger-query:專門負(fù)責(zé)調(diào)用鏈查詢的一個(gè)服務(wù),有自己獨(dú)立的UI。

  • spark-job:基于spark的運(yùn)算任務(wù),可以計(jì)算服務(wù)的依賴關(guān)系,調(diào)用次數(shù)等。

? ? 說明:其中jaeger-collector和jaeger-query是必須的,其余的都是可選的,我們采用agent上報(bào)的方式,讓客戶端上報(bào)日志到agent,以減少部分性能消耗。jaeger-collector支持Aliyun Log Service,也是很好的滿足我們要求。

? ? aliyun-log-jaeger-collector配置表:

3.4、日志

單條鏈路:

? ? 可以清晰的看到一個(gè)請求的發(fā)起時(shí)間,所經(jīng)過的服務(wù)數(shù)量、所調(diào)用服務(wù)的依賴關(guān)系、消耗的時(shí)長等信息。

3.5、技術(shù)名詞解釋

  • service:微服務(wù)的名稱或者標(biāo)識(shí)。

  • operation:一個(gè)span的名稱,簡單易讀。

  • span:系統(tǒng)中具有開始時(shí)間和執(zhí)行時(shí)長的邏輯運(yùn)行單元 。具體可以理解為一次方法調(diào)用, 一個(gè)程序塊的調(diào)用或者一次RPC/數(shù)據(jù)庫訪問。

  • tags:“鍵值對”形式的tags,一個(gè)span可以有多tags,tags是對span的簡單注解,不會(huì)被子級span繼承。tags value 的標(biāo)準(zhǔn)含義看參考https://opentracing.io/ specification/conventions

  • logs:一個(gè)span可以有多l(xiāng)ogs,每一個(gè)logs都可以自定名稱以及任意大小的存儲(chǔ)結(jié)構(gòu)。

  • spanContext:跨進(jìn)程邊界,傳遞到下級span的狀態(tài),每個(gè)span都有訪問spanContext的方法。當(dāng)在創(chuàng)建span時(shí),向傳輸協(xié)議Inject(注入)從上級span傳輸協(xié)議中Extract(提取)的spanContext既可。

  • Inject and Extract:spanContext可以通過Injected操作向Carrier增加,或者通過ExtractedCarrier中獲取,跨進(jìn)程通訊數(shù)據(jù)。通過這種方式,SpanContexts可以跨越進(jìn)程邊界,并提供足夠的信息來建立跨進(jìn)程的span間關(guān)系(因此可以實(shí)現(xiàn)跨進(jìn)程連續(xù)追蹤)。

四、落地應(yīng)用

4.1、??核心設(shè)計(jì)思路:

  • 采用jaeger-client上報(bào)數(shù)據(jù)到j(luò)aeger-agent,再由jaeger-agent集中處理傳輸?shù)絡(luò)aeger-collector,之后jaeger-collector會(huì)將合法的數(shù)據(jù)存儲(chǔ)到阿里日志。

  • 之后在我們需要時(shí),可以通過jaeger-query + jaeger-ui來查詢?nèi)罩尽?/p>

  • 我們采用jaeger的默認(rèn)方式,將spanContext中跨進(jìn)程數(shù)據(jù)(當(dāng)前只有uber-trace-id)注入到header中,當(dāng)下游服務(wù)在請求header中提取到對應(yīng)的跨進(jìn)程數(shù)據(jù)就會(huì)形成一個(gè)依賴和鏈路關(guān)系,如果沒有就生成一個(gè)新的供下游服務(wù)發(fā)現(xiàn)和關(guān)聯(lián)。

4.2、traceId傳遞方式

// 上游服務(wù)將traceId注入到header中$header = TraceJaeger::inject($header); // 下游服務(wù)解析獲取traceId,完成一個(gè)請求的傳遞 $target = []; foreach (request()->headers->all() as $key => $value) {$target[$key] = Arr::first($value); } $spanContext = $this->tracer->extract(TEXT_MAP, $target);

4.3、應(yīng)用結(jié)果

串行

traceId:1660cc5871c2df9e1660cc5871c34a59

并行

traceId:1660d1de34f6c7691660d1de34f5a93b

? ? 以上都是我們實(shí)際的調(diào)用場景,應(yīng)用創(chuàng)建的改造前(串行),改造后(并行)。可以很清晰的看到服務(wù)之間的調(diào)用和所花費(fèi)的時(shí)間。

? ? 我們打開可以看到app-service這個(gè)服務(wù)被調(diào)用的詳細(xì)信息。包括請求方式、請求數(shù)據(jù)、響應(yīng)數(shù)據(jù)等。

4.4、兼容Go語言

1、go服務(wù)gin中間件使用開源框架,代碼倉庫:https://github.com/yuchanns/bullets

go get -u github.com/yuchanns/bullets

2、中間件使用:

package main import ("context""github.com/gin-gonic/gin""github.com/yuchanns/bullets/common""github.com/yuchanns/bullets/common/middlewares""os" ) func main() {g := gin.Default()//服務(wù)名serviceName := "openapi-service"//上報(bào)agent地址agentAddr := os.Getenv("OPENTRACING_AGENT")//操作前綴operationPrefix := []byte("api-request-")opentracerCloseFunc, opentracerMiddleware, err := middlewares.BuildOpenTracerInterceptor(serviceName, agentAddr, operationPrefix)if err != nil {common.Logger.Error(context.Background(), err)} else {defer opentracerCloseFunc()g.Use(opentracerMiddleware)} }

3、自定義打tag:

import ("github.com/gin-gonic/gin""github.com/opentracing/opentracing-go""github.com/opentracing/opentracing-go/log""github.com/pkg/errors" ) func CustomTag(ctx *gin.Context) {if cspan, ok := ctx.Get("tracing-context"); ok {if span, ok := cspan.(opentracing.Span); ok {span.SetTag("error", true)span.LogFields(log.Error(errors.New("err")))span.LogFields(log.String("exampleKey", "stringValue"))}} }

4.5、兼容PHP語言

1、安裝composer包

composer require tracelog/jaeger

2、根目錄執(zhí)行

php artisan vendor:publish

3、選擇發(fā)布配置?件

Tracelog\jaeger\config\jaeger.php文件拷貝到工程項(xiàng)目的config?錄

4、修改配置?件

return['enabled' => env('JAEGER_ENABLED', true), //是否開啟'service_name' => env('JAEGER_SERVICE_NAME', env('APP_NAME', 'Laravel')), //服務(wù)名稱'agent' => [ 'host' => env('OPENTRACING_AGENT','0.0.0.0:6831'), //日志服務(wù)代理 地址],'watchers' => [Tracelog\jaeger\watchers\RequestWatcher::class, //請求日志監(jiān)聽Tracelog\jaeger\watchers\FrameworkWatcher::class //項(xiàng)目日志推送] ]

使? jukylin/jaeger-php 直接記錄。

參考:https://github.com/jukylin/jaeger-php/blob/master/example/HTTP.php

4.6、集成到Laravel Log

? ? 使?框架中Log??時(shí),也可以將日志記錄到代理。針對當(dāng)前框架情況修改(添加)/app/Common/StreamHandler ---> Handle

if (config('jaeger.enabled')){$span = TraceJaeger::client()->startSpan($record['message'],['child_of' => TraceJaeger::getRootSpan()]);$span->setTag('log.level', $record['level_name']);$span->log($record['context']);$span->finish();TraceJaeger::client()->flush(); }

說明:對Nodejs的兼容,我們目前正在實(shí)現(xiàn)中。

五、總結(jié)

? ? 自從鏈路日志工具上線后,我們排查問題的效率有了很大提升。我們可以直接通過日志定位出有問題的后端服務(wù),通過請求和響應(yīng)數(shù)據(jù)快速判斷問題原因,極大的提高了工作效率和排查問題的幸福感!

------ END ------

作者簡介

智同學(xué):?研發(fā)工程師,目前負(fù)責(zé)天際-移動(dòng)平臺(tái)的研發(fā)工作。

也許您還想看

記AWSS3在iOS端的一次改造事件

明源云創(chuàng)CI/CD技術(shù)演進(jìn)

微前端架構(gòu)在容器平臺(tái)的應(yīng)用

AI云店小程序演變之路

天眼探針基于rrweb實(shí)現(xiàn)前端異常視頻錄制與回放功能

總結(jié)

以上是生活随笔為你收集整理的技术分享 | jaeger链路日志实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。