前言:

之前我们组内部使用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. 「BUAA OO Unit 4 HW16」第四单元总结与课程回顾

    「BUAA OO Unit 4 HW16」第四单元总结与课程回顾 目录 「BUAA OO Unit 4 HW16」第四单元总结与课程回顾 Part 0 第四单元作业架构设计 架构设计概要 AppRun ...

  2. nginx启动失败/报错(bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket...permissions) nginx启动失败

    出现这个问题是因为80端口被占用了 1.cmd输入命令netstat -aon|findstr "80" 2..查看80端口 16356对应的任务 输入命令 tasklist|fi ...

  3. freeswitch拨打分机号源代码跟踪

    概述 freeswitch是一款非常好用的开源VOIP软交换平台. 之前我们有介绍过使用fs拨打分机号的方法,其中代码流程是比较复杂的,所以单独开一章介绍. fs拨打分机号,是使用send_dtmf接 ...

  4. scanf读入与printf输出

    作为一个资深$cin,cout$玩家,在多次因为$cin$太慢被吊打后,开始反思有必要认真地学一下$scanf$和$printf$了$\cdot \cdot \cdot$ 格式 $scanf( &qu ...

  5. JsonPath:针对json的强大的规则解析与参数查找工具

    项目特点 GitHub项目地址:https://github.com/json-path/JsonPath 主要功能: 将Json字符串转为Java Map对象(这个不算什么,FastJson之类的工 ...

  6. Leetcode 1331. 数组序号转换

    给你一个整数数组 arr ,请你将数组中的每个元素替换为它们排序后的序号. 序号代表了一个元素有多大.序号编号的规则如下: 序号从 1 开始编号. 一个元素越大,那么序号越大.如果两个元素相等,那么它 ...

  7. 【百度飞桨】手写数字识别模型部署Paddle Inference

    从完成一个简单的『手写数字识别任务』开始,快速了解飞桨框架 API 的使用方法. 模型开发 『手写数字识别』是深度学习里的 Hello World 任务,用于对 0 ~ 9 的十类数字进行分类,即输入 ...

  8. 五分钟给你的 gRPC服务 加上 HTTP 接口

    gRPC 服务要加 HTTP 接口? go-zero 给大家带来极简的 RESTful 和 gRPC 服务开发体验的同时,社区又给我们提出了新的期望: 我想只写一次代码 既要 gRPC 接口 也要 H ...

  9. CSS面试总结

    文章首次发表:_时雨_CSDN 1. BFC:块级格式化上下文(重点关注) BFC基本概念:BFC是 CSS布局的一个概念,是一块独立的渲染区域(环境),里面的元素不会影响到外部的元素. BFC原理( ...

  10. 多态的好处和instanceof关键字

    多态的好处: 可替换性:多态对已经存在的代码具有可替换性 可扩展性:多态对待吗具有可扩展性,增加新的子类不影响已经存在类的多态性,继承性,以及其他特征的运行和操作.实际上新家子类更容易获得多态功能 接 ...