gRPC协议抓包

1. 引言

平时我们在浏览器中(如Chrome)可以通过开发者工具中的Network非常方便的查看HTTP/1.1和HTTP/2协议,
比如可以查询HTTP请求的protocol、host、method、path、headers、payload及response信息等相关数据,非常直观。
在这里插入图片描述

gRPC协议也是构建在HTTP/2上,并使用protobuf序列化通信数据,
我们可以通过Wireshark工具对gRPC通信进行抓包,
以查看其是如何运转在HTTP/2协议之上的,并且和我们平时的HTTP协议有何区别。

注:
使用WireShark抓取gRPC协议需要一些特殊设置,
具体设置可参见我之前的文章:《wireshark支持gRPC协议》

2. 定义gRPC服务

测试抓包使用的gRPC服务定义可参见我之前的一篇文章《gRPC Java入门示例》的Hello服务定义。

/*
* HelloWorld入门示例
*/

//使用proto3语法
syntax = "proto3";

//proto包名
package hello;
//生成多个Java文件
option java_multiple_files = true;
//指定Java包名
option java_package = "com.luo.demo.grpc.hello";
//指定Java输出类名
option java_outer_classname = "HelloProto";



//gRPC服务定义
service Hello {
  //gRPC服务方法定义 - Unary
  rpc sayHello (HelloRequest) returns (HelloReply) {}

  //gRPC服务方法定义 - Server Streaming - 服务端流
  rpc sayHelloServerStream (HelloRequest) returns (stream HelloReply) {}

  //gRPC服务方法定义 - Client Streaming - 客户端流
  rpc sayHelloClientStream (stream HelloRequest) returns (HelloReply) {}

  //gRPC服务方法定义 - BiDirection Streaming - 双向流
  rpc sayHelloBiStream (stream HelloRequest) returns (stream HelloReply) {}
}

//请求参数定义
message HelloRequest {
  string name = 1;
}

//响应结果定义
message HelloReply {
  string message = 1;
}

如上proto定义了Hello服务的4个方法,分别对应不同的类型:

包名package服务名方法名方法类型
helloHellosayHelloUnary
helloHellosayHelloServerStreamServer Streaming
helloHellosayHelloClientStreamClient Streaming
helloHellosayHelloBiStreamBiDirection Streaming

入门抓包使用Unary方法sayHello,
进阶使用Bidirectional Stream方法sayHelloBiStream。

注:
由于Bidirecitional Stream是Client Stream和Server Stream的超集,
故不在对sayHelloClientStream和sayHelloServerStream进行抓包演示,
具体细节可参见sayHelloBiStream。

3. 抓包Unary方法

启动gRPC Server端和Client端,发起一次sayHello请求,使用Wireshark抓包后一个完整的请求如下图:
在这里插入图片描述

这里直接讲解此次gRPC通信的几个重点步骤:

  • #6444 gRPC请求
  • #6458 gRPC响应头
  • #6467 gRPC响应数据

3.1 gRPC请求解析

查看#6444 gRPC请求对应的协议解析详情,如下图:
在这里插入图片描述
如上图可以发现HTTP2请求对应到gRPC请求,关系如下:

HTTP2协议GRPC协议
:authorityServer端地址
:methodPOST
:path/{package}.{service}/{method}
/包名.服务名/方法名
  • /hello.Hello/sayHello
  • /hello.Hello/sayHelloServerStream
  • /hello.Hello/sayHelloClientStream
  • /hello.Hello/sayHelloBiStream
content-typeapplication/grpc
grpc-accept-encodinggzip
DATA(payload OR 请求数据)Protobuf message定义的参数,
hello.HelloRequest

3.2 gRPC响应解析

查看#6458 gRPC响应头对应的协议解析详情,如下图:
在这里插入图片描述
查看#6467 gRPC响应数据对应的协议解析详情,如下图:
在这里插入图片描述
如上图可以发现HTTP2响应对应到gRPC响应,关系如下:

HTTP2协议GRPC协议
:status
HTTP响应码
grpc-status
grpc响应码
content-typeapplication/grpc
grpc-accept-encodinggzip
grpc-encodingidentity
DATA(响应数据 )Protobuf message定义的返回结果),
hello.HelloReply

4. 抓包Bidirectional Stream方法

发起一次sayHelloBIStream调用,示例代码中Client端发送了3次请求,相应的Server端也回应了3次,

注:
实际测试时发现,若Client端连续发送多次请求且间隔较短,Client端会合并多次请求为1次,但Server端还是分多次返回。
故在此次测试中将Client端2次发送间添加了2~3秒间隔,以便更直观展示抓取效果。

使用Wireshark抓包后效果如下图:
在这里插入图片描述

可以发现一共发送了3次gRPC双向通信且使用同一个连接(同一个tcp.stream=23),
每一次的gRPC请求及返回与之前的Unary调用类似,故不在展开,
需要注意的是仅第一次gRPC通信发送了请求HEADERS和响应HEADERS,后续的请求都不在发送相关HEADERS。


参考:
https://imququ.com/post/header-compression-in-http2.html
https://grpc.github.io/grpc/core/md_doc_statuscodes.html
https://pingcap.com/zh/blog/grpc

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

罗小爬EX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值