背景
一个RPC慢调用引发的思考
和 Mysql 的慢查询类似,RPC 服务调用也会有慢请求。通过本篇文章你可以了解到一个RPC调用的执行过程,从而能快速定位问题
Pigeon 作为 RPC 中间件,本篇文章就以 Pigeon-2.10.8 为例,
什么是Pigeon
Pigeon是一个纯粹使用HTTP协议封装的一个符合RESTful规范的用于客户端与服务端之间通过接口规范来进行通讯的RPC框架
尤其擅长于Android/iOS与JAVA服务端的API调用,致力于解决目前移动互联网开发过程中网络通讯方面的各种问题.
其基本框架如下:
大体上,Pigeon 分为 Client 端和 Server 端
Client 端包括:客户端代理、客户端Filter、连接池、业务线程池、NettyClient。
Pigeon 允许客户端与一个服务端机器建立多个连接,这个连接是在 Client 的 ChannelPool 中维护。
Reactor 模型
假设当客户端和服务端建立连接之后( pigeon启动过程 ),客户端调用远程服务,参照上图,Pigeon 的执行路径如下:
1、首先在客户端调用远程服务方法时,其真正调用的是 InvocationHandler 的 invoke 方法(这里使用 JDK 的动态代理)。Pigeon 中 InvocationHandler 的实现为 ServiceInvocationProxy, 所以调用接口声明的任意方法最终都会进到 ServiceInvocationProxy.invoke 方法。
2、ServiceInvocationProxy.invoke 中会调用客户端 Filter ,请求会依次经过 监控、路由、降级、网关、鉴权 等模块后,进入 RemoteCallInvokeFilter。
3、在 RemoteCallInvokeFilter 中调用 Client.write 方法,其逻辑为从连接池(ChannelPool)中 获取连接(获取连接的超时时间默认为:2000ms),然后将数据写进 Channel。
4、在向服务端发送数据之前,需经过 Channel 的 Pipeline(序列化、压缩等,减少网络传输的数据量)。
5、然后就开始向服务端发送数据,由于 Netty 发送消息是异步的,所以如果是同步调用的话,Pigeon 这里会让业务线程主动 await ,直到收到服务端响应或超时后唤醒。
6、服务端收到客户端发过的消息后,从 Channel 中将消息读出来之前,也会先经过一些 Pipeline(反序列化、解压缩等)后到达 NettyServerHandler,在其中 Pigeon 这边还做了服务隔离的设计:
7、在选择相应的线程池并成功的拿到线程后,请求就到了服务端 Filter 中。请求会依次经过 监控、流量录制、鉴权、泛化调用、网关等模块后,进入 BusinessProcessFilter。
8、在 BusinessProcessFilter 中会根据客户端传递来的服务信息和参数,通过反射调用相应的业务服务并拿到业务处理结果。然后在 WriteResponseProcessFilter 中将返回结果写入 Channel。
9、返回结果再经过服务端的 Pipeline 处理(序列化、压缩等),就发给客户端
10、客户端收到消息后,经过客户端的 Pipeline 处理(反序列化、解压缩等)后到达 NettyClientHandler,然后交给 ResponseThreadPoolProcessor 线程池处理。
11、ResponseThreadPoolProcessor 收到消息后,会通知之前 await 的业务线程,并将结果传递给他。
12、业务线程收到 signal 通知后,就将结果返回给之前的方法调用。
总结:知原理,才能快速定位问题