skywalking安装以及使用go
Skywalking是分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s)架构而设计。提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案。
1.部署Elasticsearch
这里基于Docker简单单机部署,普通部署和集群部署可以参考官方文档。
docker pull elasticsearch:7.6.2
指定单机启动
注:通过ES_JAVA_OPTS设置ES初始化内存,否则在验证时可能会起不来
docker run --restart=always -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms512m -Xmx512m" --name='elasticsearch' -d elasticsearch:7.6.2
验证es安装成功, 浏览器地址栏输入:http://127.0.0.1:9200/,浏览器页面显示如下内容:
{ "name" : "592326f2d7c6", "cluster_name" : "docker-cluster", "cluster_uuid" : "zY7SuwXCSLulJGIkJbMgWQ", "version" : { "number" : "7.6.2", "build_flavor" : "default", "build_type" : "docker", "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f", "build_date" : "2020-03-26T06:34:37.794943Z", "build_snapshot" : false, "lucene_version" : "8.4.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" }
2.部署Skywalking OAP
拉取镜像
docker pull apache/skywalking-oap-server:8.5.0-es7
启动Skywalking OAP
注:–link后面的第一个参数和elasticsearch容器名一致; -e SW_STORAGE_ES_CLUSTER_NODES:es7也可改为你es服务器部署的Ip地址,即ip:9200
docker run --name oap --restart always -d --restart=always -e TZ=Asia/Shanghai -p 12800:12800 -p 11800:11800 --link elasticsearch:elasticsearch -e SW_STORAGE=elasticsearch7 -e SW_STORAGE_ES_CLUSTER_NODES=elasticsearch:9200 apache/skywalking-oap-server:8.5.0-es7
3.部署Skywalking UI
拉取镜像
docker pull apache/skywalking-ui:8.5.0
启动Skywalking UI
注:–link后面的第一个参数和skywalking OAP容器名一致;
docker run -d --name skywalking-ui --restart=always -e TZ=Asia/Shanghai -p 8088:8080 --link oap:oap -e SW_OAP_ADDRESS=oap:12800 apache/skywalking-ui:8.5.0
注意,这里的 8080 端口为可视化页面端口。默认账号密码为 admin/admin
go代码示例
这里完美写2个服务8080---->7070
7070的代码如下
package main import ( "fmt" "github.com/SkyAPM/go2sky" v3 "github.com/SkyAPM/go2sky-plugins/gin/v3" "github.com/SkyAPM/go2sky/reporter" "github.com/gin-gonic/gin" "net/http" "time" ) func main() { r := gin.Default() rp, err := reporter.NewGRPCReporter("192.168.100.30:11800", reporter.WithCheckInterval(time.Second)) if err != nil{ fmt.Println("NewGRPCReporter failed!") return } tracer, err := go2sky.NewTracer("demo2", go2sky.WithReporter(rp)) if err != nil{ fmt.Println("NewTracer failed!") return } //使用go2sky-plugins的middleware,就不用我们自己写span了,插件帮我们完成 go2sky.SetGlobalTracer(tracer) r.Use(v3.Middleware(r, tracer)) r.GET("/",test) r.Run(":7070") } func test(c *gin.Context) { span,ctx, _ :=go2sky.GetGlobalTracer().CreateLocalSpan(c.Request.Context(),go2sky.WithOperationName("demo2-test")) if span!=nil{ span.Log(time.Now(),"start demo2-test") defer span.End() } fmt.Println(fmt.Sprintf("traceid:%s spaneId:%d, test 7070",go2sky.TraceID(ctx),go2sky.SpanID(ctx))) c.String(http.StatusOK, "test 7070") }
8080的代码如下
package main import ( "context" "crypto/tls" "fmt" "github.com/SkyAPM/go2sky" v3 "github.com/SkyAPM/go2sky-plugins/gin/v3" "github.com/SkyAPM/go2sky/reporter" "github.com/gin-gonic/gin" "io/ioutil" "net/http" "time" ) func main() { r := gin.Default() rp, err := reporter.NewGRPCReporter("192.168.100.30:11800", reporter.WithCheckInterval(time.Second)) if err != nil { fmt.Println("NewGRPCReporter failed!") return } tracer, err := go2sky.NewTracer("demo1", go2sky.WithReporter(rp)) if err != nil { fmt.Println("NewTracer failed!") return } //使用go2sky-plugins的middleware,就不用我们自己写span了,插件帮我们完成 go2sky.SetGlobalTracer(tracer) r.Use(v3.Middleware(r, tracer)) r.GET("/", test) r.Run(":8080") } func test(c *gin.Context) { span, ctx, _ := go2sky.GetGlobalTracer().CreateLocalSpan(c.Request.Context(), go2sky.WithOperationName("demo1-test")) if span != nil { defer span.End() } fmt.Println(fmt.Sprintf("traceid:%s spaneId:%d, test 8080",go2sky.TraceID(ctx),go2sky.SpanID(ctx))) HttpRequest(ctx) c.String(http.StatusOK, "test 8080") } func HttpRequest(ctx context.Context) { url := "http://localhost:7070/" request, _ := http.NewRequest(http.MethodGet, url, nil) span, _ := go2sky.GetGlobalTracer().CreateExitSpan(ctx, "httpRequest", url, func(headerKey, headerValue string) error { request.Header.Set(headerKey, headerValue) return nil }) defer span.End() span.Log(time.Now(), "start "+url) request = request.WithContext(ctx) client := http.Client{Transport: &http.Transport{DisableKeepAlives: true, TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}} response, err := client.Do(request) if err != nil { span.Error(time.Now(), fmt.Sprintf("%v", err)) } else { defer response.Body.Close() responseByte, _ := ioutil.ReadAll(response.Body) span.Log(time.Now(), "response:"+string(responseByte)) fmt.Println(fmt.Sprintf("traceid:%s spaneId:%d, response%s", go2sky.TraceID(ctx), go2sky.SpanID(ctx), string(responseByte))) } }
运行结果
附GRPC使用:
package main import ( "context" "fmt" "github.com/SkyAPM/go2sky" "google.golang.org/grpc" "google.golang.org/grpc/metadata" agentv3 "skywalking.apache.org/repo/goapi/collect/language/agent/v3" ) // ClientInterceptor 客户端拦截器 func ClientTracing() grpc.UnaryClientInterceptor { return func(ctx context.Context, method string, request, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { md, ok := metadata.FromOutgoingContext(ctx) if !ok { md = metadata.New(nil) } else { md = md.Copy() } span, err := go2sky.GetGlobalTracer().CreateExitSpan(ctx, "GRPC Client Request", method, func(headerKey, headerValue string) error { md.Set(headerKey, headerValue) return nil }) if err == nil && span != nil { defer span.End() span.SetSpanLayer(agentv3.SpanLayer_RPCFramework) ctx = metadata.NewOutgoingContext(ctx, md) } fmt.Println(fmt.Sprintf("traceid:%s spaneId:%d, GRPC Client Call:%s", go2sky.TraceID(ctx), go2sky.SpanID(ctx), method)) err = invoker(ctx, method, request, reply, cc, opts...) return err } } // ServerInterceptor Server 端的拦截器 func ServerTracing() grpc.UnaryServerInterceptor { return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { md, ok := metadata.FromIncomingContext(ctx) if !ok { md = metadata.New(nil) } span, newCtx, err := go2sky.GetGlobalTracer().CreateEntrySpan(ctx, info.FullMethod, func(headerKey string) (string, error) { headerValues := md.Get(headerKey) if len(headerValues) > 0 { return headerValues[0], nil } return "", nil }) if err == nil && span != nil && newCtx != nil { defer span.End() span.SetSpanLayer(agentv3.SpanLayer_RPCFramework) ctx = newCtx } fmt.Println(fmt.Sprintf("traceid:%s spaneId:%d, GRPC Server Start:%s", go2sky.TraceID(ctx), go2sky.SpanID(ctx), info.FullMethod)) return handler(ctx, req) } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?