thrift中的超时(timeout)坑

最近在项目中采用thrift作为后台服务rpc框架,总体用下来性能还不错,跨语言特性使用起来也还行,但是也遇到了一些坑,其中之一就是超时问题(timeout),如果服务端些的某些业务场景耗时较长,thrift client几乎毫无意外的会遇到:Read timed out, 当然解决办法也很容易,thrift client端手动设置一个较长的超时时间即可。

下面才是真正吐槽的开始:

既然号称跨语言,至少各个语言在实现底层功能时,API应该保持一致吧,比如java中的有一个XXXTimeout的属性,php中应该也有这个属性吧,然而并不是这样的,不仅超时设置的方法名(属性名)不同,连TMD的时间单位都不一致。

而且这种问题,几乎在网上也查不到资料,只能查看源码,在thrift源码(目前最新的是0.9.3)的lib包下,有名种语言的实现,可以找几个来瞅瞅:

 

php版:

文件位置:thrift-0.9.3/lib/php/lib/Thrift/Transport/TSocket.php

 1   /**
 2    * Send timeout in seconds.
 3    *
 4    * Combined with sendTimeoutUsec this is used for send timeouts.
 5    *
 6    * @var int
 7    */
 8   private $sendTimeoutSec_ = 0;
 9
10   /**
11    * Send timeout in microseconds.
12    *
13    * Combined with sendTimeoutSec this is used for send timeouts.
14    *
15    * @var int
16    */
17   private $sendTimeoutUsec_ = 100000;
18
19   /**
20    * Recv timeout in seconds
21    *
22    * Combined with recvTimeoutUsec this is used for recv timeouts.
23    *
24    * @var int
25    */
26   private $recvTimeoutSec_ = 0;
27
28   /**
29    * Recv timeout in microseconds
30    *
31    * Combined with recvTimeoutSec this is used for recv timeouts.
32    *
33    * @var int
34    */
35   private $recvTimeoutUsec_ = 750000;

在php中,是通过设置sendTimeout及recvTimeout来影响超时的,而且从注释中的单词microseconds可以看出,时间单位为『微秒』,但同样在这个文件中,继续向下看,

 1   /**
 2    * Sets the send timeout.
 3    *
 4    * @param int $timeout  Timeout in milliseconds.
 5    */
 6   public function setSendTimeout($timeout)
 7   {
 8     $this->sendTimeoutSec_ = floor($timeout / 1000);
 9     $this->sendTimeoutUsec_ =
10             ($timeout - ($this->sendTimeoutSec_ * 1000)) * 1000;
11   }
12
13   /**
14    * Sets the receive timeout.
15    *
16    * @param int $timeout  Timeout in milliseconds.
17    */
18   public function setRecvTimeout($timeout)
19   {
20     $this->recvTimeoutSec_ = floor($timeout / 1000);
21     $this->recvTimeoutUsec_ =
22             ($timeout - ($this->recvTimeoutSec_ * 1000)) * 1000;
23   }

到了真正设置的地方,按注释上的描述,又换成了milliseconds(毫秒),不明白为啥要这么折腾,php不太懂,根据http://blog.csdn.net/zf2371752658/article/details/40148399 这篇文章中的1楼回复来看,正确的理解应该是微秒。

 

c#版:

文件位置:thrift-0.9.3/lib/csharp/src/Transport/TSocket.cs

1         public int Timeout
2         {
3             set
4             {
5                 client.ReceiveTimeout = client.SendTimeout = timeout = value;
6             }
7         }

干脆就全统一成Timeout这一个属性了,而且没给任何注释说明什么时间单位。

 

java版:

文件位置:thrift-0.9.3/lib/java/src/org/apache/thrift/transport/TSocket.java

 1   /**
 2    * Sets the socket timeout and connection timeout.
 3    *
 4    * @param timeout Milliseconds timeout
 5    */
 6   public void setTimeout(int timeout) {
 7     this.setConnectTimeout(timeout);
 8     this.setSocketTimeout(timeout);
 9   }
10
11   /**
12    * Sets the time after which the connection attempt will time out
13    *
14    * @param timeout Milliseconds timeout
15    */
16   public void setConnectTimeout(int timeout) {
17     connectTimeout_ = timeout;
18   }
19
20   /**
21    * Sets the socket timeout
22    *
23    * @param timeout Milliseconds timeout
24    */
25   public void setSocketTimeout(int timeout) {
26     socketTimeout_ = timeout;
27     try {
28       socket_.setSoTimeout(timeout);
29     } catch (SocketException sx) {
30       LOGGER.warn("Could not set socket timeout.", sx);
31     }
32   }

又拆成了3个成员:Timeout,ConnectTimeout,SocketTimeout了,时间单位从注释上看,是毫秒。

 

js版:(你没有看错,thrift client还支持node js/javascript)

文件位置:thrift-0.9.3/lib/js/src/thrift.js

通篇全文查找,也没到关于"timeout"的内容

 

个人猜测:造成这种乱象的原因是不同语言的客户端实现,是由不同团队完成的,每个团队各自为阵,没有一个上层的牵头人来强制约束API规范。

 

结论:thrift很强大,也很成熟,但是好用的文档并不多,如果在项目中遇到问题,求人不如求已,除了啃源码,还是啃源码。 

时间: 2024-10-18 16:37:07

thrift中的超时(timeout)坑的相关文章

jQuery.form.js插件不能解决连接超时(timeout)的原因分析及解决方法_jquery

jQuery.form.js是一个form插件,支持ajax表单提交和ajax文件上传. 最近在使用jquery.form.js提交包含文件的表单时,碰到了一个问题:当碰上网速较慢时,而我们又设置了timeout时,例如: var options = { timeout: 3000 //限制请求的时间,当请求大于3秒后,跳出请求 } 我们的页面会死在这里,贴上F12开发者工具返回的结果: 此时,我们并没有处理错误的回调函数,而百度出来的例子中也只有这两个回调函数: beforeSubmit: s

PHP中捕获超时事件的方法实例

 这篇文章主要介绍了PHP中捕获超时事件的方法实例,本文直接给出示例代码,需要的朋友可以参考下     set_error_handler()不能捕获致命错误(具体错误类型见手册). 所以需要如下方法: ? 1 2 3 4 5 6 7 8 9 <?php ini_set ( 'max_execution_time', 1 ); function shutdown() { $a = error_get_last (); print_r ( $a ); } register_shutdown_fun

详解Bypass UAC过程中踩过的坑(第一部分)

本文讲的是详解Bypass UAC过程中踩过的坑(第一部分),我目前正在尝试对Chrome沙盒进行一些改进.而作为其中的一部分,我现在正在对我的沙盒攻击Surface 分析工具进行更新,因为我想衡量我对Chrome做的事情是否具有实际的安全性.但事实上当我在进行这一切时,我一直躲不开绕过UAC的麻烦,这就导致进程出现了问题.所以为了顺便演示下我以前在UAC绕过的博文中所讲的,我决定将这一切再来一次.当我完成这一切的时候,我将使用最新版本的NtObjectManager  Powershell模块

详解Bypass UAC 过程中踩过的坑(第二部分)

本文讲的是详解Bypass UAC 过程中踩过的坑(第二部分),在第1部分完成后,我们知道普通用户在拆分令牌管理登录中处理可以获得对升级进程的Terminate,QueryLimitedInformation 和  Synchronize进程访问权限的访问.这是由于正常的用户和管理员具有默认DACL,该默认DACL授予对同一桌面上所有令牌设置的当前登录会话的执行访问权限.我们接下来的问题是如何才能提升你的权限? 在我们拥有的3个访问权限中, Terminate 和 Synchronize 都不是

iOS开发中 经常遇到的坑,看我就够了! 韩俊强的博客

        从事iOS开发有些年月了,从最开始的磕磕绊绊,不知所措,到现在的遇到困难都能快速做出最佳方案处理,中间经历了不可或缺的痛苦.在项目开发中,本人有用印象笔记记录的习惯,所以很多重复出现的坑,很快迎刃而解,而不在同一个地方摔倒两次.为此,特意总结了一下开发中经常遇到的坑,有些可能和你形成共鸣,有些在你看来或许是小儿科,不喜勿喷. 1.XCode8的项目在xcode7运行报错: The document "ViewController.xib" requires Xcode

Javascript之旅——第四站:parseInt中要注意的坑

原文:Javascript之旅--第四站:parseInt中要注意的坑   前些天信用卡站点要接入一个新功能,不过还真比较坑爹,asp站点,大家都知道信用卡的背面是有一个有效期的,在对接银行中这个信息 一定是要传给银行做数据校验,用户在语音输入信用卡有效期后,系统会做一个有效期判断,为了不必要的麻烦,就是判断过期时间一定不能在 一个月内,由于输入的年月日在三个文本框中,再加上我嫌转成时间麻烦,就索性直接拿年,月,日的文本内容直接强转成int类型来判断,此为 背景. 说了这么多,终于说到文章主题了

Tomcat在Eclipse中启动超时的问题解决

具体现象就是eclipse在启动tomcat时, 会报错: "Timeout waiting for Tomcat v6.0 Server @ localhost to start. Server did not start after 45s" 的错误. 尤其是在debug时更加容易出现这 个问题. 通过错误提示来看, 是因为tomcat启动时间超过了45m, 于是被终止了启动.出现这个问题, 可能是应用程序比较庞大, 有很多启动加载项和初始化工作, 或者log太多.想着加大tomc

解决shell、perl及ssh脚本中的超时问题

大家有时候执行一个脚本,因为脚本中有些程序的假死和超时,影响了我们对下一步的判断.随意我们有必要设置对函数和进程的超时设置,让他在一段时间没有反应后,return一个状态. 在命令参数里ssh -o ServerAliveInterval=60  这样子就能控制到60秒. 比如ClientAliveInterval=15,ClientAliveCountMax=3,那就会在15秒发送一次,30秒发送一次,45秒发送一次,如果三次都失败,收回这个链接 但是这个参数不是太好用,大家可以后面加个 sl

node.js超时timeout详解_node.js

如果在指定的时间内服务器没有做出响应(可能是网络间连接出现问题,也可能是因为服务器故障或网络防火墙阻止了客户端与服务器的连接),则响应超时,同时触发http.ServerResponse对象的timeout事件. response.setTimeout(time,[callback]); 也可以不在setTimeout中指定回调函数,可以使用时间的监听的方式来指定回调函数. 如果没有指定超时的回调函数,那么出现超时了,将会自动关闭与http客户端连接的socket端口.如果指定了超时的回调函数,