首页 > 系统 > Linux > 正文

linux上TCP connection timeout问题解决办法

2019-11-02 16:00:54
字体:
来源:转载
供稿:网友

 linux上TCP connection timeout问题解决办法

最近在产线上经常出现connection timeout的问题,先看看Java 中关于connection timeout 的异常如何产生

JAVA中的timeout

java.net.SocketTimeoutException: connect timed out 客户端异常:connect timed out   at java.net.PlainSocketImpl.socketConnect(Native Method)   at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)   at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)   at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)   at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)   at java.net.Socket.connect(Socket.java:589) 

我们能经常看到的connect timed out异常产生,看一下java 是如何生成这个异常

plainsocketimpl.c 中

while (1) {         jlong newTime; #ifndef USE_SELECT         {           struct pollfd pfd;           pfd.fd = fd;           pfd.events = POLLOUT;            errno = 0;           connect_rv = NET_Poll(&pfd, 1, timeout);         } #else         {           fd_set wr, ex;           struct timeval t;            t.tv_sec = timeout / 1000;           t.tv_usec = (timeout % 1000) * 1000;            FD_ZERO(&wr);           FD_SET(fd, &wr);           FD_ZERO(&ex);           FD_SET(fd, &ex);            errno = 0;           connect_rv = NET_Select(fd+1, 0, &wr, &ex, &t);         } #endif          if (connect_rv >= 0) {           break;         }         if (errno != EINTR) {           break;         }          /*          * The poll was interrupted so adjust timeout and          * restart          */         newTime = JVM_CurrentTimeMillis(env, 0);         timeout -= (newTime - prevTime);         if (timeout <= 0) {           connect_rv = 0;           break;         }         prevTime = newTime;        } /* while */        if (connect_rv == 0) {         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",               "connect timed out");          /*          * Timeout out but connection may still be established.          * At the high level it should be closed immediately but          * just in case we make the socket blocking again and          * shutdown input & output.          */         SET_BLOCKING(fd);         JVM_SocketShutdown(fd, 2);         return;       } 

这里可以看到在做connect的时候,是调用 NET_Poll 或者 NET_Select, 在linux 上就是使用 poll/select

当发生timeout的时候connect_rv=0  ,这里有个注意点虽然在poll/select 是传入timeout的时间,但是这是会被打断的,connect_rv返回的值为-1 ,所以jvm里面重新计算了timeout , 确保timeout 的时间片已经运行完了,才推出循环。

newTime = JVM_CurrentTimeMillis(env, 0);         timeout -= (newTime - prevTime);         if (timeout <= 0) {           connect_rv = 0;           break;         } 

同时设置connect_rv 为0, 也是下面只有当connect_rv为0的时候才抛出connect timeout

什么是connect timeout ?

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表