”抓包gRPC调用并分析具体抓包数据加深对gRPC的理解“

写在前面

最近团队里预计开发一套基于gRPC的网关,而恰逢国庆假期,可以抽出时间来整理一下早期对gRPC的一些研究。如果只是在应用层使用gRPC,我相信学习gRPC官网里的示例便足够了。但是如果打算在团队中大量地使用gRPC,会面对很多的挑战,比如服务之间的鉴权方案、多地域服务的路由方案、与已有RESTful服务的兼容方案等。

我最近感悟到,对一个技术栈的应用,需要掌握此技术栈的大量信息,如此才能保证此技术栈在生产使用时的稳定性。本文从最基本的抓包切入,简单介绍一次gRPC调用的数据流动情况。

工具及源码

抓包细节

首先应该明白,gRPC是HTTP/2和protobuf的结合体,认识到这两点,在抓包时便方便很多。比如,在使用Wireshark抓包时把未识别的HTTP/2协议手动设置为HTTP/2(否则会仅以TCP方式解析二进制);在查看HTTP/2时不要找JSON的那种数据展示(protobuf有自己的压缩算法)。

一次gRPC调用总览

gRPC调用总览 【图-gRPC调用总览】

从上图可以大体看出,在gRPC的helloworld中从client端调用server端,会有多次的HTTP2请求,大体上可以分为:Magic->Settings->Headers->Data->Settings->Window-update,Ping->Ping->Headers,Data,Headers->Window_update,ping->Ping

Settings

从gRPC调用总览图可以看到,总共有两次的Settings设置,不过两次setting有相同的数据,具体数据如下:

Settings.png

Headers

gRPC发送请求的Header的截图如下,可以发现其中一些细节:

  1. HTTP/2的Header数据是被压缩了的;
  2. Header中包含了method(POST)、scheme(http)、path(/helloword.Greeter/SayHello)、content-type(application/grpc)等,很全。

Headers

Data

Headers部分主要由client向server发送请求相关的数据,在Data部分由server向client发送数据。

data

再一次的Settings

再一次的settings与第一次基本上没有区别,除了ACK的标识位为True

settings-2

Window_update, Ping

从下面可以看到,在HTTP/2的一次请求中,可以包含两个stream块。

window_update-ping

ping(pong)

当client向server端发送了一个ping请求,server端会发回pong响应。上面的ping为client发起的,下面的ping为server端发起的。

pong

headers,data,headers

这里的数据为server向client端发送的数据(包含了header及body),具体截图如下图所示。 data-2

window_update,ping

可以发现,不仅仅client可以向server发起ping,也可以反向由server向client进行ping的操作。

window_update

再一次ping(pong)

当然,在server发起ping操作后,client会发起pong操作。

pong-2

gRPC中的context数据

context源码

有一天,小黄老师跑过来问:如果在gRPC从client调用server端服务时,在context中添加了一些数据,那么这些数据是如何传输到server端的?其实这些context中的数据会以header头的形式进行传输,比如上面图中所展示的代码,在context中塞了abc=>ccc的键值对。

通过抓包可以看到,abc=>ccc的键值对写入了header中,如下图:

context-wireshark

小结

本文通过对gRPC的helloworld进行抓包,跟踪了一次gRPC调用过程可能包含的数据流过程。在学习了gRPC的理论性知识后,再结合本文的抓包内容,应该能对gRPC(侧重HTTP/2技术)有一个更好的理解。

参考