首先在研究gRPC之前要先了解下RPC:

RPC(Remote Procedure Calling),远程过程调用的缩写。总的来说是一个Client/Server的结构,提供服务的一方称为Server,消费服务的一方称为Client(还有注册中心、监控中心、配置中心等其他模块,不太清楚应不应该归在RPC里,这里暂时就不讨论了)。

3.PNG

gRPC则是Google公布的开源软件,基于最新的HTTP2.0协议,并支持常见的众多编程语言(跨平台)。我们知道HTTP2.0是基于二进制的HTTP协议升级版本,目前各大浏览器都在快马加鞭的加以支持。这个RPC框架是基于HTTP协议实现的。(但是RPC 本身是一种框架,而http 是应用层的协议)(阿里的dubbo、facebook的Thrift也都是基于RPC的超流行框架)。

gRPC的优势:

1、gRPC可以通过protobuf来定义接口,从而可以有更加严格的接口约束条件。(安全性高)

2、通过protobuf可以将数据序列化为二进制编码,这会大幅减少需要传输的数据量,从而大幅提高性能。

3、http2.0更快吧。。(性能更强)

引一下protobuf:

Protobuf实际是一套类似Json或者XML的数据传输格式和规范,用于不同应用或进程之间进行通信时使用。通信时所传递的信息是通过Protobuf定义的message数据结构进行打包,然后编译成二进制的码流再进行传输或者存储。

总的来看,1、gRPC接口严格性是要比restful要强的。这点更像webservice(wsdl),不过webservice已经过时了,过时了。。。前朝余孽不做探究了。2、protobuf这东西吧,我以前没接触过,你说他比xml比json解析快我也不知道,愚昧的我一直以为现在是json一统江湖。。3、http2.0是趋势这个肯定没问题。4、接口安全性很高。。。

总结下用rpc框架的好处:

restful是在接口不多、系统与系统交互较少的情况下,解决信息孤岛初期常使用的一种通信手段;优点就是简单、直接、开发方便。利用现成的http协议 进行传输。但是如果是一个大型的网站,内部子系统较多、接口非常多的情况下,RPC框架的好处就显示出来了,RPC框架一般都有注册中心,有丰富的监控管理;发布、下线接口、动态扩展等,对调用方来说是无感知、统一化的操作。安全性也比较强。最后就是最近流行的服务化架构、服务化治理,RPC框架是一个强力的支撑。

所以,可以把gRPC理解为企业级架构解决方案的一部分。(因为我只分析到了他的接口规范严格,数据处理速度快,http协议新)(dubbo可以理解为一套。)

2.PNG

简单做个gRPC中protobuf的实例吧:

放弃了,是真的繁琐,pom包阿里都没有,,比写webservice还麻烦,不喜欢用。

1.PNG

贴一段代码以备不时之需:

编写一个helloworld.proto,maven install 后会生成接口供client和server调用

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;
 
// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}
 
// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}
 
// The response message containing the greetings
message HelloReply {
  string message = 1;
}

client:

public class HelloWorldClient {
  private static final Logger logger = Logger.getLogger(HelloWorldClient.class.getName());
 
  private final ManagedChannel channel;
  private final GreeterGrpc.GreeterBlockingStub blockingStub;
 
  /** Construct client connecting to HelloWorld server at {@code host:port}. */
  public HelloWorldClient(String host, int port) {
    this(ManagedChannelBuilder.forAddress(host, port)
        // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
        // needing certificates.
        .usePlaintext()
        .build());
  }
 
  /** Construct client for accessing HelloWorld server using the existing channel. */
  HelloWorldClient(ManagedChannel channel) {
    this.channel = channel;
    blockingStub = GreeterGrpc.newBlockingStub(channel);
  }
 
  public void shutdown() throws InterruptedException {
    channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
  }
 
  /** Say hello to server. */
  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());
  }
 
  /**
   * Greet server. If provided, the first element of {@code args} is the name to use in the
   * greeting.
   */
  public static void main(String[] args) throws Exception {
    // Access a service running on the local machine on port 50051
    HelloWorldClient client = new HelloWorldClient("localhost", 50051);
    try {
      String user = "world";
      // Use the arg as the name to greet if provided
      if (args.length > 0) {
        user = args[0];
      }
      client.greet(user);
    } finally {
      client.shutdown();
    }
  }
}

server:

public class HelloWorldServer {
  private static final Logger logger = Logger.getLogger(HelloWorldServer.class.getName());
 
  private Server server;
 
  private void start() throws IOException {
    /* The port on which the server should run */
    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() {
        // Use stderr here since the logger may have been reset by its JVM shutdown hook.
        System.err.println("*** shutting down gRPC server since JVM is shutting down");
        try {
          HelloWorldServer.this.stop();
        } catch (InterruptedException e) {
          e.printStackTrace(System.err);
        }
        System.err.println("*** server shut down");
      }
    });
  }
 
  private void stop() throws InterruptedException {
    if (server != null) {
      server.shutdown().awaitTermination(30, TimeUnit.SECONDS);
    }
  }
 
  /**
   * Await termination on the main thread since the grpc library uses daemon threads.
   */
  private void blockUntilShutdown() throws InterruptedException {
    if (server != null) {
      server.awaitTermination();
    }
  }
 
  /**
   * Main launches the server from the command line.
   */
  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();
    }
  }
}

代码逻辑:启动server->启动client调用client.greet(user);->response = blockingStub.sayHello(request);进server sayHello方法->处理后返回 Greeting Hello world.

参考文章:

https://www.jianshu.com/p/9c947d98e192

(gRPC详解)

https://www.zhihu.com/question/34074946

(HTTP/2 相比 1.0 有哪些重大改进?)

https://www.cnblogs.com/zs-notes/p/9334935.html

(RPC与HTTP)

https://blog.csdn.net/tanga842428/article/details/52159757

(RPC和Webservice的区别)

https://blog.csdn.net/ation_work/article/details/88037065

(ProtoBuf、XML相关技术与Web服务架构)

https://blog.csdn.net/iverson2010112228/article/details/82631439

(spring cloud和普通rpc框架的区别)

https://www.freesion.com/article/4721457304/

(grpc-java入门实例)

https://www.cnblogs.com/LBSer/p/4853234.html

(你应该知道的RPC原理)💣


标题:浅析gRPC
作者:jyl
地址:http://www.jinyunlong.xyz/articles/2021/05/24/1621825882746.html