zoukankan      html  css  js  c++  java
  • windows下Socket链接溢出

    最近在windows下使用通过多线程使用jdbc操作数据库,在线程数设置为5,并且每个线程执行完成后Sleep(1000),在这种情况下,竟然还会报错:

    java.net.SocketException No buffer space available (maximum connections reached) JVM_Bind

    一看这个错误类型,应该是属于Socket连接没有关闭或者一直在等待,因为我用的是jdbc去操作数据库,并且是短连接的形式,也即每次执行一个操作就新建jdbc连接,操作完毕即关闭jdbc连接,而jdbc连接是基于Socket的,那么问题应该就出现在jdbc连接数据库上面了,再加上我使用的是原声java编写的程序,并没有用任何框架以及web容器,所以并没有jdbc连接池帮我控制jdbc连接的关闭。经过各种尝试和google,发现可能是windows系统级Socket设置的原因。

    解决方案如下:

    1. 启动注册表编辑器。 HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Tcpip/Parameters

    2. 新建

    值名称:MaxUserPort

    值类型: DWORD

    值数据: 65534(十进制)

    有效范围: 5000 - 65534 (十进制)

    默认: 0x1388 5000 (十进制)

    新建

    值名称:TCPTimedWaitDelay

    值类型: DWORD

    值数据: 30(这个表示TIME_WAIT的秒数)

    其中最重要的是TCPTimedWaitDelay,如果一个Socket连接等待时间超过30秒,就关闭连接。

    再次运行程序,现在将线程数设置为30,程序仍旧能正常运行。

     根据TCP协议定义的3次握手断开连接规定,发起socket主动关闭的一方 socket将进入TIME_WAIT状态,TIME_WAIT状态将持续2个MSL(Max Segment Lifetime),在Windows下默认为4分钟,即240秒,TIME_WAIT状态下的socket不能被回收使用。

        具体现象是对于一个处理大量短连接的服务器,如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于TIME_WAIT状态的socket,甚至比处于Established状态下的socket多的多,严重影响服务器的处理能力,甚至耗尽可用的socket,停止服务。 TIME_WAIT是TCP协议用以保证被重新分配的socket不会受到之前残留的延迟重发报文影响的机制,是必要的逻辑保证。
     
    Linux下的解决办法:
         netstat -ae |grep mysql
    tcp        0      0 aaaa:53045               192.168.12.13:mysql           TIME_WAIT   root       0
    tcp        0      0 aaaa:53044               192.168.12.13:mysql           TIME_WAIT   root       0
    tcp        0      0 aaaa:53051               192.168.12.13:mysql           TIME_WAIT   root       0
    tcp        0      0 aaaa:53050               192.168.12.13:mysql           TIME_WAIT   root       0
    tcp        0      0 aaaa:53049               192.168.12.13:mysql           TIME_WAIT   root       0
    tcp        0      0 aaaa:53048               192.168.12.13:mysql           TIME_WAIT   root       0

    发现系统存在大量TIME_WAIT状态的连接,通过调整内核参数解决,
    vi /etc/sysctl.conf

    编辑文件,加入以下内容:
     

    代码如下:
    net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_fin_timeout = 30

    然后执行 /sbin/sysctl -p 让参数生效。
    net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
    net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
    net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
    net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间
     
    修改之后,再用
    netstat -ae|grep mysql
    tcp        0      0 aaaa:50408               192.168.12.13:mysql           ESTABLISHED nobody     3224651
    tcp        0      0 aaaa:50417               192.168.12.13:mysql           ESTABLISHED nobody     3224673
    tcp        0      0 aaaa:50419               192.168.12.13:mysql           ESTABLISHED nobody     3224675

    发现大量的TIME_WAIT 已不存在,mysql进程的占用率很快就降下来的,各网站访问正常。

  • 相关阅读:
    深入理解JavaScript系列(4):立即调用的函数表达式
    深入理解JavaScript系列(3):全面解析Module模式
    深入理解JavaScript系列(2):揭秘命名函数表达式
    深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点
    深入理解JavaScript系列
    大白话讲解Promise(一)
    《你不知道的JavaScript》整理(二)——this
    Mysql日期时间大全
    Mysql的时间和日期
    mysql命令大全用户管理相关命令
  • 原文地址:https://www.cnblogs.com/edwinchen/p/4206066.html
Copyright © 2011-2022 走看看