微服务gRPC学习笔记(六)| 青训营笔记

92 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 13 天

生成客户端和服务器端代码

接下来我们需要从 .proto 的服务定义中生成 gRPC 客户端和服务器端的接口。我们通过 protocol buffer 的编译器 protoc 以及一个特殊的 gRPC Java 插件来完成。为了生成 gRPC 服务,你必须 使用proto3编译器(同时支持 proto2 和 proto3 语法)。

这个例子使用的构建系统也是 Java gRPC 本身构建的一部分——为了简单起见,我们推荐使用为这个例子 提前生成的代码。你可以参考README学习如何从你的 .proto 文件中生成代码。

从这里src/generated/main可以看到为了例子预生成的代码。

下面的类都是从我们的服务定义中生成:

  • 包含了所有填充,序列化以及获取请求和应答的消息类型的Feature.javaPoint.java, Rectangle.java以及其它类文件。

  • RouteGuideGrpc.java 文件包含(以及其它一些有用的代码):

    • RouteGuide 服务器要实现的一个接口 RouteGuideGrpc.RouteGuide,其中所有的方法都定 义在RouteGuide服务中。
    • 客户端可以用来和RouteGuide服务器交互的 存根 类。 异步的存根也实现了 RouteGuide 接口。

创建服务器

首先来看看我们如何创建一个 RouteGuide 服务器。如果你只对创建 gRPC 客户端感兴趣,你可以跳 过这个部分,直接到创建客户端 (当然你也可能发现它也很有意思)。

RouteGuide 服务工作有两个部分:

  • 实现我们服务定义的生成的服务接口:做我们的服务的实际的“工作”。
  • 运行一个 gRPC 服务器,监听来自客户端的请求并返回服务的响应。

你可以从[grpc-java/examples/src/main/java/io/grpc/examples/RouteGuideServer.java] (github.com/grpc/grpc-j…%E7%9C%8B%E5%88%B0%E6%88%91%E4%BB%AC%E7%9A%84) RouteGuide 服务器的实现代码。现在让我们近距离研究它是如何工作的。

实现RouteGuide

如你所见,我们的服务器有一个实现了生成的 RouteGuideGrpc.Service 接口的 RouteGuideService类:

private static class RouteGuideService implements RouteGuideGrpc.RouteGuide {
...
}

简单 RPC

routeGuideServer 实现了我们所有的服务方法。首先让我们看看最简单的类型 GetFeature,它 从客户端拿到一个 Point 对象,然后从返回包含从数据库拿到的feature信息的 Feature

    @Override
    public void getFeature(Point request, StreamObserver<Feature> responseObserver) {
      responseObserver.onNext(checkFeature(request));
      responseObserver.onCompleted();
    }

...

    private Feature checkFeature(Point location) {
      for (Feature feature : features) {
        if (feature.getLocation().getLatitude() == location.getLatitude()
            && feature.getLocation().getLongitude() == location.getLongitude()) {
          return feature;
        }
      }

      // No feature was found, return an unnamed feature.
      return Feature.newBuilder().setName("").setLocation(location).build();
    }

getFeature() 接收两个参数:

  • Point: 请求
  • StreamObserver<Feature>: 一个应答的观察者,实际上是服务器调用它应答的一个特殊接口。

要将应答返回给客户端,并完成调用:

  1. 如在我们的服务定义中指定的那样,我们组织并填充一个 Feature 应答对象返回给客户端。在这个 例子中,我们通过一个单独的私有方法checkFeature()来实现。
  2. 我们使用应答观察者的 onNext() 方法返回 Feature
  3. 我们使用应答观察者的 onCompleted() 方法来指出我们已经完成了和 RPC的交互。