麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 服務(wù)器 > Linux服務(wù)器 > 正文

linux上TCP connection timeout問題解決辦法

2024-09-05 23:03:47
字體:
供稿:網(wǎng)友

 linux上TCP connection timeout問題解決辦法

最近在產(chǎn)線上經(jīng)常出現(xiàn)connection timeout的問題,先看看Java 中關(guān)于connection timeout 的異常如何產(chǎn)生

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) 

我們能經(jīng)常看到的connect timed out異常產(chǎn)生,看一下java 是如何生成這個(gè)異常

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的時(shí)候,是調(diào)用 NET_Poll 或者 NET_Select, 在linux 上就是使用 poll/select

當(dāng)發(fā)生timeout的時(shí)候connect_rv=0  ,這里有個(gè)注意點(diǎn)雖然在poll/select 是傳入timeout的時(shí)間,但是這是會(huì)被打斷的,connect_rv返回的值為-1 ,所以jvm里面重新計(jì)算了timeout , 確保timeout 的時(shí)間片已經(jīng)運(yùn)行完了,才推出循環(huán)。

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

同時(shí)設(shè)置connect_rv 為0, 也是下面只有當(dāng)connect_rv為0的時(shí)候才拋出connect timeout

什么是connect timeout ?

也就是client 發(fā)出 syn 包,server端在你指定的時(shí)間內(nèi)沒有回復(fù)ack,poll/select 返回0

server 端為什么沒有回復(fù)ack, 因?yàn)閟yn包的回復(fù)是內(nèi)核層的,要么網(wǎng)絡(luò)層丟包,要么就是內(nèi)核層back_log的queue滿了,關(guān)于backlog在本片中就不詳細(xì)描述了。

當(dāng)時(shí)查看產(chǎn)線上的連接最高能到1000多,同時(shí)查看了backlog 的queue的大小

cat /proc/sys/net/ipv4/tcp_max_syn_backlog 

有8192 在產(chǎn)線上沒有這么多的客戶端的連接,不可能backlog queue會(huì)滿,雖然syn_backlog 的設(shè)置是8192 但并不代表服務(wù)器啟動(dòng)的時(shí)候設(shè)置成了8192,所以必須查這個(gè)端口所設(shè)置的backlog大小

ss -lt 

看到Send-Q在8080端口是128 ,原來在服務(wù)器端啟動(dòng)listen 的時(shí)候設(shè)置了128的backlog

查看tomcat 的配置,默認(rèn)bio的設(shè)置

<Connector executor="tomcatThreadPool"       port="8080"          protocol="HTTP/1.1"           acceptCount="5000"           connectionTimeout="25000"           maxHttpHeaderSize="8192"           useBodyEncodingForURI="true"           enableLookups="false"            redirectPort="8443"            URIEncoding="UTF-8"            maxThreads="500"           maxKeepAliveRequests="1000"           keepAliveTimeout="30000"         /> 

產(chǎn)線上已經(jīng)設(shè)置了acceptCount, 默認(rèn)是100 但是這里設(shè)置了是5000 ,這與通過ss看到的send-q的結(jié)果嚴(yán)重不符合
通過內(nèi)核代碼分析,發(fā)現(xiàn)原來內(nèi)核參數(shù)不僅僅是通過tcp_max_syn_backlog控制,同時(shí)也受somaxconn控制
查看

cat /proc/sys/net/core/somaxconn 

發(fā)現(xiàn)值是128, OK 原因找到了,修改/etc/sysctl.conf 添加

net.core.somaxconn = 8192 

sysctl -f /etc/sysctl.conf 重新加載一下,這樣就能改變?nèi)至?/p>

問題:是1000多個(gè)連接,500個(gè)工作線程,因?yàn)閎acklog的大小是受socket.accept控制的,我們通常境況下會(huì)單獨(dú)起一個(gè)線程去serversocket.accept(),而當(dāng)前server的load并不高,不因該會(huì)出現(xiàn)back_log queue出現(xiàn)滿的情況,更何況只有1000多個(gè)連接,代碼就是真相,查看tomcat的源碼。

原來accptor 線程在accept 之前,會(huì)去countUpOrWaitConnection 發(fā)現(xiàn)接受到的的socket數(shù)目大于設(shè)置的work線程數(shù)目的時(shí)候,會(huì)停止accept.

<strong>countUpOrAwaitConnection</strong>();           Socket socket = null;          try {            // Accept the next incoming connection from the server            // socket            socket = serverSocketFactory.acceptSocket(serverSocket);          } catch (IOException ioe) {            countDownConnection();            // Introduce delay if necessary            errorDelay = handleExceptionWithDelay(errorDelay);            // re-throw            throw ioe;          } 

也就是說當(dāng)并發(fā)超過628個(gè)連接以上,就有可能出現(xiàn)backlog queue滿的情況,而出現(xiàn)connect timeout的情況,一切皆清楚了。

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 毛片免费观看视频 | 成人福利软件 | 免费黄色成人 | 少妇一级淫片免费放播放 | 亚洲草逼视频 | 97青青草视频 | 国产免费观看电影网站 | 欧美成人精品欧美一级乱黄 | 男女生羞羞视频网站在线观看 | 亚洲精品一区二区三区在线看 | 欧美日本免费一区二区三区 | 国产资源在线免费观看 | 中国免费黄色 | 在线看一区二区三区 | 国产免费观看视频 | 伊人av影院 | 91综合在线观看 | av在线不卡免费 | 天天干干 | 特级毛片全部免费播放器 | 久久久噜噜噜久久熟有声小说 | 天天草夜夜骑 | 91情侣偷在线精品国产 | 欧美精品v国产精品v日韩精品 | 精品国产91久久久久久久 | 日本黄色不卡视频 | 久久久久国产一区二区三区不卡 | 亚洲视屏 | 一本一本久久a久久精品综合小说 | 国产激情视频在线 | 羞羞的动漫在线观看 | 日韩视频高清 | 国产小视频在线 | 多男操一女视频 | 在线a视频 | 亚洲成人免费网站 | 亚洲精品a级 | 精品亚洲一区二区 | 日本一道aⅴ不卡免费播放 视屏一区 | 国产午夜精品一区二区三区四区 | 国产88久久久国产精品免费二区 |