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

2023-09-15 17:25:01

一、什么是gRPC

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

gRPC官网:https://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地址:https://github.com/protocolbuffers/protobuf/releases/tag/v24.3

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

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

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

服务端实现

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

仓库地址:https://gitee.com/Nortyr/allinone

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

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();
            }
        };
    }
}
  • 服务端代码:
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<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~~~

结尾

  • 仓库地址:https://gitee.com/Nortyr/allinone/tree/main/grpc_demo
  • 参考资料
    • https://grpc.io/
    • https://protobuf.dev/
    • https://zh.wikipedia.org/wiki/HTTP/2
    • https://blog.csdn.net/luo15242208310/article/details/122909827
更多推荐

Python 基于PyCharm断点调试

视频版教程Python3零基础7天入门实战视频教程PyCharmDebug(断点调试)可以帮助开发者在代码运行时进行实时的调试和错误排查,提高代码开发效率和代码质量。准备一段代码defadd(num1,num2):returnnum1+num2if__name__=='__main__':fornuminrange(1

Linux Day18 TCP_UDP协议及相关知识

一、网络基础概念1.1网络网络是由若干结点和连接这些结点的链路组成,网络中的结点可以是计算机,交换机、路由器等设备。1.2互联网把多个网络连接起来就构成了互联网。目前最大的互联网就是因特网。网络设备有:交换机、路由器、集线器传输介质有:双绞线、同轴电缆、光纤,无线1.3IP地址IP地址就是给因特网上的每一个主机(或路由

【工作记录】springboot集成aop实现日志@20230918

springboot集成aop实现日志1.添加依赖<!--aop依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>2.定义注解@

使用Postman如何在接口测试前将请求的参数进行自定义处理

1、前言当我们使用Postman进行接口测试时,对于简单的不需要处理的接口,直接请求即可,但是对于需要处理的接口,如需要转码、替换值等,则就麻烦一些,一般我们都是先手动把修改好的值拷贝到请求里再进行请求接口,这也是大多数测试人员进行接口测试时这么做的。其实Postman有一个Pre-requestScript功能,即在

Ampere ARM Server 内核版本更新

本篇记录AmpereARMServer服务器上,升级内核版本或部分驱动的方法。安装编译依赖库sudoapt-getinstallbuild-essentialkernel-packagelibncurses5-devlibncurses-devsudoapt-getinstallgccmakebisonflexlibs

(高阶)Redis 7 第13讲 数据双写一致性 canal篇

面试题问题答案如何保证mysql改动后,立即同步到Rediscanal简介https://github.com/alibaba/canal/wikihttps://github.com/alibaba/canal/wiki基于MySQL数据库增量日志解析,提供增量数据订阅和消费业务数据库镜像数据库实时备份多级索引(卖家

mysq 主从同步错误之 Error_code 1032 handler error HA_ERR_KEY_NOT_FOUND

错误说明:MySQL主从同步的1032错误,一般是指要更改的数据不存在,SQL_THREAD提取的日志无法应用故报错,造成同步失败(Update、Delete、Insert一条已经delete的数据)。1032的错误本身对数据一致性没什么影响,影响最大的是造成了同步失败、同步停止。如果主主(主从)有同步失败,要第一时间

第八天:gec6818arm开发板和Ubuntu中安装并且编译移植mysql驱动连接QT执行程序

一、Ubuntu18.04中安装并且编译移植mysql驱动程序连接qt执行程序1、安装Mysqlsudoapt-getinstallmysql-serverapt-getisntallmysql-clientsudoapt-getinstalllibmysqlclient-d2、查看是否安装成功,即查看MySQL版本m

软件测试(功能、工具、接口、性能、自动化、测开)详解

一、软件测试功能测试测试用例编写是软件测试的基本技能;也有很多人认为测试用例是软件测试的核心;软件测试中最重要的是设计和生成有效的测试用例;测试用例是测试工作的指导,是软件测试的必须遵守的准则。黑盒测试常见测试用例编写方法1、等价类选取少数有代表性的数据,这一类数据等价于这一类的其它值;找出最小的子集,可以发现最多的错

时序预测 | MATLAB实现POA-CNN-LSTM鹈鹕算法优化卷积长短期记忆神经网络时间序列预测

时序预测|MATLAB实现POA-CNN-LSTM鹈鹕算法优化卷积长短期记忆神经网络时间序列预测目录时序预测|MATLAB实现POA-CNN-LSTM鹈鹕算法优化卷积长短期记忆神经网络时间序列预测预测效果基本介绍程序设计参考资料预测效果基本介绍MATLAB实现POA-CNN-LSTM鹈鹕算法优化卷积长短期记忆神经网络时

分布式系统的 38 个知识点

天天说分布式分布式,那么我们是否知道什么是分布式,分布式会遇到什么问题,有哪些理论支撑,有哪些经典的应对方案,业界是如何设计并保证分布式系统的高可用呢?1.架构设计这一节将从一些经典的开源系统架构设计出发,来看一下,如何设计一个高质量的分布式系统;而一般的设计出发点,无外乎冗余:简单理解为找个备胎,现任挂掉之后,备胎顶

热文推荐