使用基于monkey指针的调试功能
简介
本示例展示了 ioc-golang 框架提供的基于monkey指针的调试功能。
注入到接口的对象已经默认支持调试层。本例子针对注入到接口体指针的对象,可通过这种方式赋予其代理层运维能力。
基于monkey指针的调试功能对于程序性能有损耗,请您不要在追求性能的场景下开启调试能力。
本框架基于 AOP 的思路,为每个注册在框架的结构方法都封装了一组拦截器。基于这些拦截器,可以实现具有扩展性的调试功能。
调试能力包括:
- 基于 ioc-debug 协议,暴露调试端口
- 查看所有接口、实现、方法列表
- 监听、修改任意方法的入参和返回值
- 性能瓶颈分析【开发中】
- 可观测性【开发中】
示例介绍
本示例实现了以下拓扑
在这个例子中,App 结构会依此调用所有依赖对象,进而调用一个单例模型注入的 gRPC 客户端,该客户端发起网络请求,并获得结果。
我们将开启 debug 模式,通过 iocli 工具查看接口、实现、方法,并监听通过 gRPC Client 发送的所有请求和返回值。
运行示例
启动 grpc Server
% cd example/denbug/grpc_server % go run .
新开一个终端,启动客户端。
注意 GOARCH 环境变量和 ‘-gcflags="-N -l" -tags iocdebug’ 编译参数, amd机器无需指定 GOARCH 环境变量。
正确在 ioc_golang.yaml 中开启debug模式后,会打印
[Debug] Debug port is set to default :1999
的日志。% cd example/debug/cmd % GOARCH=amd64 go run -gcflags="-N -l" -tags iocdebug . ___ ___ ____ ____ _ |_ _| / _ \ / ___| / ___| ___ | | __ _ _ __ __ _ | | | | | | | | _____ | | _ / _ \ | | / _` | | '_ \ / _` | | | | |_| | | |___ |_____| | |_| | | (_) | | | | (_| | | | | | | (_| | |___| \___/ \____| \____| \___/ |_| \__,_| |_| |_| \__, | |___/ Welcome to use ioc-golang! [Boot] Start to load ioc-golang config [Config] Load default config file from ../conf/ioc_golang.yaml [Config] merge config map, depth: [0] [Boot] Start to load debug [Debug] Debug port is set to default :1999 [Boot] Start to load autowire [Autowire Type] Found registered autowire type singleton [Autowire Struct Descriptor] Found type singleton registered SD github.com/alibaba/ioc-golang/example/debug/cmd/service2.Impl2 [Autowire Struct Descriptor] Found type singleton registered SD github.com/alibaba/ioc-golang/example/debug/cmd/struct1.Struct1 [Autowire Struct Descriptor] Found type singleton registered SD main.App [Autowire Struct Descriptor] Found type singleton registered SD github.com/alibaba/ioc-golang/example/debug/cmd/service1.Impl1 [Autowire Struct Descriptor] Found type singleton registered SD github.com/alibaba/ioc-golang/example/debug/cmd/service2.Impl1 [Autowire Type] Found registered autowire type grpc [Autowire Struct Descriptor] Found type grpc registered SD github.com/alibaba/ioc-golang/example/debug/api.HelloServiceClient [Debug] Debug server listening at :1999 create conn target localhost:8080 App call grpc get: Hello laurence ExampleService1Impl1 call grpc get :Hello laurence_service1_impl1 ExampleService2Impl1 call grpc get :Hello laurence_service2_impl1 ExampleService2Impl2 call grpc get :Hello laurence_service2_impl2 ExampleStruct1 call grpc get :Hello laurence_service1_impl1
每隔 5s,所有的对象都会发起一次 gRPC 请求。
新开一个终端,查看所有接口、实现和方法。
% iocli list github.com/alibaba/ioc-golang/example/debug/api.HelloServiceClient [SayHello] github.com/alibaba/ioc-golang/example/debug/cmd/service1.Impl1 [Hello] github.com/alibaba/ioc-golang/example/debug/cmd/service2.Impl1 [Hello] github.com/alibaba/ioc-golang/example/debug/cmd/service2.Impl2 [Hello] github.com/alibaba/ioc-golang/example/debug/cmd/struct1.Struct1 [Hello] main.App [Run]
监听 gRPC Client 的所有流量,每隔 5s 会打印出相关的请求、返回值信息。
% iocli watch github.com/alibaba/ioc-golang/example/debug/api.HelloServiceClient SayHello ========== On Call ========== github.com/alibaba/ioc-golang/example/debug/api.HelloServiceClient.SayHello() Param 1: (*context.emptyCtx)(0xc0000280e0)(context.Background) Param 2: (*api.HelloRequest)(0xc000260280)(name:"laurence") Param 3: ([]grpc.CallOption) (len=2 cap=2) { (grpc.MaxRecvMsgSizeCallOption) { MaxRecvMsgSize: (int) 1024 }, (grpc.MaxRecvMsgSizeCallOption) { MaxRecvMsgSize: (int) 1024 } } ========== On Response ========== github.com/alibaba/ioc-golang/example/debug/api.HelloServiceClient.SayHello() Response 1: (*api.HelloResponse)(0xc000260380)(reply:"Hello laurence") Response 2: (interface {}) <nil> ========== On Call ========== github.com/alibaba/ioc-golang/example/debug/api.HelloServiceClient.SayHello() Param 1: (*context.emptyCtx)(0xc0000280e0)(context.Background) Param 2: (*api.HelloRequest)(0xc0003988c0)(name:"laurence_service1_impl1") Param 3: ([]grpc.CallOption) <nil> ========== On Response ========== github.com/alibaba/ioc-golang/example/debug/api.HelloServiceClient.SayHello() Response 1: (*api.HelloResponse)(0xc000398980)(reply:"Hello laurence_service1_impl1") Response 2: (interface {}) <nil> ========== On Call ========== github.com/alibaba/ioc-golang/example/debug/api.HelloServiceClient.SayHello() Param 1: (*context.emptyCtx)(0xc0000280e0)(context.Background) Param 2: (*api.HelloRequest)(0xc000260480)(name:"laurence_service2_impl1") Param 3: ([]grpc.CallOption) <nil> ========== On Response ========== github.com/alibaba/ioc-golang/example/debug/api.HelloServiceClient.SayHello() Response 1: (*api.HelloResponse)(0xc000260540)(reply:"Hello laurence_service2_impl1") Response 2: (interface {}) <nil> ========== On Call ========== github.com/alibaba/ioc-golang/example/debug/api.HelloServiceClient.SayHello() Param 1: (*context.emptyCtx)(0xc0000280e0)(context.Background) Param 2: (*api.HelloRequest)(0xc00041c200)(name:"laurence_service2_impl2") Param 3: ([]grpc.CallOption) <nil> ========== On Response ========== github.com/alibaba/ioc-golang/example/debug/api.HelloServiceClient.SayHello() Response 1: (*api.HelloResponse)(0xc00041c2c0)(reply:"Hello laurence_service2_impl2") Response 2: (interface {}) <nil> ========== On Call ========== github.com/alibaba/ioc-golang/example/debug/api.HelloServiceClient.SayHello() Param 1: (*context.emptyCtx)(0xc0000280e0)(context.Background) Param 2: (*api.HelloRequest)(0xc000260700)(name:"laurence_service1_impl1") Param 3: ([]grpc.CallOption) <nil> ========== On Response ========== github.com/alibaba/ioc-golang/example/debug/api.HelloServiceClient.SayHello() Response 1: (*api.HelloResponse)(0xc0002607c0)(reply:"Hello laurence_service1_impl1") Response 2: (interface {}) <nil> ...
小结
通过 Debug 能力,开发人员可以在测试环境内动态地监控流量,帮助排查问题。
也可以基于 ioc-golang 提供的拦截器层,注册任何自己期望的调试拦截器,扩展调试、可观测、运维能力。
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.