Google gRPC 入门案例实战

本文介绍了gRPC的基础知识,包括它如何结合Protobuf和Netty提供高性能RPC服务,并详细阐述了gRPC环境的搭建步骤。接着,通过一个HelloWorld的示例,展示了服务端和客户端的Java代码实现,包括protobuf文件的定义、服务端的启动以及客户端的调用过程。最后,给出了运行示例后的测试结果。
摘要由CSDN通过智能技术生成

一 点睛

Protobuf 可以对消息进行编码和解码,但必须借助 Netty 等通信技术才能进行传输消息。Google 公司将 Protobuf 和 Netty 进行了结合,并在此基础上开发了一歀新的高性能的 RPC 框架——gRPC。

gRPC 是基于 HTTP/2 协议标准的,不过 HTTP/2 完全兼容 HTTP/1 的语义,因此在开发时,不用担心两种协议之间的差异。

二 gRPC 环境搭建步骤

1 访问 GitHub - grpc/grpc-java: The Java gRPC implementation. HTTP/2 based RPCicon-default.png?t=M4ADhttps://github.com/grpc/grpc-java下载 grpc,这里使用 v1.15.0

2 通过 Git 命令,对其进行下载

git clone -b v1.15.0 https://github.com/grpc/grpc-java

三 入门案例

以官方的 examples 中的 HelloWorld 示例进行说明。

1 protobuf 文件

syntax = "proto3";

option java_multiple_files = true;

option java_package = "io.grpc.examples.helloworld";

option java_outer_classname = "HelloWorldProto";

option objc_class_prefix = "HLW";

package helloworld;

// 接口定义

service Greeter {

  // 接口方法

  rpc SayHello (HelloRequest) returns (HelloReply) {}

}

// 请求消息

message HelloRequest {

  string name = 1;

}

// 响应消息

message HelloReply {

  string message = 1;

}

2 服务端代码

package io.grpc.examples.helloworld;

import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;
import java.io.IOException;
import java.util.logging.Logger;

/**
* Hello world 的服务端
*/
public class HelloWorldServer {
  private static final Logger logger = Logger.getLogger(HelloWorldServer.class.getName());

  private Server server;

  // 启动服务端
  private void start() throws IOException {
    /* 监听端口 */
    int port = 50051;
    server = ServerBuilder.forPort(port)
        .addService(new GreeterImpl()) // 服务端对应的实现类
        .build()
        .start();
    logger.info("Server started, listening on " + port);
    Runtime.getRuntime().addShutdownHook(new Thread() {
      @Override
      public void run() {
        // 虚拟机退出时,将这些下面这段代码
        System.err.println("*** shutting down gRPC server since JVM is shutting down");
        HelloWorldServer.this.stop();
        System.err.println("*** server shut down");
      }
    });
  }

  // 关闭服务器
  private void stop() {
    if (server != null) {
      server.shutdown();
    }
  }

  private void blockUntilShutdown() throws InterruptedException {
    if (server != null) {
      server.awaitTermination();
    }
  }

  // 启动服务端
  public static void main(String[] args) throws IOException, InterruptedException {
    final HelloWorldServer server = new HelloWorldServer();
    server.start();
    server.blockUntilShutdown();
  }

  // 服务实现类
  static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
    @Override
    public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
      HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
      responseObserver.onNext(reply);
      responseObserver.onCompleted();
    }
  }
}

3 客户端代码

package io.grpc.examples.helloworld;

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
* Hello world 的客户端
*/
public class HelloWorldClient {
  private static final Logger logger = Logger.getLogger(HelloWorldClient.class.getName());

  private final ManagedChannel channel;
  private final GreeterGrpc.GreeterBlockingStub blockingStub;

  /** 连接服务端的构造器 */
  public HelloWorldClient(String host, int port) {
    this(ManagedChannelBuilder.forAddress(host, port)
        .usePlaintext()
        .build());
  }


  /** 初始化通道 */
  HelloWorldClient(ManagedChannel channel) {
    this.channel = channel;
    blockingStub = GreeterGrpc.newBlockingStub(channel);
  }

  // 关闭通道
  public void shutdown() throws InterruptedException {
    channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
  }

  /** 客户端请求 */
  public void greet(String name) {
    logger.info("Will try to greet " + name + " ...");
    HelloRequest request = HelloRequest.newBuilder().setName(name).build();
    HelloReply response;
    try {
      response = blockingStub.sayHello(request);
    } catch (StatusRuntimeException e) {
      logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
      return;
    }
    logger.info("Greeting: " + response.getMessage());
  }


  public static void main(String[] args) throws Exception {
    HelloWorldClient client = new HelloWorldClient("localhost", 50051);
    try {
      String user = "world";
      if (args.length > 0) {
        user = args[0]; 
      }
      client.greet(user);
    } finally {
      client.shutdown();
    }
  }
}

四 测试

1 启动服务端

2 启动客户端

3 服务端打印

信息: Server started, listening on 50051

4 客户端打印

六月 04, 2022 7:49:19 上午 io.grpc.examples.helloworld.HelloWorldClient greet

信息: Will try to greet world ...

六月 04, 2022 7:49:20 上午 io.grpc.examples.helloworld.HelloWorldClient greet

信息: Greeting: Hello world

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值