Thrift RPC改进—更加准确的超时管理
前言:
之前我们组内部使用Thrift搭建了一个小型的RPC框架,具体的实现细节可以参考我之前的一篇技术文章:https://www.cnblogs.com/kaiblog/p/9507642.html
相关代码的下载地址:https://github.com/zhangkai253/simpleRPC
在我们的RPC框架中,通过设置socket的timeout属性来控制超时时间,但是这个参数的设置无法保证对超时时间的准确控制,因为只要在超时时间范围内,该socket接收到了1个字节的数据,TimeoutException就不会被抛出。
在我们的日常业务中,竟然会出现设置了300ms超时时间,结果耗时3秒的情况。于是,我们开始寻找更好的解决方案。
方案一:
使用线程池设置超时时间,该方案简单直接,不过多进行叙述。
方案二:
修改底层的TTransport.readAll方法,在其中设置超时时间
Thrift中的TTransport负责进行数据的传输,其基本的类结构图如下所示:

我们本次的改进任务主要关心如下几个类:

我们的RPC框架底层使用了TFastFramedTransport来执行传输任务,这个类是TFramedTransport类的改进版本,两个类在消息格式上面是一致的,都是通过读取4个字节的消息头来解决拆包和粘包的问题。
只是底层buffer的使用方式上面有所不同,在读取数据的时候TFramedTransport类使用的是TMemoryInputTransport,而TFastFramedTransport则使用的是AutoExpandingBufferReadTransport。

通过上面的流程,我们可以看到数据的传输主要是通过在Tsocket中重写TTransport的readAll方法,可以有效地控制超时时间。
方案三:
使用TAsyncClient来替代现在的client,利用TAsyncClientManager来进行超时时间管理,下面我们看看TAsyncClientManager是如何管理请求的。这个问题的答案,我们可以直接从相关的源码中获得,
public void run() {
while (running) {
try {
try {
// 当Thrift请求发送的时候,如果请求设置了超时时间,则会被放到
// timeoutWatchSet中
if (timeoutWatchSet.size() == 0) {
// 如果没有设置了超时时间的请求,则无限期低等待下去
selector.select();
} else {
// 从timeoutWatchSet中取出距离当前最近的过期时间
long nextTimeout = timeoutWatchSet.first().getTimeoutTimestamp();
long selectTime = nextTimeout - System.currentTimeMillis();
if (selectTime > 0) {
// 如果过期时间大于当前时间,则等待剩余时间
selector.select(selectTime);
} else {
// 如果过期时间小于等于当前时间,则立即返回
selector.selectNow();
}
}
} catch (IOException e) {
LOGGER.error("Caught IOException in TAsyncClientManager!", e);
}
transitionMethods();
timeoutMethods();
startPendingMethods();
} catch (Exception exception) {
LOGGER.error("Ignoring uncaught exception in SelectThread", exception);
}
}
try {
selector.close();
} catch (IOException ex) {
LOGGER.warn("Could not close selector. This may result in leaked resources!", ex);
}
}
上述三种方案都可以很好地实现RPC框架对超时时间的控制。大家可以根据自己的使用场景选择合适的解决方案。
如果想进一步沟通和讨论的小伙伴,可以加群聊或者微信进一步交流哈。

Thrift RPC改进—更加准确的超时管理的更多相关文章
- C++服务器设计(四):超时管理机制设计
前四章介绍了系统层的设计,从这一章开始进入服务层的设计. 连接断开 在常见的服务器场景中,客户端断开连接的方式为被动关闭.即作为客户端请求完服务器的服务后,选择主动关闭同服务器的连接.在服务器的角度看 ...
- 如何用istio实现请求超时管理
前言 在前面的文章中,大家都已经熟悉了Istio的故障注入和流量迁移.这两个方面的功能都是Istio流量治理的一部分.今天将继续带大家了解Istio的另一项功能,关于请求超时的管理. 首先我们可以通过 ...
- thrift RPC 框架的自我搭建
安装thrift rpc 安装的系统是Centos 7 未成功的方法 :(原因没找到,但是还是要记录下) 安装依赖库 yum install automake libtool flex bison ...
- thrift rpc通信
thrift rpc通信 框架 别人的简历: 负责抓取程序的开发和维护,对抓取内容进行数据提取.整理.1.定向数据抓取程序的维护和开发,了解了Sqlite数据库.Thrift服务和多线程的开发调试.2 ...
- Thrift RPC Golang、C++ Example
Thrift RPC Example 运行 请直接使用即可,无需拉取任何依赖包. cd $GOPATH/src git clone https://github.com/hunterhug/thrif ...
- idou老师教你学Istio 07: 如何用istio实现请求超时管理
在前面的文章中,大家都已经熟悉了Istio的故障注入和流量迁移.这两个方面的功能都是Istio流量治理的一部分.今天将继续带大家了解Istio的另一项功能,关于请求超时的管理. 首先我们可以通过一个简 ...
- Thrift RPC实战(三) thrift序列化揭秘
本文主要讲解Thrift的序列化机制, 看看thrift作为数据交换格式是如何工作的? 1.构造应用场景: 1). 首先我们先来定义下thrift的简单结构. 1 2 3 4 5 namespace ...
- libevent源码学习(11):超时管理之min_heap
目录min_heap的定义向min_heap中添加eventmin_heap中event的激活以下源码均基于libevent-2.0.21-stable. 在前文中,分析了小顶堆min_h ...
- 使用Thrift RPC编写程序(服务端和客户端)
1. Thrift类介绍 Thrift代码包(位于thrift-0.6.1/lib/cpp/src)有以下几个目录: concurrency:并发和时钟管理方面的库processor:Processo ...
随机推荐
- sed基本使用
1. 删除由空格组成的空白行 sed '/^ *$/d' test.txt sed '/[ ][ ]/d' test.txt 2. 删除空白行 sed '/^[[:space:]]*$/d' test ...
- 【cartographer_ros】七: 主要配置参数说明
上一节介绍了路标Landmark数据的订阅和发布,各类数据的发布和订阅基本阐述完毕. 本节会介绍cartographer的主要配置参数,研究这些参数的使用和对算法的影响. 目录 1,map_build ...
- httrack使用cookie克隆站点
关于cookies使用在这里官方已有说明,意思是将cookies.txt文件放在项目的根目下即可,格式也给了说明.问题是cookie值太多,手动不好整理,所以就需要用到神器editthiscookie ...
- Kubuntu安装字体
打开设置,选择字体-字体管理器,再把网上下载好的ttf字体包解压,选择安装即可.(建议选为系统字体) Kubuntu20.04LTS
- 10分钟带你进入Swagger的世界,快来看一看吧
什么是Swagger? 如下引用swagger官方的解释 Swagger is a powerful yet easy-to-use suite of API developer tools for ...
- 一种新的UI测试方法:视觉感知测试
什么是视觉测试 视觉测试(Visual Testing),主要检查软件用户界面(UI)是否正确显示给所有用户.它检查网页上的每个元素的形状.大小和位置是否符合预期,还检查这些元素是否在不同的设备和浏览 ...
- Winsock Client Code
以下代码来自MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/ms737591(v=vs.85).aspx #define W ...
- VIM学习笔记-1
VIM vim主要分为3个模式: Normal 模式 Insert模式 command模式 Insert 模式就是普通的编辑模式,没有太多可以介绍的,vim的主要功能都在 Normal 模式和 Com ...
- Solution -「基环树」做题记录
写的大多只是思路,比较简单的细节和证明过程就不放了,有需者自取. 基环树简介 简单说一说基环树吧.由名字扩展可得这是一类以环为基础的树(当然显然它不是树. 通常的表现形式是一棵树再加一条非树边,把图画 ...
- ESXI启用本地登录和SSH服务连接功能,使用Xshell连接
1.选中Troubleshoot Options进行SSH服务配置 2.开启本地登录功能 3.开启远程连接功能 4.本地登录修改SSH服务允许基于密码登录 默认无法用密码登录ssh服务,只支持基于ke ...