GoFrame HTTP示例-Baggage

2022-04-01 14:53 更新

baggage鏈路數(shù)據(jù)傳遞

示例代碼地址:https://github.com/gogf/gf/tree/master/example/trace/http

客戶(hù)端

package main

import (
	"github.com/gogf/gf/contrib/trace/jaeger/v2"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/gtrace"
	"github.com/gogf/gf/v2/os/gctx"
)

const (
	ServiceName       = "http-client"
	JaegerUdpEndpoint = "localhost:6831"
)

func main() {
	var ctx = gctx.New()
	tp, err := jaeger.Init(ServiceName, JaegerUdpEndpoint)
	if err != nil {
		g.Log().Fatal(ctx, err)
	}
	defer tp.Shutdown(ctx)

	StartRequests()
}

func StartRequests() {
	ctx, span := gtrace.NewSpan(gctx.New(), "StartRequests")
	defer span.End()

	ctx = gtrace.SetBaggageValue(ctx, "name", "john")

	content := g.Client().GetContent(ctx, "http://127.0.0.1:8199/hello")
	g.Log().Print(ctx, content)
}

客戶(hù)端代碼簡(jiǎn)要說(shuō)明:

  1. 首先,客戶(hù)端也是需要通過(guò)?jaeger.Init?方法初始化?Jaeger?。
  2. 隨后,這里通過(guò)?gtrace.SetBaggageValue(ctx, "name", "john")?方法設(shè)置了一個(gè)?baggage?,該?baggage?將會(huì)在該請(qǐng)求的所有鏈路中傳遞。不過(guò)我們?cè)撌纠灿袃蓚€(gè)節(jié)點(diǎn),因此該?baggage?數(shù)據(jù)只會(huì)傳遞到服務(wù)端。該方法會(huì)返回一個(gè)新的?context.Context?上下文變量,在隨后的調(diào)用鏈中我們將需要傳遞這個(gè)新的上下文變量。
  3. 其中,這里通過(guò)?g.Client()?創(chuàng)建一個(gè)?HTTP?客戶(hù)端請(qǐng)求對(duì)象,該客戶(hù)端會(huì)自動(dòng)啟用鏈路跟蹤特性,無(wú)需開(kāi)發(fā)者顯示調(diào)用任何方法或者任何設(shè)置。
  4. 最后,這里使用了?g.Log().Print(ctx, content)?方法打印服務(wù)端的返回內(nèi)容,其中的?ctx?便是將鏈路信息傳遞給日志組件,如果?ctx?上下文對(duì)象中存在鏈路信息時(shí),日志組件會(huì)同時(shí)自動(dòng)將?TraceId?輸出到日志內(nèi)容中。

服務(wù)端

package main

import (
	"github.com/gogf/gf/contrib/trace/jaeger/v2"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/net/gtrace"
	"github.com/gogf/gf/v2/os/gctx"
)

const (
	ServiceName       = "http-server"
	JaegerUdpEndpoint = "localhost:6831"
)

func main() {
	var ctx = gctx.New()
	tp, err := jaeger.Init(ServiceName, JaegerUdpEndpoint)
	if err != nil {
		g.Log().Fatal(ctx, err)
	}
	defer tp.Shutdown(ctx)

	s := g.Server()
	s.Group("/", func(group *ghttp.RouterGroup) {
		group.GET("/hello", HelloHandler)
	})
	s.SetPort(8199)
	s.Run()
}

func HelloHandler(r *ghttp.Request) {
	ctx, span := gtrace.NewSpan(r.Context(), "HelloHandler")
	defer span.End()

	value := gtrace.GetBaggageVar(ctx, "name").String()

	r.Response.Write("hello:", value)
}

服務(wù)端代碼簡(jiǎn)要說(shuō)明:

  1. 當(dāng)然,服務(wù)端也是需要通過(guò)?jaeger.Init?方法初始化?Jaeger?。
  2. 服務(wù)端啟動(dòng)啟用鏈路跟蹤特性,開(kāi)發(fā)者無(wú)需顯示調(diào)用任何方法或任何設(shè)置。
  3. 服務(wù)端通過(guò)?gtrace.GetBaggageVar(ctx, "name").String()?方法獲取客戶(hù)端提交的?baggage?信息,并轉(zhuǎn)換為字符串返回。

效果查看

啟動(dòng)服務(wù)端:


啟動(dòng)客戶(hù)端:


可以看到,客戶(hù)端提交的?baggage?已經(jīng)被服務(wù)端成功接收到并打印返回。并且客戶(hù)端在輸出日志內(nèi)容的時(shí)候也同時(shí)輸出的?TraceId?信息。?TraceId?是一條鏈路的唯一?ID?,可以通過(guò)該?ID?檢索該鏈路的所有日志信息,并且也可以通過(guò)該?TraceId?在?Jaeger?系統(tǒng)上查詢(xún)?cè)撜{(diào)用鏈路詳情。

在?Jaeger?上查看鏈路信息:


可以看到在這里出現(xiàn)了兩個(gè)服務(wù)名稱(chēng):?tracing-http-client?和?tracing-http-server?,表示我們這次請(qǐng)求涉及到兩個(gè)服務(wù),分別是?HTTP?請(qǐng)求的客戶(hù)端和服務(wù)端,并且每個(gè)服務(wù)中分別涉及到2個(gè)?span?鏈路節(jié)點(diǎn)。

我們點(diǎn)擊這個(gè)?trace?的詳情,可以看得到調(diào)用鏈的層級(jí)關(guān)系。并且可以看得到客戶(hù)端請(qǐng)求的地址、服務(wù)端接收的路由以及服務(wù)端路由函數(shù)名稱(chēng)。我們這里來(lái)介紹一下客戶(hù)端的?Atttributes?信息和?Events?信息,也就是?Jaeger?中展示的?Tags?信息和?Process?信息。

HTTP Client Attributes


Attribute/Tag
說(shuō)明
otel.instrumentation_library.name 當(dāng)前儀表器名稱(chēng),往往是當(dāng)前span操作的組件名稱(chēng)
otel.instrumentation_library.version 當(dāng)前儀表器組件版本
span.kind

當(dāng)前span的類(lèi)型,一般由組件自動(dòng)寫(xiě)入。常見(jiàn)span類(lèi)型為:

類(lèi)型
說(shuō)明

client 

客戶(hù)端
server 服務(wù)端
producer 生產(chǎn)者,常用于MQ
consumer 消費(fèi)者,常用于MQ
internal 內(nèi)部方法,一般業(yè)務(wù)使用
undefined 未定義,較少使用
status.code 當(dāng)前span狀態(tài),0為正常,非0表示失敗
status.message 當(dāng)前span狀態(tài)信息,往往在失敗時(shí)會(huì)帶有錯(cuò)誤信息
hostname 當(dāng)前節(jié)點(diǎn)的主機(jī)名稱(chēng)
ip.intranet 當(dāng)前節(jié)點(diǎn)的主機(jī)內(nèi)網(wǎng)地址列表
http.address.local HTTP通信的本地地址和端口
http.address.remote HTTP通信的目標(biāo)地址和端口
http.dns.start 當(dāng)請(qǐng)求的目標(biāo)地址帶有域名時(shí),開(kāi)始解析的域名地址
http.dns.done 當(dāng)請(qǐng)求的目標(biāo)地址帶有域名時(shí),解析結(jié)束之后的IP地址
http.connect.start 開(kāi)始創(chuàng)建連接的類(lèi)型和地址
http.connect.done 創(chuàng)建連接成功后的類(lèi)型和地址

HTTP Client Events


Event/Log
說(shuō)明
http.request.headers HTTP客戶(hù)端請(qǐng)求提交的Header信息,可能會(huì)比較大。
http.request.baggage HTTP客戶(hù)端請(qǐng)求提交的Baggage信息,用于服務(wù)間鏈路信息傳遞。
http.request.body

HTTP客戶(hù)端請(qǐng)求提交的Body數(shù)據(jù),可能會(huì)比較大,最大只記錄512KB,如果超過(guò)該大小則忽略。

http.response.headers HTTP客戶(hù)端請(qǐng)求接收返回的的Header信息,可能會(huì)比較大。
http.response.body HTTP客戶(hù)端請(qǐng)求接收返回的Body數(shù)據(jù),可能會(huì)比較大,最大只記錄512KB,如果超過(guò)該大小則忽略。

HTTP Server Attributes


?HTTP Server?端的?Attributes?含義同?HTTP Client?,在同一請(qǐng)求中,打印的數(shù)據(jù)基本一致。

HTTP Server Events


?HTTP Server?端的?Events?含義同?HTTP Client?,在同一請(qǐng)求中,打印的數(shù)據(jù)基本一致。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)