Google高性能开源框架gRPC:快速搭建及HTTP/2抓包

2023年 9月 16日 150.3k 0

一、什么是gRPC

gRPC是google发起的一个*远程过程调用(rpc)*开源框架,可以在任何语言中,用任何编程语言编写。gRPC基于HTTP/2协议,使用Protocol Buffers作为序列化工具。

gRPC官网:grpc.io/

RPC

Remote Procedure Call,远程过程调用协议,一种通过网络调用远程计算机上服务,并且无需关注交互细节。可以理解为,服务A调用另一个服务B中的某段程序,底层实现对于开发者无感知,可以是基于HTTP/1.1也可以基于HTTP/2,可以序列化成json,xml,Protocol Buffers这些都不需要关心。像Dubbo就是一个RPC框架,仅关心业务编程即可。

Protocol Buffers

Protocol Buffers是一个跨语言,跨平台可扩展的数据结构序列化的一个工具语言,和JSON类似,但比JSON更小,更高效。需要通过工具编译成指定语言的代码,相当于你定义的对象需要由工具生成。

HTTP/2

HTTP协议第二个版本,兼容HTTP/1.1(目前广泛使用的仍然是HTTP/1.1),基于SPDY协议,于2015年2月17日被批准。

特性如下:

  • 头部压缩:使用HPACK算法对头部进行压缩
  • 对数据传输采用多路复用,让多个请求合并在同一TCP连接内。
  • 服务端主动推送消息
  • 二、简单实践

    文件生成

    因为gRPC基于Protocol Buffers,需要通过工具来生成。

    一种完全无依赖的方式是自己下载软件,如果要使用gRPC需要额外下载protoc-gen-grpc-java

    proto地址:github.com/protocolbuf…

    protoc-gen-grpc-java地址:repo.maven.apache.org/maven2/io/g…

    配置了好久没有配置成功,然后用了其他方案,maven插件的方式

            
                
                    org.springframework.boot
                    spring-boot-maven-plugin
                
                
                    org.xolstice.maven.plugins
                    protobuf-maven-plugin
                    0.6.1
                    
                        com.google.protobuf:protoc:3.21.5:exe:${os.detected.classifier}
                        grpc-java
                        io.grpc:protoc-gen-grpc-java:1.48.1:exe:${os.detected.classifier}
                        ${project.basedir}/src/main/proto
                        
                        ${project.basedir}/src/main/java/
                        false
    
                    
                    
                        
                            
                                compile
                                compile-custom
                            
                        
                    
                
    
            
    

    服务端实现

    生成的文件部分就不占用过多篇幅了

    仓库地址:gitee.com/Nortyr/alli…

    这个是服务端实现,其中doubleStream我测试接收stream,返回stream

    public class ServiceImpl extends GreeterGrpc.GreeterImplBase{
      //...略
        @Override
        public StreamObserver doubleStream(StreamObserver responseObserver) {
            return new StreamObserver() {
                AtomicInteger integer=new AtomicInteger();
    
                @Override
                public void onNext(Helloworld.HelloRequest helloRequest) {
                    System.out.println(helloRequest.getMessage());
    
                    Helloworld.HelloReply response = Helloworld.HelloReply.newBuilder()
                            .setMessage("瞅你咋地~~"+integer.incrementAndGet())
                            .build();
                    responseObserver.onNext(response);
                }
    
                @Override
                public void onError(Throwable throwable) {
                    System.out.println("error: " + throwable.getMessage());
    
                }
    
                @Override
                public void onCompleted() {
                    System.out.println("Server completed");
                    responseObserver.onCompleted();
                }
            };
        }
    }
    
    • 服务端代码:
    public class ServerDemo {
        public static void main(String[] args) throws Exception {
            int port = 9091;
            Server server = ServerBuilder
                    .forPort(port)
                    .addService(new ServiceImpl())
                    .build()
                    .start();
            System.out.println("server started, port : " + port);
            server.awaitTermination();
        }
    }
    
    • 客户端代码:
    
         private static void testDoubleStream() throws InterruptedException {
                String host = "127.0.0.1";
                int port = 9091;
                ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext().build();
    
        //        client接收一个对象
                GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel);
    
    
                StreamObserver doubleStream = stub.doubleStream(new StreamObserver() {
    
                    @Override
                    public void onNext(Helloworld.HelloReply helloReply) {
                        System.out.println("Received: " + helloReply.getMessage());
                    }
    
                    @Override
                    public void onError(Throwable throwable) {
                        System.out.println("error: " + throwable);
                    }
    
                    @Override
                    public void onCompleted() {
                        System.out.println("Client completed");
                    }
                });
                doubleStream.onNext(Helloworld.HelloRequest.newBuilder().setMessage("你瞅啥~~ 1").build());
                doubleStream.onNext(Helloworld.HelloRequest.newBuilder().setMessage("你瞅啥~~ 2").build());
                doubleStream.onNext(Helloworld.HelloRequest.newBuilder().setMessage("你瞅啥~~ 3").build());
                doubleStream.onCompleted();
                Thread.sleep(10000);
                channel.shutdown();
            }
    
    • 启动结果如下:

    抓包分析

    还没见过HTTP/2报文,想看下,发现全是TCP

    需要修改下,使用http2解析

    如果想要看到内容需要配置下ProtoBuf文件位置
    Wireshark>Perferences>Protocols>ProtoBuf

    至此over~~~

    结尾

    • 仓库地址:gitee.com/Nortyr/alli…
    • 参考资料
      • grpc.io/
      • protobuf.dev/
      • zh.wikipedia.org/wiki/HTTP/2
      • blog.csdn.net/luo15242208…

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论