前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >腾讯开源框架TarsCpp-rpc设计分析-client(一)

腾讯开源框架TarsCpp-rpc设计分析-client(一)

原创
作者头像
路小饭
修改2019-06-10 11:23:45
2.8K0
修改2019-06-10 11:23:45
举报

前言

Tars是腾讯开源的微服务平台,包含了一个高性能的rpc框架和服务治理平台,TarsCpp是其C++版本。对于以C++为主要开发语言,同时还想深入了解rpc和微服务框架具体实现的同学来说,Tars是一个极佳的选择。

想像一下,如果你自己来设计一个rpc-client,都应该考虑哪些因素?

  • 一个高效、可靠的调度器(epoll模型)
  • 如何设计同步调用、异步调用
  • 使用适当的协议来发送请求、解析结果
  • 提供不同的选择服务节点的策略,包括但不限于轮询、hash、权重等
  • 管理服务节点状态,包括不限于节点是否已经连接,是否正在连接中,连接是否超时,是否需要重连,连接超时时间设置,连接重连时间设置等
  • 如何可靠的接收请求、发送结果,请求量怎么控制,接收到1.5个请求怎么办,请求发送完迟迟没收到结果怎么办

这些问题都可以从tars-rpc-client中寻找到实现答案

1 rpc-client概要设计

学习源码的一个重要目的是学习“别人家”模块或项目的设计思路,设计思路的珍贵之处在于其超脱了项目甚至语言的层次,可以迁移到其他地方。

tar-rpc-client主要由4个组件构成:ServantProxy,ObjectProxy,CommunicatorEpoll,AsyncProcThread,其中:

  • ServantProxy:直接与使用者交互,提供简便易用接口
  • ObjectProxy:封装网络层收发细节
  • CommunicatorEpoll:提供收发调度功能
  • AsyncProcThread:提供异步调用功能

四个组件的关系见图1。

图1
图1
  • 在主线程里,ServantProxy是工头,它承接客户需求并加以整理,然后按照一定顺序分给众小弟们(一个小弟是一个ObjectProxy)
  • 小弟ObjectProxy在调度线程中依赖CommunicatorEpoll中的epoll模型高效有序的干活
  • 如果是同步调用,ServantProxy会在主线程中等待,直到ObjectProxy在调度线程中完成请求发送和结果接收
  • 如果是异步调用,主线程不会阻塞,主线程中注册的回调函数在回调线程AsyncProcThread中被执行
  • 一个小弟ObjectProxy对应一个CommunicatorEpoll,一个ServantProxy可以对应多个ObjectProxy
  • 一个CommunicatorEpoll可以对应多个AsyncProcThread

2 CommunicatorEpoll概要设计

CommunicatorEpoll在rpc-client设计中处于核心地位,它确认了client信息流的调度方式。

CommunicatorEpoll是一个封装后的epoll模型,CommunicatorEpoll设计巧妙之处在于将客户调用函数的动作也作为了epoll的触发条件。下面以图2说明CommunicatorEpoll的设计架构

图2
图2

CommunicatorEpoll将epoll\_wait中得到的消息分为两类,一类是处理ObjectProxy消息,另外一类是处理EPOLLIN、EPOLLOUT、EPOLLERR消息。

最核心的系统调用函数也列在了图2上,包括紫色的epoll\_wait和epoll\_ctl、绿色的connect、send和readv。

图2中展示了一个最简单的函数调用流程,下面的序号对应了图2中箭头里的序号

  1. 当用户调用ServantProxy::Hello方法时候,ServantProxy将这个方法包含的内容组成一个msg
  2. 通过ObjectProxy将msg注册到CommunicatorEpoll中。
  3. epoll\_wait获取了通知,处理msg
  4. 链接server端,成功后获取connent fd
  5. 将connect fd注册到CommunicatorEpoll中
  6. 发送请求
  7. 接收结果

2.1 同步call

rpc\_client一般有两种基本的调用方式,sync\_call和async\_call,即同步call和异步call。先看下同步call的实现机制。

同步call实现机理较简单,只需要主线程、调度线程配合就能实现。见图3.

图3
图3
  1. 主线程调用函数后阻塞等待调度线程的信号通知,
  2. 调度线程收到结果后,主备发送信号通知
  3. 发送信号通知
  4. 主线程接收到信号后,本次调用结束

2.2 异步call

异步call需要主线程、调度线程、回调线程三个组件,见图4

图4
图4
  1. 主线程调用完方法后直接结束
  2. 调度线程接收到结果后,放入回调线程的队列\_msgQueue中
  3. 回调线程循环等待\_msgQueue中的msg,当有msg进入时,会使用pop\_front取出
  4. 调用回调函数处理msg

未完--待续

下一篇文章会继续ObjectProxy的设计思路

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 1 rpc-client概要设计
  • 2 CommunicatorEpoll概要设计
    • 2.1 同步call
      • 2.2 异步call
      相关产品与服务
      微服务平台 TSF
      微服务平台(Tencent Service Framework,TSF)是一个围绕应用和微服务的 PaaS 平台,提供一站式应用全生命周期管理能力和数据化运营支持,提供多维度应用和服务的监控数据,助力服务性能优化。提供基于 Spring Cloud 和 Service Mesh 两种微服务架构的商业化支持。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档