一、什么是RPC
RPC是“远程调用(Remote Procedure Call)”的一个名称的缩写,并不是任何规范化的协议,也不是大众都认知的协议标准,我们更多时候使用时都是创建的自定义化(例如Socket,Netty)的消息方式进行调用,相比http协议,我们省掉了不少http中无用的消息内容。因此很多系统内部调用仍然采用自定义化的RPC调用模式进行通信,毕竟速度和性能是内网的关键指标之一,而标准化和语义无关性在外网中举足轻重。所以,为何API网关无法工作在RPC上,因为它没有一个像HTTP/HTTPS那样的通用标准。
二、CzarRpc简介
CzarRpc是作者基于Dotnetty实现的RPC通讯框架,参考了Surging
和Tars.Net
优秀设计,目前正在内部使用中,下面就CzarRpc调用方式做一个简单介绍,测试结构如下:
1、服务接口
新建一个Czar.Rpc.Common
类库,首先需要引用Czar.Rpc
Nuget包。
然后定义测试接口IHelloRpc.cs
,也是目前支持的调用方式。
2.服务端
新建一个控制台程序Czar.Rpc.Server
,然后实现服务接口,因为都是测试数据,所以就随意实现了方法。
HelloRpcServer.cs
然后启动服务端监听。
启用外部使用CzarConfig.json的配置文件,注意需要设置成始终复制。
到此服务器端搭载完成。
3、客户端
新建客户端控制台程序Czar.Rpc.Client
,然后配置Rpc调用信息。
现在开始启用客户端信息。
现在整个RPC调用搭建完毕,然后分别启动服务器端和客户端,就可以看到屏幕输出内容如下。
客户端输出:
服务器端输出:
至此整个CzarRpc的基本使用已经介绍完毕,感兴趣的朋友可以自行测试。
三、Ocelot增加RPC支持
有了CzarRpc
的通讯框架后,现在在Ocelot
上实现Rpc
功能简直易如反掌,现在开始添加我们的Rpc
中间件,也让我们扩展的网关灵活起来。
还记得我介绍网关篇时添加中间件的步骤吗?如果不记得的可以先回去回顾下。
首先如何让网关知道这个后端调用是http
还是Rpc
呢?这时应该会想到Ocelot
路由配置里的DownstreamScheme
,可以在这里判断我们定义的是http
还是rpc
即可。同时我们希望之前定义的所有中间件都生效,最后一步请求时如果配置下端路由rpc
,使用rpc
调用,否则使用http
调用,这样可以重复利用之前所有的中间件功能,减少重复开发。
在之前的开发的自定义限流和自定义授权中间件开发中,我们知道开发完的中间件放到哪里使用,这里就不介绍原理了,直接添加到BuildCzarOcelotPipeline
里如下代码。
这里是在最后请求前判断使用的下游请求方式,如果DownstreamScheme
使用的rpc
,就使用rpc
中间件处理。
Rpc处理的完整逻辑是,如何从http请求中获取想要解析的参数,这里需要设置匹配的优先级,目前设计的优先级为。
1、首先提取路由参数,如果匹配上就是用路由参数名称为key,值为value,按顺序组成第一批参数。
2、提取query参数,如有有值按顺序组成第二批参数。
3、如果非Get请求,提取body内容,如果非空,组成第三批参数
4、从配置库里提取rpc路由调用的服务名称和函数名称,以及是否单向调用。
5、按照获取的数据进行rpc调用并等待返回。
看了上面的设计是不是思路很清晰了呢?
1、rpc路由表设计
2、提取远程调用方法
根据上游路由获取远程调用的配置项目
3、重写返回结果
由于rpc调用后是返回的Json封装的信息,需要解析成对应的HttpContent。
4、rpc中间件逻辑处理
有了前面的准备信息,现在基本可以完成逻辑代码的开发了,详细的中间件代码如下。
5、启动Rpc客户端配置
目前Rpc的客户端配置我们还没启动,只需要在AddCzarOcelot
中添加相关注入即可。
6、配置客户端
最后别忘了配置Rpc客户端信息是否启用证书信息,为了配置信息的内容。
现在让网关集成Rpc功能全部配置完毕。
四、网关Rpc功能测试
本次测试我在原有的网关基础上,增加不同类型的Rpc调用,就按照不同维度测试Rpc调用功能,本次测试案例是建立在Czar.Rpc 服务端基础上,正好可以测试。
1、测试路由参数
请求路径/hello/{no}/{name}
,调用的服务端方法Hello
,传入的两个参数分别是no ,name
。
可以在服务器端添加断点调试,发现确实接收到请求信息,并正常返回,下面是PostMan
测试结果。
2、使用Query方式传递参数
请求路径/rpc/query
,调用的服务端方法还是Hello
,参数分别是no ,name
。
3、使用Post方式传递Json
请求路径/rpc/body
,调用的服务器方法是HelloSendModel
。
4、混合参数使用
请求的路径/rpc/bodyparm/{name}
,调用的服务器端方法是HelloSendModelParm
。
所有的返回结果可自行调试测试,发现都能达到预期结果。
同时此网关还是支持默认的http请求的,这里就不一一测试了。
五、总结
本篇我介绍了什么是Rpc,以及Czar.Rpc的基本使用,然后使用Czar.Rpc框架集成到我们基于Ocelot扩展网关中,并实现了不能方式的Rpc调用,可以在几乎不改变现有流程的情况下很快速的集成进去,这也是Ocelot开发框架的魅力所在。
如果在使用过程中有什么问题或建议,可以在.NET Core项目实战交流群(637326624)
中联系作者。
最后本文涉及的所有的源代码可在https://github.com/jinyancao/czar.gateway中下载预览。