凉山建设局网站,酒店vi设计公司,焦作市建设工程网站,企业邮箱申请流程简介#xff1a; 本文主要介绍Jaeger最新的插件化后端的接口以及开发方法#xff0c;让大家能够一步步的根据文章完成一个Jaeger插件的开发。此外SLS也推出了对于Jaeger的支持#xff0c;欢迎大家试用。
随着云原生 微服务的推广和落地#xff0c;服务监控也变得越来越重…简介 本文主要介绍Jaeger最新的插件化后端的接口以及开发方法让大家能够一步步的根据文章完成一个Jaeger插件的开发。此外SLS也推出了对于Jaeger的支持欢迎大家试用。
随着云原生 微服务的推广和落地服务监控也变得越来越重要了。中等规模的微服务场景下运维同学已经无法通过日志还原请求的调用轨迹和请求所经过服务的执行耗时更不用说去定位和分析服务异常根因研发运维同学需要一个服务监控工具它可以还原每次请求的服务调用轨迹以及服务执行时间并以图的形式展现出来。分布式链路追踪系统孕育而生。 近些年市面上有大量优秀的商业产品这些商业产品通常也叫APM应用性能监控比如国内商业公司有阿里云ARMS听云博瑞云智慧等等国外优秀的商业公司有AppDynamicDynaTrace等等它们在产品方面做非常完善能够适配各种场景。同样地开源也有非常优秀的解决方案。比如说 CNCF JaegerApache SkyWalkingCat Pinpoint等。Jaeger作为CNCF毕业的顶级项目 在云原生场景下通常会成为运维同学首选监控解决方案。
Jaeger项目是Uber 在 2015 年开发的。2017 年Jaeger 纳入云原生计算基金会CNCF的孵化项目2019 年Jaeger 正式毕业。下图是Jaeger架构图。图中包含两中架构模式两种架构上大体一样区别在于添加了Kafka作为缓冲以解决峰值流量过载的问题。Jaeger Jaeger组件包括 ClientAgentCollectorDBUI等组件另外Jaeger支持还多种后端存储其中包括内存BadgerCassandraElasticSearchgRPC插件。 今天我们就来说一说gRPC插件这个强大且容易被人遗忘的功能。简单点来说gRPC插件提供了一种能够将Trace数据从Jaeger系统中导出的能力。通过这个能力开发同学可以很轻松的将Trace对接到一个具备Trace存储和分析的后端服务这些服务可以对Trace进行二次分析加工比如说异常根因分析异常检测和告警等帮助运维和开发同学更好的发现和定位系统潜在的问题
jaeger插件开发流程
为了更好的了解jaeger插件开发需要先补充gRPC插件的底层实现原理Jaeger gRPC插件是使用HashiCorp/go-plugin框架实现的。接下我们将介绍Go Plugin以及插件的开发流程。
Go Plugin由HashiCorp公司开源它遵循设计模式中的开闭原则通过接口固定上层业务逻辑通过改变调用不同的RPC服务接口来改实现对业务的扩展。 目前Go Plugin包含两类插件RPC Plugin和 GRPCPlugin两类插件Client的底层调用不一样。一个通过net/rpc调用一个是grpc服务调用两个插件都提供了两个方法Server和Client方法。Service方法的完成的功能是充当服务端的stub服务端接受到请求后调用接口服务端接口的实现。Client方法充当了一个工厂方法为客户端生成接口的实现对象。 Go Plugin在启动过程中会启动一个子进程让子进程开启RPC/gRPC服务主进程直接通过RPC/gRPC接口达到插件的方式它支持多版本服务后面会讲到并存它本身并不提供服务的高可用相关的解决方案这块需要用户自己去提供。讲了这么多接下来简单的介绍Go Plugin的开发的过程
插件开发
下面介绍Go Plugin中的Example下的KV例子KV例子定义了两个方法Put和 Get方法KV例子包含多个协议版本本文以gRPC为例。
定义服务接口
type KV interface {// KV接口是KV插件定义的接口Put(key string, value []byte) errorGet(key string) ([]byte, error)
} 实现接口客户端 // KV接口客户端实现
type GRPCClient struct{ // 接口的客户端封装了gRPC服务client proto.KVClient
}func (m *GRPCClient) Put(key string, value []byte) error {// 调用gRPC服务接口_, err : m.client.Put(context.Background(), proto.PutRequest{...})return err
}func (m *GRPCClient) Get(key string) ([]byte, error) {// 本身调用KV的gRPC服务resp, err : m.client.Get(context.Background(), proto.GetRequest{...})....return resp.Value, nil
实现接口服务端
type GRPCServer struct {Impl KV
}// 实现KV gRPC服务
func (m *GRPCServer) Put(ctx context.Context,req *proto.PutRequest) (*proto.Empty, error) {// 接受到请求后便会调用接口的服务端实现return proto.Empty{}, m.Impl.Put(req.Key, req.Value)
}func (m *GRPCServer) Get(ctx context.Context, req *proto.GetRequest) (*proto.GetResponse, error) {// 接受到请求后便会调用接口的服务端实现v, err : m.Impl.Get(req.Key)return proto.GetResponse{Value: v}, err
}type KV struct{}func (KV) Put(key string, value []byte) error {// 具体业务实现
}func (KV) Get(key string) ([]byte, error) {// 具体业务实现
}实现go plugin插件接口
// 实现GrpcPlugin接口
type KVGRPCPlugin struct {plugin.Plugin Impl KV //KV接口的实现
}func (p KVGRPCPlugin) GRPCClient(ctx context.Context, broker plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) {// 注意返回为接口客户端实现return GRPCClient{client: proto.NewKVClient(c)}, nil
}func (p KVGRPCPlugin) GRPCServer(broker plugin.GRPCBroker, s *grpc.Server) error {// 注册gRpc服务proto.RegisterKVServer(s, GRPCServer{Impl: p.Impl})return nil
}插件使用
上面介绍了插件的开发这部分将介绍插件是如何使用的插件使用分为两个部分插件服务端和插件的客户端部分
插件服务端
上面部分提到go plugin启动时会启动在本地一个子进程这里的子进程指的就是插件的服务端插件服务端需要是一个包含main方法的可执行文件。下面介绍开始简单介绍插件服务端使用
编写一个main函数并将插件的客户端实现注册到go-plugin中如下:
plugin.Serve(plugin.ServeConfig{// shakeConfig包含查件版本和认证信息HandshakeConfig: shared.Handshake,Plugins: map[string]plugin.Plugin{// 插件名字kv_grpc: shared.KVGRPCPlugin{Impl: KV{}},},GRPCServer: plugin.DefaultGRPCServer,
})
使用go build 编译成可执行文件
插件客户端
插件客户端流程主要包括创建插件的Client启动插件服务端获取插件的接口实现调用服务接口
client : plugin.NewClient(plugin.ClientConfig{// shakeConfig包含查件版本和认证信息HandshakeConfig: shared.Handshake,//插件名字和插件的实例的映射关系Plugins: shared.PluginMap,// 这里填写插件可执行文件的路径Cmd: exec.Command(sh, -c, os.Getenv(KV_PLUGIN)),// 插件支持的协议。AllowedProtocols: []plugin.Protocol{plugin.ProtocolGRPC, plugin.ProtocolNetRPC},
})
// 获取插件的client端在这步go plugin通过Cmd穿过来的参数启动子进程同时做插件版本和认证信息的校验
rpcClient, err : client.Client()
// 获取接口客户端的对象
raw, err : rpcClient.Dispense(kv_grpc)
kv : raw.(shared.KV)
// 执行命令
result, err : kv.Get(os.Args[1])jaeger插件接口规范
通过上面的介绍我们已经可以了解到Jaeger已经帮我们实现了插件的客户端服务端和接口的客户端我们只需完成接口的服务端开发一个gRPC插件的开发完成了。Jaeger在gRPC插件预留了2个插件接口StorePlugin和ArchiveStorePlugin两者区别在于StorePlugin比ArchiveStorePlugin多了DependencyReader接口的定义DependencyReader接口用来查询服务间依赖关系。同时这两个插件接口都暴露了SpanReader和SpanWriter接口用于Trace/Span的读写操作。
SpanReader
// 读取所有的operation Name
func GetOperations(ctx context.Context, query spanstore.OperationQueryParameters) ([]spanstore.Operation, error)
// 读取所有的应用名称
func GetServices(ctx context.Context) ([]string, error)
// 通过符合条件的Trace
func FindTraces(ctx context.Context, query *spanstore.TraceQueryParameters) ([]*model.Trace, error)
// 通过符合条件的Trace ID
func FindTraceIDs(ctx context.Context, query *spanstore.TraceQueryParameters) ([]model.TraceID, error)
// 通过Trace ID获取具体Trace详情
func GetTrace(ctx context.Context, traceID model.TraceID) (*model.Trace, error)
SpanWriter
// 写入Trace
func WriteSpan(ctx context.Context, span *model.Span) error
DependencyReader
// 读取应用之间的依赖关系用于绘应用拓扑图和DAG图
func GetDependencies(ctx context.Context, endTs time.Time, lookback time.Duration) ([]model.DependencyLink, error)
开发SLS Jaeger插件
SLS现已推出分布式链路追踪Trace的统一存储和分析方案目前支持接入JaegerApache SkyWalkingOpenTelemetryZipkin等多种追踪数据接入。感兴趣的可以点击查看Demo。
SLS的Jaeger插件里的代码逻辑这里就不赘述。目前插件代码现在已经开源GitHub地址https://github.com/aliyun/aliyun-log-jaeger 欢迎大家加⭐️拍砖仓库也提供了一个一键Run的Demo示例欢迎使用使用方面的文档已经在Github上提供下面给大家演示一下效果以及开发Jaeger插件开发背后的意义。 插件背后的思考
整个插件至此开发完成同时我们也需要思考一下插件的背后给我们带来了什么。用户利用trace所带来的信息价值Trace数据采集上来仅仅只是系统监控的开始挖掘Trace隐藏的信息是构建监控系统最重要的能力。同样的再利用Trace所带来的的信息价值同时如何持续地保障这种能力也是我们思考的重心
“海恩法则”指出每一起严重事故的背后必然有29次轻微事故和300起未遂先兆以及1000起事故隐患。 “海恩法则”告诉我们这样一个道理每一起安全事故的背后看似偶然其实都是各种因素积累到一定程度的必然结果 业务系统每天都再生产大量的Trace数据这些Trace数据用人的肉眼是无法了解系统运行的状态的信息更别去发现系统一些隐藏起来的问题。这时就需要系统提供大数据场景下的分析的能力。SLS做日志起家每天处理数PB级别的日志量另外也提供一堆的日志分析的算子加工处理的工具为用户分析系统背后的故事。Trace我们可以理解为是一种特定的日志只是这个日志带了关联的上下文TraceIDparentSpanIDSpanID相信SLS在处理Trace日志的也会游刃有余
作为Jaeger作为一个可观察性/监控系统的组成部分是定位和发现业务系统问题的重要数据来源我们需要保证监控系统比业务系统活的更久。一旦监控系统先于业务系统down掉此时的监控可以说是完全没有意义。而Jaeger作为一个开源项目它本身只提供解决方案并不会提供部署规模的评估方案和服务如何保证高可用的方案这种情况下怎么去提供高可用和高性能的后端服务谁去为监控系统提供最后一层保障? SLS作为一个云服务其最大的一个特点就是高性能、弹性和免运维让用户轻松应对激增流量或者规模评估不准确的问题SLS服务本身提供99.9%的可用性以及11个9的数据可靠性。
总结
构建完备的监控体系体系不仅要保证监控系统的可用性还需要强大的分析能力。分析能力帮助运维同学快速的定位和发现故障提高系统的可用性。而Jaeger插件为我们提供接入多种分析系统的扩展能力这样的扩展能力能够让专业的分析团队提供专业的分析能力让运维和开发团队的更加专注业务运维。
原文链接 本文为阿里云原创内容未经允许不得转载。