前言
其实不只在微服务中,在平常网络请求,或者与第三方系统进行交互都需要设置超时时间
为什么需要超时与重试? 总体上讲,肯定是为了增加系统可靠性,具体表现在两个方面系统自我保护: 快速失败,在业务最大允许等待时间内未收到返回数据,主动放弃等待,释放占用资源,避免请求不断累积带来的客户端雪崩效应
成功率:服务处理超时原因有很多,但常见的超时都是短暂的,主要是GC,或者有网络抖动等。这些短时间影响服务端状态的情况而造成请求成功率下降,需要补救措施。简单的补救有超时重试操作:当前请求超时后,将会重试到非当前服务器,降低重试超时的机率
这一篇将由浅入深探索timeout机制,以及在微服务下的实践超时
经常被提起的两种超时:connection timeout、socket timeout
通过最底层的Socket,ServerSocket演示一下这两种超时的表现,nio框架都会有对应的配置选项
connectionTimeout
建立连接超时时间
客户端,随便写个IP,设置一个timeoutSocket socket = new Socket();
socket.connect(new InetSocketAddress("10.0.0.1",8080),20000);
在timeout时间到时,就会抛出connect timed out异常Exception in thread "main" java.net.SocketTimeoutException: connect timed out
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
socketTimeoutEnable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.
服务端,只要让客户端能连接上就行,不发送数据ServerSocket serverSocket = new ServerSocket(8080);
while ( true) {
Socket socket = serverSocket.accept();
new Thread(new P(socket)).start();
}
客户端,进行读数据Socket socket = new Socket();
socket.connect(new InetSocketAddress("localhost",8080),20000);
socket.setSoTimeout(3000);
3s后,就抛出Read timed outjava.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.Sock