稳定性三十六计-超时处理

引子
分布式系统调用的三态
在传统的单机系统中,调用一个函数,要么返回成功,要么返回失败。这就是两态系统(2-state system)。
在分布式系统中,因为系统是分布在不一样机器上的。还可能有一种状态叫:超时。成功、失败和超时是分布式系统调用的三态。
为何要超时处理
对于超时这种状态,长时间等待会影响用户体验,并发量大时还可能会由于线程池耗尽而不能响应其余请求。若是这个服务的调用方也是一个服务,那就有可能产生级联反应,致使其余服务不可用,最终产生雪崩效应。
 
超时处理的手段
超时处理的两个要点:判断何时超时和超时后怎么处理。
判断何时超时在无基础数据时可经过经验估算一个相对合理值。在服务上线后可依赖统计进行设置,好比设置99%的请求响应时间为超时时间。还能够经过人工智能进行调参来设置。
超时后通常采用快速失败,若是不是核心服务,可直接超时返回失败。若是是核心服务,能够设置相应的重试次数。
 
HTTP请求超时处理
HTTP请求通常会对两个阶段作超时处理:创建链接阶段、数据通讯阶段。在apache的HttpClient实现中,添加了获取链接池阶段。
获取链接池阶段
由于创建链接须要IO、网络带宽等开销,须要池化处理,若是超过了链接池的最大值,则须要等待其余链接执行完释放资源。超时时间通常设置为1s以内。
创建创建阶段
HTTP请求须要“三次握手”,第一次握手客户端发送一个报文到服务器表示想和服务端创建链接。第二次握手是服务端接收到客户端的请求,返回带有同步和相应标记的客户端报文,询问客户端是否准备好。第三次握手是客户端再次响应服务端表示已经准备好。超时时间通常设置为1s到5s。
数据通讯阶段
与目标url创建链接后,等待数据报文传输的时间。这个阶段又叫作socket通讯阶段。这个阶段可能有两种类型的事件:读取和写入。超时时间通常设1s到5s。
在以上三个阶段的任何一个阶段发生超时则当即终止等待返回失败,http请求通常会设置超时后有三次重试。为了进一步理解,能够借助HttpClient的调用代码来感觉一下其使用
    HttpParams httpParams = new BasicHttpParams();
    // 获取链接的最大等待时间1s,对应获取链接池阶段
    ConnManagerParams.setTimeout(httpParams, 1000);
    // 链接超时时间5s,对应创建创建阶段
    HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
    // socket超时时间5s,对应数据通讯阶段
    HttpConnectionParams.setSoTimeout(httpParams, 5000);
最近由于OkHttpClient比HttpClient更简单易用,使用的人多起来。借助OkHttpClient的调用代码来感觉一下其使用
    OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
    // 链接超时时间5s,对应创建创建阶段
    httpClientBuilder.connectTimeout(config.getConnectionTimeout(), TimeUnit.MILLISECONDS);
    // 读取超时时间5s,对应数据通讯阶段(将socket细分为读取和写入两种类型)
    httpClientBuilder.readTimeout(config.getReadTimeout(), TimeUnit.MILLISECONDS);
    // 写入超时时间5s,对应数据通讯阶段(将socket细分为读取和写入两种类型)
    httpClientBuilder.writeTimeout(config.getReadTimeout(), TimeUnit.MILLISECONDS);
读取和写入都是socket阶段的一个证据是若是发生超时,曝出的异常是SocketTimeoutException
 
Mysql链接超时处理
客户端和Mysql链接也分为创建链接和数据通讯两个阶段。目前mysql经常使用的版本是5.6和5.7。
和超时处理相关的参数汇总以下
 
参数名称 参数说明 缺省值 最低版本要求
connectTimeout
和数据库服务器简历socket链接时的超时
单位:毫秒。0表示永不超时
0 3.0.1
socketTimeout
socket操做(读写)超时
单位:毫秒。0表示永不超时
0 3.0.1
autoReconnect 当数据库链接异常中断时是否自动重连 false 1.1
maxReconnects autoReconnect=true时,重试链接的次数 3 1.1
failOverReadOnly 自动重连成功后,链接是否设置为只读 true 3.0.12
autoReconnectForPools 是否使用针对数据库链接池的重连策略 False 3.1.3
 
总结
慢就是错 
 

关于做者mysql

一线开发十二年,有日本东京和美国硅谷研发经验。有百余项技术发明专利,目前任美团点评技术专家。有本身的技术公众号「编程一辈子」。若是您在阅读文章时有什么疑问或者发现文章的错误,欢迎在公众号里给我留言。sql

相关文章
相关标签/搜索