tars客户端(一):一次rpc的调用过程

本文详细介绍了Tars客户端的线程模型,包括客户端线程、主要类的职责,以及一次RPC调用的过程。从客户端的ServantProxy如何发起请求,到网络线程如何处理请求和响应,揭示了Tars框架在通信中的内部机制。同时,提到了网络线程和异步处理线程的生成与启动,并强调了配置参数如netthread和asyncthread的数量对客户端行为的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

用tars的客户端与tars服务端通信非常简单,因为框架层已经帮我们隐藏了寻址,协议封装,通信等细节,我们只需创建一个本地Servant代理,发起一个调用就可以。以官网的HelloServer为例:

//生成客户端代理
HelloPrx pPrx = Application::getCommunicator()->stringToProxy<HelloPrx>("Test.HelloServer.HelloObj");
//发起远程调用
string s = "hello word";
string r;
int ret = pPrx->testHello(s, r);

作为tars客户端的第一篇文章,会分两部分来初步了解tars客户端的实现:

  1. 先从顶层了解一下客户端的线程模型和客户端的各个类的职责
  2. 在熟悉了tars客户端的一些概念后,再结合代码看一下客户端发起rpc的过程

一.客户端的线程和各个代理概念

1.客户端线程

tars客户端rpc在一次调用中主要会有三个不同的线程参与:

  • 上图省略了很多细节,但是已经能够说明客户端的一次rpc调用请求的路线:主调线程发起调用,负责把请求序列化,封装成一个ReqMessage,push到消息队列中;网络线程负责处理所有的网络细节,包括链接的建立,请求发送,负载,容灾等,在收到响应后,再根据rpc调用方式决定是把响应返回给主调线程还是交由异步处理线程处理
  • 网络线程个数可配置,默认是1;每个网络线程有自己的一组异步处理线程,个数也可配,默认是3个

2.客户端主要类

  • Communicator:通信器,负责与服务端的通信。
  • ServantProxy:服务端Servant的本地代理,通过该类可以访问服务端的rpc接口。需要注意的是,这里的Servant是指tars寻址单位的Servant(即App.Server.Servant)
  • CommunicatorEpoll:基于epoll的客户端网络线程类
  • ObjectProxy:Servant在每个客户端线程的代理
  • EndPointManager:管理所有的AdapterProxy节点
  • AdapterProxy:服务端每个Adapter(对应着一个ip:port)的本地代理
  • Transceiver:负责具体的socket收发

类图如下:

 

每个ServantProxy可以有多个ObjectProxy,每个ObjectProxy又可以有多个AdapterProxy,它们的关系如下:

  • 黄色部分是ServantA在通信器中的各个代理;灰色部分是ServantB在通信器中的各个代理
  • 每个Servant在一个tars进程的通信器中只会有一个代理ServantProxy;Servant和ServantProxy是1:1的关系
  • ObjectProxy的个数和网络线程的个数有关,每个ServantProxy在每个网络线程中都有一个与之对应的ObjectProxy,例如这里的网络线程1和网络线程2都有1个ObjectProxyA;ServantProxy和ObjectProxy是1:多的关系
  • 每个ObjectProxy的EndpointManager里面又会有该Servant部署过的所有Adapter的代理,例如ServantA部署了ip1和ip2这2个节点,那么ObjectProxyA里面就会有AdapterPrxA_ip1和AdapterPrxA_ip2;ObjectProxy和AdapterProxy也是1:多的关系
  • 每个AdapterProxy都有一个属于自己的Transceiver,负责具体的网络收发工作

在与服务端的通信过程中,这些类都有自己负责的功能。下图的列子,服务端1个Servant部署两个节点(ip1,ip2),客户端通信器配了2个网络线程:

  1. ServantProxy负责发起rpc请求,序列化请求并准备好请求包,把请求包推到消息队列中
  2. 每个网络线程中都有一个ObjectProxy与每个ServantProxy对应,负责管理对应的Servant的协议解析器等
  3. ObjectProxy的EndPointManager根据负载规则和容灾规则选出合适的AdaptrProxy,把请求发给服务端
  4. AdapterProxy的Transceiver负责和服务端建立好TCP链接,进行socket收发
  5. 可以看到,在只有一个ServantProxy,两个网络线程,且每个Servant有两个活跃的Adapter的通信器中,总共会有4个TCP长链接与服务端保持链接状态

二.客户端一次rpc调用过程

1.调用流程

客户端发起rpc调用的过程,有2条主线,以同步调用方式为例子:

  1. 发起调用的线程,在发起请求后阻塞在条件变量上,直到网络线程通知它解除阻塞;
  2. 网络线程负责具有的请求收发工作

整个过程如下图:

  • 每个步骤都写上了对应的函数,可以根据这些步骤在对应的代码里看实现细节
  • 网络线程的io模型和主要逻辑和我们之前讲到的服务端网络线
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值