前言:

之前我们组内部使用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改进—更加准确的超时管理的更多相关文章

  1. C++服务器设计(四):超时管理机制设计

    前四章介绍了系统层的设计,从这一章开始进入服务层的设计. 连接断开 在常见的服务器场景中,客户端断开连接的方式为被动关闭.即作为客户端请求完服务器的服务后,选择主动关闭同服务器的连接.在服务器的角度看 ...

  2. 如何用istio实现请求超时管理

    前言 在前面的文章中,大家都已经熟悉了Istio的故障注入和流量迁移.这两个方面的功能都是Istio流量治理的一部分.今天将继续带大家了解Istio的另一项功能,关于请求超时的管理. 首先我们可以通过 ...

  3. thrift RPC 框架的自我搭建

    安装thrift rpc   安装的系统是Centos 7 未成功的方法 :(原因没找到,但是还是要记录下) 安装依赖库 yum install automake libtool flex bison ...

  4. thrift rpc通信

    thrift rpc通信 框架 别人的简历: 负责抓取程序的开发和维护,对抓取内容进行数据提取.整理.1.定向数据抓取程序的维护和开发,了解了Sqlite数据库.Thrift服务和多线程的开发调试.2 ...

  5. Thrift RPC Golang、C++ Example

    Thrift RPC Example 运行 请直接使用即可,无需拉取任何依赖包. cd $GOPATH/src git clone https://github.com/hunterhug/thrif ...

  6. idou老师教你学Istio 07: 如何用istio实现请求超时管理

    在前面的文章中,大家都已经熟悉了Istio的故障注入和流量迁移.这两个方面的功能都是Istio流量治理的一部分.今天将继续带大家了解Istio的另一项功能,关于请求超时的管理. 首先我们可以通过一个简 ...

  7. Thrift RPC实战(三) thrift序列化揭秘

    本文主要讲解Thrift的序列化机制, 看看thrift作为数据交换格式是如何工作的? 1.构造应用场景: 1). 首先我们先来定义下thrift的简单结构. 1 2 3 4 5 namespace ...

  8. libevent源码学习(11):超时管理之min_heap

    目录min_heap的定义向min_heap中添加eventmin_heap中event的激活以下源码均基于libevent-2.0.21-stable.       在前文中,分析了小顶堆min_h ...

  9. 使用Thrift RPC编写程序(服务端和客户端)

    1. Thrift类介绍 Thrift代码包(位于thrift-0.6.1/lib/cpp/src)有以下几个目录: concurrency:并发和时钟管理方面的库processor:Processo ...

随机推荐

  1. 谷歌浏览器控制台 f12怎么设置成中文/英文 切换方法,一定要看到最后!!!

    1.打开谷歌浏览器 2.右键选择检查或 f12 打开控制台 3.点击控制台右边的设置 4.中切英 选择偏好设置->语言=>English 5.英切中 6.选择中文 7.重启 8.切换中文成 ...

  2. java程序使用ssl证书连接mysql

    1. 在mysql服务器上生成证书 openssl genrsa 2048 > ca-key.pem openssl req -new -x509 -nodes -days 3600 -key ...

  3. ansible在linux和windows批量部署zabbix-agent2

    --- - hosts: linux tasks: - name: copy centos 7 zabbix-agent2 copy: src=zabbix-agent2-5.0.11-1.el7.x ...

  4. docker删除镜像报错 Error response from daemon: conflict: unable to delete f73fe6298efc (cannot be forced) - image has dependent child images

    方法1 docker rmi 镜像ID 方法2 docker rmi -f 镜像ID 方法3 docker rmi 镜像仓库名:tag

  5. NC14893 栈和排序

    NC14893 栈和排序 题目 题目描述 给你一个1->n的排列和一个栈,入栈顺序给定 你要在不打乱入栈顺序的情况下,对数组进行从大到小排序 当无法完全排序时,请输出字典序最大的出栈序列 输入描 ...

  6. FFT 学习笔记(自认为详细)

    引入 什么是 \(\text{FFT}\) ? 反正我看到 \(\text{wiki}\) 上是一堆奇怪的东西. 快速傅里叶变换(英语:Fast Fourier Transform, FFT),是快速 ...

  7. Mac安装 Scrapy 报错 No local packages or working download links found for incremental>=16.10.1

    证书原因: wget http://curl.haxx.se/ca/cacert.pem mv cacert.pem ca-bundle.crt sudo mkdir -p /etc/pki/tls/ ...

  8. dynamic + shardingsphere(4.1.1) 实现动态分库分表

    1. 主要依赖: <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-da ...

  9. 2022-7-11 javascript学习 第七组 刘昀航

    ​ JavaScript是什么? 编程语言,脚本语言,依赖于某种容器来运行. JS是运行在浏览器上的,可以帮助我们去控制页面. Vue.js   react.js    jquery.js    an ...

  10. Java基础语法02

    回顾前面的章节,我们学习了(1.注释,2.标识符和关键字,3.数据类型)今天让我们继续加油. 四.变量,常量,作用域1.变量是什么:存数的(可以变化的量) Java是一种强类型语言,每个变量都必须声明 ...