在我的负载均衡器之一的服务中,在我部署的服务之一中调用服务器方法时出现以下错误:
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
}
Run Code Online (Sandbox Code Playgroud)
该错误表明没有名为 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)
}
}
Run Code Online (Sandbox Code Playgroud)
我试图从客户端访问的功能:
func (s *RedisGatewayServer) GetData(ctx context.Context, in *rs.KeyRequest)(*rs.KeyRequest, error) {
return in, nil
}
Run Code Online (Sandbox Code Playgroud)
我的 docker 和 yaml 文件都是正确的,并且具有正确的命名和端口。
Cam*_*rán 10
I had this exact problem, and it was because of a very simple mistake: I had put the call to the service registration after the server start. The code looked like this:
err = s.Serve(listener)
if err != nil {
log.Fatalf("[x] serve: %v", err)
}
primepb.RegisterPrimeServiceServer(s, &server{})
Run Code Online (Sandbox Code Playgroud)
Obviously, the registration should have been called before the server was ran:
primepb.RegisterPrimeServiceServer(s, &server{})
err = s.Serve(listener)
if err != nil {
log.Fatalf("[x] serve: %v", err)
}
Run Code Online (Sandbox Code Playgroud)
有很多场景都可能发生这种情况。根本问题似乎是相同的 - GRPC 服务器可以访问,但无法服务客户端请求。
我遇到的两个场景没有记录在以前的答案中:
合同中引入的重大变更可能会导致此错误。
就我而言,服务器正在运行旧版本的合约,而客户端正在运行最新版本的合约。
重大更改意味着服务器无法解析我的客户端请求的服务,从而返回未实现的错误。
客户端到达了不执行合同的错误服务器。
如果您正在运行多个不同的 GRPC 服务,请考虑这种情况。您可能会错误地拨错号码。
感谢@dolan 的评论,它解决了问题。
基本上我们必须确保服务器和客户端中的方法值应该相同(您甚至可以从服务器端生成的 pb.go 文件中复制方法名称)
func (cc *ClientConn) Invoke(ctx context.Context, 方法字符串, args, 回复接口{}, opts ...CallOption) error {
此调用函数将存在于您在 gRPC 服务中实现的所有方法中。