天天看点

tars学习rpc微服务框架涉及的问题:tars

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模式

流程

客户端请求包–>服务端解析请求包–>服务端协议处理器处理–>返回响应包–>客户端负责解包

步骤

  1. 服务端 ,开发第三方协议的解码模式,实现协议包的解析器,加载到服务中
  2. 建一个类,继承servant的非tars框架,重载servant的doRequest
  3. 保存链接上来的客户信息
  4. 重载servant的doClose,释放客户信息,服务端可以建立一个专门用于向客户push消息的线程
  5. 客户端,开发第三方协议编码模式,实现编解码函数
  6. 设置到相应的servantProxy代理的协议解析器,通过sevantProxy的tars_set_protocaol方法实现
  7. 自定义回调类,继承sevantproxyCallback,异步处理服务端过来的消息
  8. 重载onDispatch,用于解析协议
  9. new一个上面自定义的回调类,然后将其作为参数传入到servantProxy的tars_set_push_callback方法中。

    10.客户端定期给服务端发送心跳

服务端实现

1.按照第三方协议部署一个TestPushServant服务

TestPushServantImp :

int doRequest(tars::TarsCurrentPtr current, vector& response):保存用户信息,将用户请求再返回给客户端

int doClose(tars::TarsCurrentPtr current):从用户信息中将此用户删除

TestPushServer:

  1. initialize()中加载服务对象TestPushServantImp
  2. 设置第三方协议解析器parse,对收到的数据进行解析后 交给服务对象TestPushServantImp
  3. 开启pushThread

TestPushInfoThread

4. setPushInfo:设置推送的内容

5. 循环向所有客户端推送消息

客户端实现
  1. 建立通信器,
  2. 实现编解码器并设置
  3. 同步或者异步的方法访问服务:rpc_call rpc_call_async
  4. 设置接收服务端push消息的方法

RevThread:

5. 构造函数:建立通信器,设置编解码器

6. pushResponse:响应包解码,解码从服务端收到的数据为ResposePacket

7. pushRequest: 请求包编码

8. onDispatch:

9. run:发送心跳

测试结果

运行环境:linux

  1. 一个客户端,给两个server发请求,两个server都可以收到请求,
  2. 两个客户端,给两个server发请求,两个server都可以收到请求,且push的消息,两个客户端都可以收到
  3. 一个客户端发送的心跳消息 = 两个server收到的心跳消息和
  4. 只有在客户端调用同步或者

继续阅读