• 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中,是通过设置sendTimeoutrecvTimeout来影响超时的,而且从注释中的单词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很强大,也很成熟,但是好用的文档并不多,如果在项目中遇到问题,求人不如求已,除了啃源码,还是啃源码。 

  • 相关阅读:
    模块
    Queue(队列)
    Stack(栈)
    Vector(容器)
    位图像素的颜色
    大数处理之三(除法)
    大数处理之二(幂运算)
    浮点数(double)的优势
    大数处理之一(加法和乘法)
    Depth-First Search
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/thrift-timeout.html
Copyright © 2020-2023  润新知