rpc微服务框架涉及的问题:
- 高效、可靠的调度器
- 同步调用和异步调用的设计
- 适当的发送协议已经解析结果
- 提供不同的服务选择节点的策略-轮询、hash、权重
- 管理服务节点状态,节点是否已连接,是否连接中,是否超时,是否重连,超时时间设置,重连时间设置等,
- 如何可靠的接受请求,发送结果,请求量的控制,接受到1.5个请求怎么办,发送请求,未收到结果怎么办;
tars
App:应用名,标识一组服务的一个小集合,在tars系统中是唯一的–
Server:服务名,服务的进程名称,在App下是唯一的,绑定至少一个ip
Servant:服务提供者,多个具体的接口;是一个类,需要自己实现内部接口,举例:HelloObj,在Server下是唯一的,调用方式举例:App.Server.Servant
module:tars协议文件中的关键字,定义了协议空间,类似c++中的命名空间
tars文件目录规范:
- 目录:/home/tarsproto/[namespace]/[server]
- tars接口原则上只能增加,不能减少或者修改
- 各语言提供的Tars服务框架, 都提供了快速release tars文件到/home/tarsproto/[namespace]/[server]下的工具
服务端开发方式:
- 确定APP, Server,Servant名称
- 编写tars文件,定义服务对外提供的interface以及函数,主要interface必须有一个,
- 使用tars2xxx工具,将tars文件生成代码;
- 实现tars服务,集成生成的Servant类
- 编译发布
- 本地运行:
ps -efww | grep ${your server name}
定位到配置文件所在路径,复制到当前目录,用
severname --config=xxxX.config
即可本地运行,上述配置文件是服务框架的配置,而非业务配置
客户端开发方式
使用通信器,根据Servant名称获取对应服务的代理对象,使用代理对象完成通信
- 通信器:是个类,服务框架Application中有一个初始化过的可以使用;
- 如果client是部署在框架上的另外一个服务,则使用Application中的通信器,不用指定ip和port,直接使用Servant的Obj名称即可访问
- 如果client是独立的,没有部署在框架上,则需要自己创建通信器,有两种调用方式:
Communicator *communicator = new Communicator();
HelloPrx helloPrx = communicator->stringToProxy<HelloPrx>("Test.HelloServer.Hello[email protected] -h xxx -p yyy:tcp -h www -p zzz");
helloPrx->call();
tars中的push模式
流程
客户端请求包–>服务端解析请求包–>服务端协议处理器处理–>返回响应包–>客户端负责解包
步骤
- 服务端 ,开发第三方协议的解码模式,实现协议包的解析器,加载到服务中
- 建一个类,继承servant的非tars框架,重载servant的doRequest
- 保存链接上来的客户信息
- 重载servant的doClose,释放客户信息,服务端可以建立一个专门用于向客户push消息的线程
- 客户端,开发第三方协议编码模式,实现编解码函数
- 设置到相应的servantProxy代理的协议解析器,通过sevantProxy的tars_set_protocaol方法实现
- 自定义回调类,继承sevantproxyCallback,异步处理服务端过来的消息
- 重载onDispatch,用于解析协议
-
new一个上面自定义的回调类,然后将其作为参数传入到servantProxy的tars_set_push_callback方法中。
10.客户端定期给服务端发送心跳
服务端实现
1.按照第三方协议部署一个TestPushServant服务
TestPushServantImp :
int doRequest(tars::TarsCurrentPtr current, vector& response):保存用户信息,将用户请求再返回给客户端
int doClose(tars::TarsCurrentPtr current):从用户信息中将此用户删除
TestPushServer:
- initialize()中加载服务对象TestPushServantImp
- 设置第三方协议解析器parse,对收到的数据进行解析后 交给服务对象TestPushServantImp
- 开启pushThread
TestPushInfoThread
4. setPushInfo:设置推送的内容
5. 循环向所有客户端推送消息
客户端实现
- 建立通信器,
- 实现编解码器并设置
- 同步或者异步的方法访问服务:rpc_call rpc_call_async
- 设置接收服务端push消息的方法
RevThread:
5. 构造函数:建立通信器,设置编解码器
6. pushResponse:响应包解码,解码从服务端收到的数据为ResposePacket
7. pushRequest: 请求包编码
8. onDispatch:
9. run:发送心跳
测试结果
运行环境:linux
- 一个客户端,给两个server发请求,两个server都可以收到请求,
- 两个客户端,给两个server发请求,两个server都可以收到请求,且push的消息,两个客户端都可以收到
- 一个客户端发送的心跳消息 = 两个server收到的心跳消息和
- 只有在客户端调用同步或者