分布式下的请求超时
在日常的生产中,用户往往不在乎你使用的什么样的性能优化的手段,他们更关心地是点击一个按钮后能否立马给予反馈。这个用户等待反馈的时间,就是我们软件设计过程中的用户操作的响应时间。
我们花费心思去优化系统提升系统性能,本质上就是缩短响应时间,从而提升用户体验的满意度。那到底什么样的系统才算得上“流畅丝滑”的呢?
在互联网上对于用户响应时间,有一个普遍的标准,即 2/5/10秒原则 :
当然这个原则也不是固定的,合理的响应时间取决于用户的需求,不是臆想来的。
这里以一个基于SpringCloud搭建的微服务Web为例我们谈一谈有关请求超时的相关配置。
SpringBoot web超时配置
首先我们要知道搭建一个基于SpringBoot的web项目,其运行默认是在其内置的tomcat服务器中,所以探究一个SpringBoot项目的超时时间,要先看tomcat的超时配置。
tomcat服务设置的超时时间(…/conf/server.xml)
<Connector port="8080" protocol="HTTP/1.1” connectionTimeout=“20000" redirectPort="8443" acceptCount="500" maxThreads="400" />
SpringBoot mvc 设置请求超时时间 (application.properties)
SpringBoot的启动容器也是tomcat其超时时间默认也是20s
spring.mvc.async.request-timeout=20s
Spring Cloud 相关的超时设置
Spring Cloud需要设置的超时设置主要有三个部分:
hystrix
ribbon
zuul设置
#默认1000
zuul.host.socket-timeout-millis=2000
#默认2000
zuul.host.connect-timeout-millis=4000
hystrix设置
#断路器的超时时间,下级服务返回超出熔断器时间,即便成功,消费端消息也是TIMEOUT,所以一般断路器的超时时间需要大于ribbon的超时时间。
#服务的返回时间大于ribbon的超时时间,会触发重试
##默认=1000,太小
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=60000
ribbon设置
#ribbon请求连接的超时时间- 限制3秒内必须请求到服务,并不限制服务处理的返回时间
ribbon.ConnectTimeout=3000
#请求处理的超时时间 下级服务响应最大时间,超出时间消费方(路由也是消费方)返回timeout
ribbon.ReadTimeout=5000
数据库相关的配置项
jdbc设置
connectTimeout:表示等待和MySQL数据库建立socket链接的超时时间,默认值0,表示不设置超时,单位毫秒,建议30000
socketTimeout:表示客户端和MySQL数据库建立socket后,读写socket时的等待的超时时间,linux系统默认的socketTimeout为30分钟,可以不设置
jdbc:mysql://127.0.0.1:3306/ceshi?useUnicode=true&characterEncoding=UTF8&connectTimeout=30000&socketTimeout=30000
连接池设置
#连接池在等待返回连接时,最长等待多少毫秒再抛出异常
spring.datasource.max-wait=10000
#连接超时(单位毫秒)
spring.datasource.connection-timeout=20000
#是否自动回收超时连接
spring.datasource.remove-abandoned=true
#超时时间(以秒数为单位)
spring.datasource.remove-abandoned-timeout=180
Mybatis超时设置
defaultStatementTimeout:表示在MyBatis配置文件中默认查询超时间,单位秒,不设置则无限等待
在配置文件中设置全局的sql执行超时时间(单位s):
mybatis.configuration.default-statement-timeout = 1
如果想把粒度更细,比如粒度到某个sql的话,可以在select/insert/update/delete 操作语句中设置 timeout值(单位s)
<select id="getXXXX" parameterType="java.lang.String" resultMap="dataMap" timeout="1">
</select>
当sql执行时间超过1s,就会断开操作了,起到保护数据库服务的作用。
spring 事务超时设置
事务超时用于控制事务执行的超时,执行时间是事务内所有代码执行总和,单位为秒。默认值为-1表示永不超时。
@Transactional(timeout =10 )
总得来说:
我们在进行RPC调用的时候,要充分考虑其调用的超时时间,尽可能要求服务提供者的调用时间,避免因为RPC调用导致请求的连接超时。
由于网络波动、节点异常的原因导致的请求超时,可以采用服务降级的方式,为请求提供兜底的数据响应,避免用户界面处于长时间停顿。
针对那些不需要立马需要响应结果的请求(即异步请求),可以采用线程池、消息中间件等异步方式来进行处理,这样对用户来说更加友好。
缩短用户操作的响应时间有很多种,最常见最有效的方式就是缓存。
