获取未实现的 desc = 未知服务错误 gRPC

问题描述 投票:0回答:7

在我的负载均衡器之一的服务中,在我部署的服务之一中调用服务器方法时,出现以下错误:

rpc 错误:代码 = 未实现的 desc = 未知服务 fooService.FooService

我还使用 gRPC 设置了一些其他服务,它们运行良好。似乎就是这个,我想知道这是不是因为它是负载均衡器?

func GetResult(w http.ResponseWriter, r *http.Request) {

    conn, errOne := grpc.Dial("redis-gateway:10006", grpc.WithInsecure())       
    defer conn.Close()

    rClient := rs.NewRedisGatewayClient(conn)
    result , errTwo := rClient.GetData(context.Background(), &rs.KeyRequest{Key: "trump", Value: "trumpVal"}, grpc.WithInsecure())

    fmt.Fprintf(w, "print result: %s \n", result)   //prints nil
    fmt.Fprintf(w, "print error one: %v \n", errOne) // prints nil
    fmt.Fprintf(w, "print error two: %s \n", errTwo) // prints error

}

该错误表明没有名为 fooService.FooService 的服务,这是正确的,因为我调用的服务的 dns 名称称为 foo-service。然而,我的其他使用 gRPC 的服务的设置完全相同并且工作正常。而且我的原型文件配置正确,所以这不是问题。

我呼叫的服务器:

 func main() {

    lis, err := net.Listen("tcp", ":10006")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }

    grpcServer := grpc.NewServer()
    newServer := &RedisGatewayServer{}
    rs.RegisterRedisGatewayServer(grpcServer, newServer)

    if err := grpcServer.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }

}

我尝试从客户端访问的功能:

func (s *RedisGatewayServer) GetData(ctx context.Context, in *rs.KeyRequest)(*rs.KeyRequest, error) {

     return in, nil
}

我的 docker 和 yaml 文件都正确,命名和端口也正确。

go grpc
7个回答
10
投票

我遇到了这个确切的问题,这是因为一个非常简单的错误:我在服务器启动之后调用了服务注册。代码如下所示:

err = s.Serve(listener) if err != nil { log.Fatalf("[x] serve: %v", err) } primepb.RegisterPrimeServiceServer(s, &server{})
显然,注册应该在服务器运行之前调用:

primepb.RegisterPrimeServiceServer(s, &server{}) err = s.Serve(listener) if err != nil { log.Fatalf("[x] serve: %v", err) }
    

6
投票
有很多场景都可能发生这种情况。根本问题似乎是相同的 - GRPC 服务器可以访问,但无法服务客户端请求。

我遇到的两个在之前的答案中没有记录的场景是:

1.客户端和服务器

运行相同的合约版本

合同中引入的重大变更可能会导致此错误。

在我的例子中,服务器正在运行旧版本的合约,而客户端正在运行最新版本的合约。

重大更改意味着服务器无法解析我的客户请求的服务,从而返回未实现的错误。

2.客户端连接到错误的 GRPC 服务器

客户端到达了不执行合约的错误服务器。

如果您正在运行多个不同的 GRPC 服务,请考虑此场景。您可能会误拨错电话。


1
投票
感谢@dolan的评论,它解决了问题。

基本上我们必须确保服务器和客户端中的方法值应该相同(您甚至可以从服务器端生成的 pb.go 文件中复制方法名称)

func (cc *ClientConn) Invoke(ctx context.Context, 方法字符串, args, 回复接口{}, opts ...CallOption) 错误 {

此调用函数将存在于您在 gRPC 服务中实现的所有方法中。


1
投票
对我来说,我的客户端连接到了错误的服务器端口。

我的服务器监听

localhost:50052

我的客户端连接到

localhost:50051

因此我看到了这个错误。


0
投票
我遇到了同样的问题 - 我能够从

Postman 到服务执行 rpc 调用,而 apigateway 能够连接到 service 但在方法调用时它给出了错误 代码 12 未知服务the原因是在我的原型文件中,客户端位于包 X 下,而服务器位于包 Y 下。 很傻,但是是的

在apigateway和服务下为proto制作包解决了我的问题


0
投票

尝试将客户端和服务器都移至 50052。


0
投票

    打包你的PackageName
  1. 服务你的ServiceName(我忘记了这一步😵)
  2. 调用你的RPCName
© www.soinside.com 2019 - 2024. All rights reserved.