当前位置: 首页 > news >正文

protoc-gen-nats-micro 试用

protoc-gen-nats-micro 试用

protoc-gen-nats-micro 使用了buf,同时基于golang 开发,所以使用需要安装一个依赖(buf 是核心)

安装工具

go install github.com/toyz/protoc-gen-nats-micro/tools/protoc-gen-nats-micro@latest

配置buf

proto 部分我使用了官方示例

  • buf.yaml 主要是添加可选依赖
version: v2
modules:- path: proto
lint:use:- STANDARD
deps:- buf.build/toyz/natsmicro- buf.build/googleapis/googleapis
  • buf gen
version: v2
managed:enabled: false
plugins:- local: protoc-gen-goout: genopt:- module=github.com/rongfengliang/nats-rpc/gen- local: protoc-gen-nats-microout: genopt: [module=github.com/rongfengliang/nats-rpc/gen, language=go]

生成的效果

  • endpoint
func (s *orderServiceService) Endpoints() []OrderServiceEndpointInfo {return []OrderServiceEndpointInfo{{Name: "CreateOrder", Subject: s.subjectPrefix + ".create_order"},{Name: "GetOrder", Subject: s.subjectPrefix + ".get_order"},{Name: "ListOrders", Subject: s.subjectPrefix + ".list_orders"},{Name: "UpdateOrderStatus", Subject: s.subjectPrefix + ".update_order_status"},}
}
  • handler 注册
// Register all endpoints with their metadata
for name, handler := range endpoints {opts := []micro.EndpointOpt{}if metadata, exists := endpointMetadata[name]; exists && len(metadata) > 0 {opts = append(opts, micro.WithEndpointMetadata(metadata))}if err := adder.AddEndpoint(name, handler, opts...); err != nil {return nil, fmt.Errorf("failed to add endpoint %s: %w", name, err)}
}
  • 消息处理

就是结合配置进行序列化处理,比如json 以及protobuf

func (h *orderServiceHandlers) CreateOrder(req micro.Request) {// Determine effective timeout: endpoint-specific timeout overrides service timeout// If endpoint timeout is set (> 0), use it; otherwise use service timeouttimeout := h.serviceTimeout// Create context with timeout if configured, otherwise use background contextctx := context.Background()var cancel context.CancelFuncif timeout > 0 {ctx, cancel = context.WithTimeout(ctx, timeout)defer cancel()}// Add incoming NATS headers to context so service methods can access themif req.Headers() != nil {ctx = WithIncomingHeaders(ctx, req.Headers())}// Initialize outgoing headers pointer in context so interceptors can set response headersoutgoingHeadersPtr := &nats.Header{}ctx = context.WithValue(ctx, outgoingHeadersKey, outgoingHeadersPtr)var msg CreateOrderRequestif h.useJSON {if err := protojson.Unmarshal(req.Data(), &msg); err != nil {req.Error(OrderServiceErrCodeInvalidArgument, fmt.Sprintf("failed to decode JSON request: %v", err), nil)return}} else {if err := proto.Unmarshal(req.Data(), &msg); err != nil {req.Error(OrderServiceErrCodeInvalidArgument, fmt.Sprintf("failed to decode request: %v", err), nil)return}}
....

通过以上可以看到注册生成部分实际上就是nats micro 框架的,消息处理是自己进行了内部处理

说明

机制上protoc-gen-nats-micro 的一些玩法,实际上算是标准的玩法,实现起来并不难,结合代码生成是一种不错的选择

参考资料

https://toyz.github.io/protoc-gen-nats-micro/

https://github.com/Toyz/protoc-gen-nats-micro

https://buf.build/docs/cli/installation/