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

一、什么是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日被批准。

特性如下:

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

二、简单实践

文件生成

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

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

proto地址:github.com/protocolbuf...

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

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

xml 复制代码
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.6.1</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.21.5:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.48.1:exe:${os.detected.classifier}</pluginArtifact>
                    <protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot>
                    <!-- 生成的Java文件目录 -->
                    <outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
                    <clearOutputDirectory>false</clearOutputDirectory>

                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>

服务端实现

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

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

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

java 复制代码
public class ServiceImpl extends GreeterGrpc.GreeterImplBase{
  //...略
    @Override
    public StreamObserver<Helloworld.HelloRequest> doubleStream(StreamObserver<Helloworld.HelloReply> responseObserver) {
        return new StreamObserver<Helloworld.HelloRequest>() {
            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();
            }
        };
    }
}
  • 服务端代码:
java 复制代码
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();
    }
}
  • 客户端代码:
java 复制代码
     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<Helloworld.HelloRequest> doubleStream = stub.doubleStream(new StreamObserver<Helloworld.HelloReply>() {

                @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~~~

结尾

相关推荐
一只叫煤球的猫7 小时前
写代码很6,面试秒变菜鸟?不卖课,面试官视角走心探讨
前端·后端·面试
bobz9657 小时前
tcp/ip 中的多路复用
后端
bobz9658 小时前
tls ingress 简单记录
后端
皮皮林5519 小时前
IDEA 源码阅读利器,你居然还不会?
java·intellij idea
你的人类朋友9 小时前
什么是OpenSSL
后端·安全·程序员
bobz9659 小时前
mcp 直接操作浏览器
后端
前端小张同学11 小时前
服务器部署 gitlab 占用空间太大怎么办,优化思路。
后端
databook11 小时前
Manim实现闪光轨迹特效
后端·python·动效
武子康12 小时前
大数据-98 Spark 从 DStream 到 Structured Streaming:Spark 实时计算的演进
大数据·后端·spark
该用户已不存在12 小时前
6个值得收藏的.NET ORM 框架
前端·后端·.net