【问题标题】:grpc with mustEmbedUnimplemented*** method带有 mustEmbedUnimplemented*** 方法的 grpc
【发布时间】:2020-11-30 18:18:48
【问题描述】:

最近,grpc-go 引入了 mustEmbedUnimplemented*** 方法。 它用于向前兼容。

简单来说,我无法理解它是如何提供帮助的,如果没有它,我们会在多早之前遇到什么问题? 现在在我的结构中,我使用添加以下语句,但是,我不知道为什么......

type server struct {
     pdfpb.UnimplementedGreetServiceServer
}

在 Github 问题 - https://github.com/grpc/grpc-go/issues/3669 他们对此进行了辩论,有人可以简单地解释一下它是如何提供帮助的吗?如果没有它,我们会在多早之前遇到什么问题?

【问题讨论】:

    标签: go protocol-buffers grpc-go


    【解决方案1】:

    这是非常基本的。

    UnimplementedGreetServiceServer 是一个包含所有已实现方法的结构。

    当我添加 pdfpb.UnimplementedGreetServiceServer 时,我可以调用 UnimplementedGreetServiceServer 定义的方法。

    就是这样,如果我在 proto 文件中添加更多的 RPC 服务,那么我不需要添加所有导致向前兼容的 RPC 方法。

    演示代码位于:https://github.com/parthw/fun-coding/tree/main/golang/understanding-grpc-change

    【讨论】:

    • 那么这实际上有什么帮助?我绝对认为这不是一项功能,可能会导致 API 中断。为什么我要允许将 proto 文件生成到 go 文件中而不是实现它们?
    • @swade 我同意你的看法。我不希望 RPC 以 Unimplemented 失败,以防有人忘记实现处理程序。但是,此更改有一个好处,那就是现在您必须有意识地选择是否具有前向兼容性。另一方面,当您升级 proto 架构而不是 grpc 实现时,您可能不希望构建失败。所以他们让你选择。无论如何,您仍然可以选择退出 fwd compat。详情见我的回答
    【解决方案2】:

    此错误来自较新版本的protoc-gen-grpc-go 编译器。服务器实现现在必须是向前兼容的。

    在此更改之前,每当您注册服务器实现时,您都会执行以下操作:

            pb.RegisterFooBarServiceServer(
                server,
                &FooBarServer{}, // or whatever you use to construct the server impl
            )
    

    如果您的服务器缺少一些方法实现,这将导致编译时错误。

    使用较新的 proto 编译器版本,前向兼容性变为选择退出,这意味着两件事:

    1. 您现在必须嵌入UnimplementedFooBarServiceServer,如错误消息所示。正如我所说,当您没有显式实现新方法时,这不会产生编译器错误(这就是前向兼容性的含义)。尽管如果您尝试调用您没有(或忘记)显式实现的 RPC,则会导致 codes.Unimplemented 出现运行时错误。

    2. 您仍然可以通过嵌入 UnsafeFooBarServiceServer(带有 Unsafe 前缀)来选择退出前向兼容性。该接口仅声明了mustEmbedUnimplementedFooBarServiceServer() 方法,该方法使问题中的错误消失,而在您没有显式实现新处理程序的情况下不会放弃编译器错误。

    例如:

    // Implements the grpc FooBarServiceServer
    type FooBarService struct {
        grpc.UnsafeFooBarServiceServer // consciously opt-out of forward compatibility
        // other fields
    }
    

    您还可以通过在protoc-gen-grpc-go 插件 (source) 上设置一个选项来生成没有前向兼容性的代码:

    protoc --go-grpc_opt=require_unimplemented_servers=false
    

    【讨论】:

      【解决方案3】:

      对于在Github Issue 上建议的mustEmbededUnimplementedServiceServer 仍有问题的任何人。最好的解决方案就是更新您的 ServerStruct。

      例如

      type AuthenticationServiceServer struct {
      }
      

      到。

      type AuthenticationServiceServer struct {
          service.UnimplementedAuthenticationServiceServer
      }
      

      这将解决 Go 在执行此操作时抛出的异常。

      grpcService.RegisterAuthenticationServiceServer(grpcServer, controller.AuthenticationServiceServer{})
      

      【讨论】:

        猜你喜欢
        • 2019-03-10
        • 2021-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-16
        相关资源
        最近更新 更多