Go-kratos 框架商城微服務實戰之使用者服務 (三) - 鏈路追蹤
這篇主要給服務加入鏈路追蹤Tracing 。寫的不清晰的地方可看原始碼 , 歡迎大佬指教。
注:豎排 … 程式碼省略,為了保持文章的篇幅簡潔,我會將一些不必要的程式碼使用豎排的 . 來代替,你在複製本文程式碼塊的時候,切記不要將 . 也一同複製進去。
jaeger
的安裝
- docker 的安裝方式
docker run --rm --name jaeger -p14268:14268 -p16686:16686 jaegertracing/all-in-one
// 執行完畢之後,切記別退出服務
- 瀏覽器訪問
http://127.0.0.1:16686/
驗證是否安裝成功
- 專案程式碼引入
user/configs/config.yaml
配置檔案新增
.
.
.
trace:
endpoint: http://127.0.0.1:14268/api/traces
- 修改
/user/internal/conf/conf.proto
檔案
syntax = "proto3";
.
.
.
message Bootstrap {
Server server = 1;
Data data = 2;
Trace trace = 3; // 新增 trace
}
.
.
.
message Trace {
string endpoint = 1;
}
根目錄執行
make config
命令,生成新的配置檔案修改
user/internal/server/grpc.go
檔案
package server
import (
.
.
.
"github.com/go-kratos/kratos/v2/middleware/tracing" // 新增引入
)
// NewGRPCServer new a gRPC server.
func NewGRPCServer(c *conf.Server, u *service.UserService, logger log.Logger) *grpc.Server {
var opts = []grpc.ServerOption{
grpc.Middleware(
recovery.Recovery(),
tracing.Server(), // 新增 tracing
),
}
.
.
.
v1.RegisterUserServer(srv, u)
return srv
}
- 修改
user/cmd/user/main.go
檔案
package main
import (
.
.
.
"github.com/go-kratos/kratos/v2/middleware/tracing"
"go.opentelemetry.io/otel/exporters/jaeger"
"go.opentelemetry.io/otel/sdk/resource"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
)
.
.
.
// Set global trace provider 新增 tracer 方法
func setTracerProvider(url string) error {
// Create the Jaeger exporter
exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url)))
if err != nil {
return err
}
tp := tracesdk.NewTracerProvider(
// Set the sampling rate based on the parent span to 100%
tracesdk.WithSampler(tracesdk.ParentBased(tracesdk.TraceIDRatioBased(1.0))),
// Always be sure to batch in production.
tracesdk.WithBatcher(exp),
// Record information about this application in an Resource.
tracesdk.WithResource(resource.NewSchemaless(
semconv.ServiceNameKey.String(Name),
attribute.String("env", "dev"),
)),
)
otel.SetTracerProvider(tp)
return nil
}
func main() {
.
.
.
if err := setTracerProvider(bc.Trace.Endpoint); err != nil {
panic(err)
}
app, cleanup, err := initApp(bc.Server, &rc, bc.Data, logger)
if err != nil {
panic(err)
}
defer cleanup()
// start and wait for stop signal
if err := app.Run(); err != nil {
panic(err)
}
}
根目錄執行
make wire
命令,生成新的wire_gen.go
檔案加入具體跟蹤方法
// user/internal/service/user.go 加入到這個檔案裡
// 具體的手機號查詢的方法
package service
import (
"context"
"github.com/go-kratos/kratos/v2/log"
"github.com/golang/protobuf/ptypes/empty"
"go.opentelemetry.io/otel"
"google.golang.org/protobuf/types/known/emptypb"
"time"
v1 "user/api/user/v1"
"user/internal/biz"
)
.
.
.
// GetUserByMobile .
func (u *UserService) GetUserByMobile(ctx context.Context, req *v1.MobileRequest) (*v1.UserInfoResponse, error) {
// add trace
tr := otel.Tracer("service")
ctx, span := tr.Start(ctx, "get user info by mobile")
defer span.End()
user, err := u.uc.UserByMobile(ctx, req.Mobile)
if err != nil {
return nil, err
}
rsp := UserResponse(user)
return &rsp, nil
}
.
.
.
- 測試是否引入成功
啟動專案
kratos run
修改測試檔案
user/test/user.go
讓其執行TestGetUserByMobile()
方法http://127.0.0.1:16686/search
瀏覽器訪問,選擇Service
驗證是否有記錄
本作品採用《CC 協議》,轉載必須註明作者和本文連結