注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

网易杭研后台技术中心的博客

 
 
 
 
 

日志

 
 

超时设置和过载保护一点想法  

来自osdba   2014-01-12 15:38:54|  分类: 开发技巧 |举报 |字号 订阅

  下载LOFTER 我的照片书  |

本文讨论一个最简单的模型,客户端通过TCP访问服务端提供的服务,如下图所示:

C/S模型

一、TCP网络的特点

  1. 发送数据时,如果网络出现问题时,通常能很快检测到网络故障。所以通常发送数据时,可以较少考虑因为网络故障导致发送hang的情况,但需要考虑因对端不接收数据导致发送端hang的问题。
  2. TCP最早设计时,当连接上无业务数据传输时,则TCP连接自己不会有其它数据传送,所以当实际的物理链路断之后,如果没有业务数据传送,这时TCP连接也不会检测到网络中断。虽然现在TCP都提供了keepalive机制,可以发送心跳包,但通常操作系统默认设置的这个心跳时间都过长,基本没有什么用处,如Linux默认为7200秒,即两个小时。
  3. 不同操作系统平台上的keepalive机制提供的API函数都有一些差异。有些平台keepalive可以为不同的连接设置不同的keepalive值,而有些操作系统,则需要全局设置,无法针对某一个连接进行设置,导致无法满足不同的应用需要不同的心跳检测的要求。
  4. 当网络中间出现问题后,可能会出现网络通信的两端,其中一端TCP连接还存在于操作系统中,另一端TCP连接已经不存在的情况。
  5.  当通过kill掉对端进程或关掉对端操作系统等方法测试时,通常TCP的能很快检测到错误,这是因为kill掉进程和关操作系统时,会向对端发送关闭TCP连接的通知,所以对端能很快检测到错误。当拔掉网络时,交换机或操作系统能很快知道网络中断了。这时向这台机器发起的连接请求有可能就会很快返回错误,而真实出现问题时,可能会hang住,没有设置连接超时,不一定能测试出问题,但真正网络出问题时,连接超时就很重要。所以仅通过拔插网线、关操作系统等方法测试程序没有问题时,不等于真正出现网络故障时,你的程序还能稳定运行。

二、有哪些超时需要注意

  1. 客户端连接超时,客户端连接服务端,需要有TCP的连接超时,否则如果网络出现问题,一直处于连接状态,会导致客户端hang住
  2. 客户端发起请求后,等待服务端处理,如果服务端一直不返回或因网络故障导致返回的信息丢失,会导致客户端被hang住。所以客户端应该有请求处理的超时机制。
  3. 服务端接收客户端请求的超时,如果服务端接收到到客户端请求的前半年数据包,那么会等待后半个数据包的到来,如果后半个数据包一直不到达,那么服务端不能一直等下去,需要有一种超时机制。
  4. 服务端的处理请求的超时机制,如果服务端接收到一个请求后,由于某种原因,无法在一定的时间内完成,应该有一种超时机制中止处理。这个超时时间应该与客户端的超时时间相一致。因为如果客户端执行一个操作,超过指定的时间后,客户端已经中止了,而服务端还在执行这个无用的操作,这时如果客户端继续发起新的请求来,很容易把服务端给压死。
  5. 服务端给客户端回送数据时的超时。因为是回送数据,所以通常如果网络出现问题,服务端会很快检测到错误,但如果客户端出现问题,一直不接收数据,这会导致服务端hang住,这也需要设置一个超时。
  6. 客户端连接到服务端之后,一直不发送请求,相当于一直空闲,但不释放TCP连接,服务端一般需要设置空闲连接超时。

所以我们在使用一个服务时,如数据库或其它的服务时,都应该关注软件中以上这些超时的设置。同时,如果我们在开发一个服务时,也应该考虑实现以上这些超时机制。

三、过载保护中的超时设置

  1. 当客户端与服务端建立连接时的连接超时的设置。如连接MySQL中,JDBC的url上可以设置connect_timeout。
  2. 客户端发送请求后,等待服务端返回的超时。通常实现方法是,客户端发起请求的在一个线程中,同时把自已的操作注册到一个超时处理线程中,当超时处理线程中发现超时后,通过一种办法把另一个线程中客户端的请求结束掉,但能否结束掉还要看具体的实现方法。如在MySQL的JDBC中,设置了statment timeout后,到达这个时间后,MySQL JDBC是通过再与服务端建一个连接,然后向服务器发送kill前一个连接的方法结束那个一直没有返回的请求,而如果是网络出现问题时,这个方法不一定可行,所以还需要设置一个socket timeout才行。
  3. 服务端也应该设置服务端处理的超时,因为如果客户端设置的处理超时是10秒,而服务端没有超时,客户端超时结束后可能会重试,这样很快会把服务端的资源耗尽。
  4. 通常服务端有一个请求队列,应该对队列中的请求也做超时处理,因为超过了一定时间,对客户端已经没有意义了,可以直接从队列中删除掉。很多服务在正常的压力下,都能提供正常的服务,但当请求稍稍超时正常范围后,就一点都不能提供服务了,多数原因就是没有设置处理超时,导致服务器端一直在处理客户端已超时的无效请求。
  评论这张
 
阅读(978)| 评论(2)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017