gRPC服务兼容问题:Evans无法识别RPC服务及方法
问题:gRPC服务无法被Evans识别,需补充代码实现向前兼容
相关文件内容
service_myservice.proto
service MyService { rpc GetData(GetRequest) returns (GetResponse) {} }
server.go
type Server struct { pb.UnimplementedMyServiceServer config util.Config } // NewServer creates a new gRPC server. func NewServer(config util.Config) (*Server, error) { server := &Server{ config: config, } return server, nil }
main包中的启动函数
func runGrpcServer(config util.Config) { server, err := gapi.NewServer(config) if err != nil { log.Fatal().Err(err).Msg("cannot create server") } grpcLogger := grpc.UnaryInterceptor(gapi.GrpcLogger) grpcServer := grpc.NewServer(grpcLogger) pb.RegisterMyServiceServer(grpcServer, server) reflection.Register(grpcServer) listener, err := net.Listen("tcp", config.GRPCServerAddress) if err != nil { log.Fatal().Err(err).Msg("cannot create listener") } log.Info().Msgf("start gRPC server at %s", listener.Addr().String()) err = grpcServer.Serve(listener) if err != nil { log.Fatal().Err(err).Msg("cannot start gRPC server") } }
测试报错信息
localhost:9090> show service +---------+-----+--------------+---------------+ | SERVICE | RPC | REQUEST TYPE | RESPONSE TYPE | +---------+-----+--------------+---------------+ +---------+-----+--------------+---------------+ localhost:9090> call GetData command call: failed to get the RPC descriptor for: GetData: service unselected
解决方法
嵌入pb.UnimplementedMyServiceServer确实是实现gRPC向前兼容的标准方式,但你需要确保以下几点来让服务被Evans识别:
1. 确保proto代码生成正确
必须使用gRPC Go插件重新生成代码,执行以下命令(替换路径为你的实际路径):
protoc --go_out=. --go-grpc_out=. service_myservice.proto
这会生成包含服务描述符、UnimplementedMyServiceServer和注册函数的service_myservice_grpc.pb.go文件,这是服务被反射识别的基础。
2. 补充RPC方法的显式实现(可选但有效)
虽然UnimplementedMyServiceServer已经提供了所有RPC方法的默认实现(返回Unimplemented错误),但显式实现GetData方法可以确保反射服务正确识别到该RPC:
在server.go中添加:
import ( "context" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func (s *Server) GetData(ctx context.Context, req *pb.GetRequest) (*pb.GetResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetData not implemented") }
3. 确认反射服务正常工作
你的启动代码中已经调用了reflection.Register(grpcServer),这部分是正确的,但需要确保生成的proto代码中包含完整的服务描述符,这样反射才能正确暴露服务信息给Evans。
完成以上步骤后,重启gRPC服务器,再用Evans测试即可识别到MyService服务。
内容的提问来源于stack exchange,提问作者golobitch
相关产品推荐
相关产品推荐

