服务端Too many open files解决方案

2023-11-08

服务端Too many open files解决方案  

转自:http://zhumeng8337797.blog.163.com/blog/static/1007689142012428104618670/

cat /proc/sys/fs/file-nr 

近期系统上线,发现了一个很奇怪的问题,服务端运行没多久就出现页面打不开的现象,查看日志发现大量Too many open files,每台服务器以100MB/s的日志写入速度增加,没多久,每台服务器的日志都纷纷突破了10GB,显然连接数太大,服务器撑不住了,日志截图如下
< xmlnamespace prefix ="v" ns ="urn:schemas-microsoft-com:vml" />< xmlnamespace prefix ="o" ns ="urn:schemas-microsoft-com:office:office" />
 
 看到这样的景象,当然是首先逐台停止服务器(目前我们使用的是
Tomcat),删除日志,然后启动,但是这样显然维持不了很久又会出现相同的问题,为了不影响用户使用,当然需要两步一起走!
1、      逐台停止Tomcat,删除日志,增大系统可打开的文件连接数,启动Tomcat,恢复服务,保障用户服务正常!
2、      尽可能快的查出问题原因,从根源上解决问题。
那么,首先第一步,查看系统当前连接数是多少?使用命令ulimit –a查看
 
 显然,当前的
1024不能满足我们的需求,因此我们需要加大,Linux连接数最大为65536,我们就暂时设置为最大,让服务器多撑一会,给我们第二部的兄弟排查问题准备足够的时间,设置有很多方法,我在这里列举2种
1、  ulimit -n 65536,上图中已经提示我们使用-n查看对应的连接数,-n + value设置对应的数据值。如下截图所示
 
 这种设置方式非常方便快捷,但是这种设置只对当前登录用户的目前使用环境有效
,系统重启或者用户退出后就会失效。要想永久改变对应的值,需要采用第二种方案
2、  vim /etc/security/limits.conf 进行设置
修改/etc/security/limits.conf(里面有很详细的注释哦),在最下方添加
* soft nofile 65536
* hard nofile 65536
保存即可,这时候,需要重启Tomcat才生效
 
 这时候,使用
umilit –a 或者 ulimit –n查看的时候仍然是1024 当你退出重新登录以后就显示正常了(注意Tomcat要重启哦)
重新登录之前
 
 执行
exit 和login之后
 
 这样,按照之前的速度,还能多撑一个小时左右。
接下来就要彻查问题到底是出在什么地方了,继续监控Tomcat发现,Tomcat抛出了很多异常can't identify protocol,并且都是进程Java(即Tomcat的进程)抛出的,下面的问题就是can't identify protocoll是什么?是如何产生的?以前为何没有见过这个异常!
(注:使用lsof |grep java |grep 'identify protocol'查看Tomcat抛出的can't identify protocol错误数。)网上查询资料,发现can't identify protocol属于网络协议包丢失或者泄漏导致,以下是一段参考资料
问题定位步骤:
1、 用root帐户 遍历 /proc/进程ID/fd目录,如果该目录下文件数比较大(如果大于10,一般就属于socket泄漏),根据该进程ID,可以确认该进程ID所对应的名称。
2、 重启程序恢复服务,以便后续查找问题。
3、 strace 该程序并记录strace信息。strace –p 进程ID >>/tmp/stracelog.log 2>&1
4、 查看 /proc/进程ID/fd 下的文件数目是否有增加,如果发现有增加,记录上一个socket编号,停止strace
5、 确认问题代码的位置。打开/tmp/stracelog.log,从尾部向上查找close(socket编号)所在行,可以确认在该次close后再次创建的socket没有关闭,根据socket连接的server ip可以确认问题代码的位置。
另一种方法:判断是否有socket泄漏:
lsof | grep "can't identify protocol"
如果存在很多,则代表socket泄漏,同时会显示哪个进程使用的sock未关闭。
 
 也就是说,他使用了某个网络,但是这个网络发起了很多请求,却一直没有断开连接,怎么会造成这种现象的呢?但是值得肯定的是一定是向某个机器发起了请求但是却没有响应并且没有断开!
1、  接口调用,显然不会,接口都设置了半分钟超时,没有相应会自动断开,并且接口调用没有这么频繁,也不会这么快做重试操作!排除(X)
2、  数据库连接池,对于数据库来说,一般都设置了数据库连接池,也就是说最多创建多少个连接,每次从连接池中取数据,不可能有这么大的连接量!并且在机器重启后和刚开始系统服务正常,说明数据库连接正常,即便是数据库的问题,也是某些数据导致了异常,但是被限定于数据库连接池的大小,用监控发现,基本上这种车错误以5个/s的速度增长,而数据库连接不可能有这么大的量!排除(X)
3、  消息中间件,消息中间件采用ActiveMQ的方式进行异步通讯,设置有自动重连机制,并且使用长连接,有可能发生连不上重连的问题,但是消息中间件只要用于短信认证、邮件认证、订单交易的使用,不可能这么均匀的增长,并且查询数据库,当时的数据量也很小,检查消息中间件,工作正常,监控过程中有消息接受和消费,因此排除(X)
4、  缓存中间件,缓存中间件采用memcache做服务端存储,使用同步机制通讯,设置有自动重连机制,也有可能导致重连连不上一直连接的问题,排查缓存服务器,端口服务正常,但是发现了一块很奇怪的问题,缓存中的数据只有很少一部分,按照之前设计的,很多数据通过缓存存取,再查缓存命中率,发现近乎100%不命中,显然是缓存除了问题,但是服务正常,为何数据却没有写入的呢?于是马上入手,检查服务器到缓存的网络链路,发现是通的,那就是程序没有连接到这台机器上了,继续排查程序的配置文件,终于真相大白了,原来配置文件配置错误!连接的是研发环境的一台缓存服务器,而不是对应的服务器,而程序包通过AutoConfig推送,导致所有的分布式机器配置文件都是错误的(分布式为了更好的自动化部署机器,使用淘宝的AutoConfig处理配置文件一致的问题),每次系统先从缓存服务器取数据,如果取不到对应的数据则直接从DB取数据,从DB取完成数据后将数据缓存的对应的缓存服务器,但是此时缓存服务器不通,因此就产生可一个长连接失效的错误can't identify protocol,而memcache客户端又不停的尝试连接memcache(因为memcache是长连接),最终导致了大量的can't identify protocol产生,而大量can't identify protocol的产生导致了系统文件连接数过多,系统连接数过多在直接影响了Socket连接的打开与关闭,最终导致了系统的无法响应!命中(√)
问题找到了,修改就变得很简单了,修改为对的配置,重启Tomcat,果然can't identify protocol消失了,系统相应快了很多!
问题是解决了,但是有个很严重的问题,之前用的memcache客户端连不上主服务器的时候会抛出Socket异常,现在为什么不会了呢?还需要继续查找!

    今天发现运行好好的J2EE项目突然访问很慢,查看了一下日志报web.xml(Too many open files),google了一下发现时文件句柄数目不够所致。

    查看下一系统当前最大文件句柄数ulimit -n 得出为1024。对应一般应用1024够用了,但是对于像mysql、java等单进程处理大量请求的应用来说就有点捉襟见肘了。如果单个进程打开的文件句柄数量超过了系统定义的值,就会提到“too many files open”的错误提示。如何查看当前打开了多少文件句柄。执行:lsof -n |awk '{print $2}'|sort|uniq -c |sort -nr|more 。得出如下结果

[c-sharp]  view plain copy
  1. 697 30635  
  2. 155 14719  
  3.  95 2763  
  4.  73 2747  
  5.  70 20029  
  6.  70 18005  
  7.  69 24950  
  8.  69 24512  
  9.  69 24493  
  10.  69 24491  
  11.  69 23274  
  12.  69 18353  
  13.  68 24510  
  14.  68 24445  
  15.  68 23411  
  16.  68 23409  
  17.  68 23405  
  18.  68 23367  

这里我只截取了部分输出信息。其中第一行是打开的文件句柄数,第二行是进程号。执行ps -ef | grep 进程号 可查看进程的详细信息。

 

通过执行ulimit -HSn 4096 增大文件句柄数。这时候再执行ulimit -n发现已经变成4096了。

 

 

修改文件句柄数对所有用户都起作用

修改/etc/security/limits.conf,在文件末加上

* soft nofile 4096

* hard nofile 4096


前段时间帮助公司解决了一次tomcat环境服务器的异常,今天有时间过来总结一下。

 

问题的表现:

tomcat服务在重启之后,短时间内会承受大量访问,由于这个时候缓存还没建立,每次访问都将消耗一定资源(数据库连接或者文件IO),并发量在2000左右的时候tomcat服务开始抛出大量Too Many Open Files的异常,主要是文件IO一块的异常,数据库连接池配置恰当就不会抛异常。

 

问题分析:

这是一个典型的文件句柄耗尽的异常,在linux里头“一切皆文件”,所以虽然提示“文件”打开太多,其实也有可能是socket打开太多或者设备打开太多。

 

文件句柄是用来干嘛的?

 

[c-sharp]  view plain copy print ?
  1. 句柄当做一个人的名字,并"可以通过名字(句柄),实现对句子的引用和访问",感觉这种比喻好象贴近,但问题是可能有许多人叫同一个名字,但句柄所以有意义正因为它具有唯一性,所以这种比喻也有问题,如果换个说法,说句柄是表示你的进程与外界的i/o连接,把它当作是一个连接的名字是不是更恰当些? 文件句柄是一个十六位长度的二进制代码(Windows95后为32位无符号整数),代表一个已被打开文件的通道号,借助于这个句柄,你的应用程序即可使用这个相应的句柄对文件进行随意存取操作,说白了文件句柄其实是一串代表着特殊含义的号码; 当然其实系统是用句柄与一些资源联系起来的,当由系统管理,动态分配给你应用程序的某些资源的代号,你就可以使用句柄访问相应的资源了,尤其在Windows系统中,有很多东东都使用句柄,如窗口,socket。  

简单看来程序通过句柄获得资源的引用,来进行资源的打开和关闭的操作。

 

为什么会出现文件句柄耗尽的情况?

 

主要是因为linux在文件句柄的数目上有两个级别的限制。

一个是系统级别的总数限制,

一个是针对用户的限制。


默认情况下每个用户所能使用的句柄数是1024。一般情况下1024也够用了,但是在大容量的系统上,特别是会频繁使用网络通信和文件IO的系统上,1024很快就被耗光了。所以首先我们要调整这个值。修改方法如下:

[c-sharp] view plain copy print ?
  1. 1. ulimit -a 查看当前用户的文件句柄限制  

  2. 2. 用户级别的句柄数限制修改。  
  3. 修改 /etc/security/limits.conf 增加下面的代码:  
  4. 用户名(或者用*表示所有用户)  soft nofile 65535    
  5. 用户名 hard nofile 65535   
  6. 有两种限制,一种是soft软限制,在数目超过软限制的时候系统会给出warning警告,但是达到hard硬限制的时候系统将拒绝或者异常了。  
  7. 修改之后可能需要重启shell生效。  

  8. 3. 系统级别的句柄数限制修改。  
  9. sysctl -w fs.file-max 65536  
  10. 或者  
  11. echo "65536" > /proc/sys/fs/file-max  
  12. 两者作用是相同的,前者改内核参数,后者直接作用于内核参数在虚拟文件系统(procfs, psuedo file system)上对应的文件而已。  
  13. 可以用下面的命令查看新的限制  
  14. sysctl -a | grep fs.file-max  
  15. 或者  
  16. cat /proc/sys/fs/file-max  
  17. 修改内核参数  
  18. /etc/sysctl.conf  
  19. echo "fs.file-max=65536" >> /etc/sysctl.conf  
  20. sysctl -p  
  21. 查看系统总限制 命令:cat /proc/sys/fs/file-max    
  22. 查看整个系统目前使用的文件句柄数量命令:cat /proc/sys/fs/file-nr   
  23. 查看某个进程开了哪些句柄 :lsof -p pid    
  24. 某个进程开了几个句柄 :lsof -p pid |wc -l    
  25. 也可以看到某个目录 /文件被什么进程占用了,显示已打开该目录或文件的所有进程信息 :lsof path/filename   

 

具体这个值应该设置成多少?

优先级(Open File Descriptors):
soft limit < hard limit < kernel < 实现最大file descriptor数采用的数据结构所导致的限制

 

其实这个值倒是没有具体限制,但是分配的值如果太大反而会影响系统性能,所以要根据具体应用调配权衡。

 

问题的解决方案:

首先当然是修改linux句柄数限制到一个合适的值。

然后就是应用本身的一个调整。有这么几种情况:

1.数据库连接池的优化。必须要使用连接池,否则句柄没耗光数据库就崩了。。。

2.抓取资源的时候有可能会用到HttpClient,尽量也应该使用连接池来控制连接数。

关于HttpClient的连接池配置可以查看我另外一文:http://blog.csdn.net/shootyou/archive/2011/05/12/6415248.aspx

3.连接池设置的把握,建立连接超时时间,读取超时时间,连接数目,等待时间,等都需要配置到一个合适的值,否则发挥不出连接池的性能。

 

一个负载比较重的discuz论坛服务器,1小时在线一万多,有时访问时无法显示。


我用另一台同网段的机器作测试,大概20次中会有1、2次超时


wget http://bbs.xxx.com
--17:06:08--  http://bbs.xxx.com/
正在解析主机 bbs.xxx.com... 221.13.18.b
Connecting to bbs.xxx.com|221.13.18.b|:80... 失败:连接超时。
重试中。
在bbs上用tcpdump监控


正常时可以接收到
......
17:27:55.746530 IP 221.13.18.a.39495 > 221.13.18.b.http: . ack 193785 win 353
17:27:55.746923 IP 221.13.18.a.39495 > 221.13.18.b.http: . ack 196705 win 353
17:27:55.747276 IP 221.13.18.a.39495 > 221.13.18.b.http: F 128:128(0) ack 197467 win 353
17:27:55.747284 IP 221.13.18.b.http > 221.130.185.a.39495: . ack 129 win 12

如果wget失败就监控不到信息,问下怎么回事?
检察了net.ipv4.tcp_max_syn_backlog 应该足够了


系统信息
======================================
centos 5.2 64bit
nginx+php+mysql

nginx 4个进程
php 96个进程


Linux bora 2.6.18-128.el5 #1 SMP Wed Jan 21 10:41:14 EST 2009 x86_64 x86_64 x86_64 GNU/Linux


sysctl内核
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_max_syn_backlog = 65536
net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768
net.ipv4.tcp_max_tw_buckets = 5000
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 196608 262144 393216
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 120
net.ipv4.ip_local_port_range = 1024  65535
net.ipv4.tcp_syncookies = 1


优化文件句柄
vi /etc/security/limits.conf
* soft nofile 51200 
* hard nofile 51200


vi /etc/rc.local
ulimit -SHn 51200 


===================
Active connections: 2419 
server accepts handled requests
73668795 73668795 232420556 
Reading: 11 Writing: 28 Waiting: 2380 



bbs在线会员 - 总计 13433 人在线

top - 13:29:01 up 33 days, 22:53,  2 users,  load average: 1.22, 1.60, 
Tasks: 265 total,   1 running, 264 sleeping,   0 stopped,   0 zombie 
Cpu(s):  9.3%us,  1.4%sy,  0.0%ni, 88.2%id,  0.5%wa,  0.0%hi,  0.6%si, 
Mem:   8168412k total,  6691148k used,  1477264k free,   917728k buffe 
Swap:  4096532k total,      228k used,  4096304k free,  3841696k cache


netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 4845
SYN_SENT 1
FIN_WAIT1 185
ESTABLISHED 2698
FIN_WAIT2 381
SYN_RECV 162
CLOSING 5
LAST_ACK 137


netstat -n |wc -l
8441


cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max
65536


cat /proc/sys/fs/file-nr
4590    0       765985

proc/sys/fs/file-nr 
该文件与   file-max   相关,它有三个值: 


        *   已分配文件句柄的数目 
        *   已使用文件句柄的数目 
        *   文件句柄的最大数目   

该文件是只读的,仅用于显示信息。

典型的,提供大量静态文件访问的web服务器,缓存服务器(如squid), 均要注意这个问题


网上的教程,大约只是简单说明了如何设置ulimit和file-max, 但并没有说清楚这两者之间的差别,让人一头雾水


1. file-max的含义

man proc,可得到file-max的描述:

/proc/sys/fs/file-max
              This  file defines a system-wide limit on the number of open files for all processes.  (See
              also setrlimit(2),  which  can  be  used  by  a  process  to  set  the  per-process  limit,
              RLIMIT_NOFILE,  on  the  number  of  files it may open.)  If you get lots of error messages
              about running out of file handles, try increasing this value:

即file-max是设置
 系统所有进程一共可以打开的文件数量 。同时一些程序可以通过setrlimit调用,设置每个进程的限制。如果得到大量使用完文件句柄的错误信息,是应该增加这个值。


也就是说,这项参数是系统级别的。


echo  6553560 > /proc/sys/fs/file-max

或修改 /etc/sysctl.conf, 加入

fs.file-max = 6553560 重启生效


2. ulimit的

Provides control over the resources available to the shell and to processes started by it, on systems that allow  such control.


即设置当前shell以及由它启动的进程的资源限制。


显然,对服务器来说,file-max, ulimit都需要设置,否则就可能出现文件描述符用尽的问题,为了让机器在重启之后仍然有效,强烈建立作以下配置,以确保file-max, ulimit的值正确无误:


1. 修改/etc/sysctl.conf, 加入

fs.file-max = 6553560


2.系统默认的ulimit对文件打开数量的限制是1024,修改/etc/security/limits.conf并加入以下配置,永久生效

* soft nofile 65535 
* hard nofile 65535


修改完之后,重启即可生效



一、查看最大打开文件数

1、查看系统及最大打开文件数

  1. [root@localhost ~]# cat /proc/sys/fs/file-max
  2. 65535

2、查看当前用户最大打开文件数

  1. # ulimit -Hn //查看硬限制
  2. # ulimit -Sn //查看软限制

二、设置最大打开文件数

1、系统及的设置

  1. # vi /etc/sysctl.conf

增加:

  1. fs.file-max = 100000

立即生效:

  1. # sysctl -p

2、用户级设置

  1. vi /etc/security/limits.conf

设置如下:

  1. httpd soft nofile 4096
  2. httpd hard nofile 10240

httpd是用户,可以使用通配符*表示所有用户。
要使 limits.conf 文件配置生效,必须要确保 pam_limits.so 文件被加入到启动文件中。
查看 /etc/pam.d/login 文件中有:

  1. session required /lib/security/pam_limits.so

使用如下命令立即生效:

  1. # su - httpd
  2. $ ulimit -Hn 10240
  3. $ ulimit -Sn 4096
  1. 1、查看进程:ps -ef|grep [java、tomcat、weblogic]  
  2. 2、查看某端口TCP连接占用数:netstat -pnt | grep :6666 |wc -l  
  3. 3、查看某端口TCP连接占用信息:lsof -i :6666  
  4. 4、查看TCP连接状态以及数量:netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'  
  5. 5、查看所有进程占用的文件句柄数:lsof -n|awk '{print $2}'|sort|uniq -c |sort -nr|more  
  6. 6、查看某进程所属服务:ps -aef|grep 24204  

我的网站刚上线的时候过不了半天就会出现如下错误: 
Service Temporarily Unavailable 
The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later. 

这种错误就是503.看到这种错误,第一想法就是BAIDU了.找到了一些解决方法!各家都有各自的意见和解决办法! 

首现谈谈网站的环境和配置. 

1、服务器WIN2003, 

2、TOMCAT5.5和APACHE2.2 

3、数据库是MSSQL2000 

差不多就这样了! 

看到这个办法,在服务器上测试,输入 http://localhost:8080/index.do 可以运行,但是输入 http://locahost/index.do 不行,出现503错误,怀疑中,怀疑1:TOMCAT和APAHCE通信出错. 

我的TOMCAT和APACHE的通信配置如下: 

在APACHE 

1、下载mod_jk-apache-2.2.4.so,把它放在APACHE目录下的modules下 

2、配置APACHE, 

LoadModule jk_module modules/mod_jk-apache-2.2.4.so 
JkWorkersFile "E:/Tomcat 5.5/conf/workers.properties" 
JkLogFile "E:/Tomcat 5.5/mod_jk2.log" 
JkLogLevel info 

3、在TOMCAT下的conf目录建立workers.properties文件,在文件中添加内 

ThreadsPerChild 100 
MaxRequestsPerChild 1000 
MaxMemFree 16 
ThreadLimit 100 
ThreadStackSize 8192 
KeepAliveTimeout 2 
MaxKeepAliveRequests 10 
Win32DisableAcceptEx 

认真看了一下,和在网上看了一些配置,差不多和我这个差不多,但是没有出错,本地测试也没有出错. 

看看APACHE出错的日志文件(error.log)其中出现了: 

[warn] (OS 64)指定的网络名不再可用. : winnt_accept: Asynchronous AcceptEx failed.和 

[warn] (OS 10038)在一个非套接字上尝试了一个操作. : setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed. 

是APACHE配置还有问题:在网上找了一下,好多人出现这个问题:大多数都是这样解决的,我也开始尝试.在APACHE中加入如下: 


ThreadsPerChild 100 
MaxRequestsPerChild 1000 
MaxMemFree 16 
ThreadLimit 100 
ThreadStackSize 8192 
KeepAliveTimeout 2 
MaxKeepAliveRequests 10 
Win32DisableAcceptEx 

重启TOMCAT和APACHE,可以用了,还认为解决了,但是过了一些时间,又出现503错误了,看来不是通信有错误,只要重启TOMCAT就好了,又查看APACHE日志文件,没有出现错误!此时又产生了一个怀疑,怀疑2:难道是TOMCAT和数据库的连接有问题. 

我网站开发的框架是(STRUTS和HIBERNATE和SPRING) 

难道是连接池的原因: 

以前是用DBCP配置的,在网上有人说这个有时候会出错,换了C3P0测试,问题依旧, 

我在WEB.XML中配置了OpenSessionInViewFilter 


 OpenSessionInViewFilter 
  
  org.springframework.orm.hibernate3.support.OpenSessionInViewFilter 
  
  
  singleSession 
  true 
  



 OpenSessionInViewFilter 
 /* 


难道是这个问题,找了一下,发现也有人出现这种情况引起了503错误.解决办法:在web.xml中加入如下配置 
  org.springframework.web.util.IntrospectorCleanupListener 


感觉可以了,充满希望重启TOMCAT,过了一阵子又出现503了,现在差不多崩溃了!怎么办,然后问了我同学(老廖)在这要特别感谢老廖和他的老大.给了我一些建.现在就轮到查TOMCAT的配置了. 

怀疑3:TOMCAT配置有问题. 

看了一下环境变量没有问题,看了一下没有错, 

看了一下TOMCAT的日志文件,出现了好多 

2008-10-22 12:00:09 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable run 
严重: Caught exception (java.lang.OutOfMemoryError: Java heap space) executing org.apache.jk.common.ChannelSocket$SocketConnection@45b409, terminating thread 
2008-10-22 12:00:17 org.apache.commons.modeler.BaseModelMBean setManagedResource 
严重: Can’t set model mbean 
java.lang.OutOfMemoryError: Java heap space 
2008-10-22 12:00:23 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable run 
严重: Caught exception (java.lang.OutOfMemoryError: Java heap space) executing org.apache.jk.common.ChannelSocket$SocketAcceptor@1931ec, terminating thread 

在网上查了一下是JVM内存泄漏引起TOMCAT昏厥,解决办法加大JVM内存,加入的办法如下:在catalina.bat加入一句 

set JAVA_OPTS=-Xms256m -Xmx1024m %JAVA_OPTS% 

把JVM的内存最大加到了1024M,哈,但是我的TOMCAT是安装版的,没有找到这个文件,只好另想办法.在tomcat5w.exe中有一个JAVA选项,那里就有设置最大和最小值的内存,看想是解决了.重启试一下.过了三天,没有出错了,网站运行正常,难道我解决了! 

netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'

会得到类似下面的结果,具体数字会有所不同:

LAST_ACK 1
SYN_RECV 14
ESTABLISHED 79
FIN_WAIT1 28
FIN_WAIT2 3
CLOSING 5
TIME_WAIT 1669

状态:描述
CLOSED:无连接是活动的或正在进行
LISTEN:服务器在等待进入呼叫
SYN_RECV:一个连接请求已经到达,等待确认
SYN_SENT:应用已经开始,打开一个连接
ESTABLISHED:正常数据传输状态
FIN_WAIT1:应用说它已经完成
FIN_WAIT2:另一边已同意释放
ITMED_WAIT:等待所有分组死掉
CLOSING:两边同时尝试关闭
TIME_WAIT:另一边已初始化一个释放
LAST_ACK:等待所有分组死掉

也就是说,这条命令可以把当前系统的网络连接状态分类汇总。

下面解释一下为啥要这样写:

一个简单的管道符连接了netstat和awk命令。

------------------------------------------------------------------

先来看看netstat:

netstat -n

Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 123.123.123.123:80 234.234.234.234:12345 TIME_WAIT

你实际执行这条命令的时候,可能会得到成千上万条类似上面的记录,不过我们就拿其中的一条就足够了。

------------------------------------------------------------------

再来看看awk:

/^tcp/
滤出tcp开头的记录,屏蔽udp, socket等无关记录。

state[]
相当于定义了一个名叫state的数组

NF
表示记录的字段数,如上所示的记录,NF等于6

$NF
表示某个字段的值,如上所示的记录,$NF也就是$6,表示第6个字段的值,也就是TIME_WAIT

state[$NF]
表示数组元素的值,如上所示的记录,就是state[TIME_WAIT]状态的连接数

++state[$NF]
表示把某个数加一,如上所示的记录,就是把state[TIME_WAIT]状态的连接数加一

END
表示在最后阶段要执行的命令

for(key in state)
遍历数组

print key,"\t",state[key]
打印数组的键和值,中间用\t制表符分割,美化一下。

如发现系统存在大量TIME_WAIT状态的连接,通过调整内核参数解决,
vim /etc/sysctl.conf
编辑文件,加入以下内容:

1. net.ipv4.tcp_syncookies = 1
2. net.ipv4.tcp_tw_reuse = 1
3. net.ipv4.tcp_tw_recycle = 1
4. 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 时间

下面附上TIME_WAIT状态的意义:

客户端与服务器端建立TCP/IP连接后关闭SOCKET后,服务器端连接的端口
状态为TIME_WAIT

是不是所有执行主动关闭的socket都会进入TIME_WAIT状态呢?
有没有什么情况使主动关闭的socket直接进入CLOSED状态呢?

主动关闭的一方在发送最后一个 ack 后
就会进入 TIME_WAIT 状态 停留2MSL(max segment lifetime)时间
这个是TCP/IP必不可少的,也就是“解决”不了的。

也就是TCP/IP设计者本来是这么设计的
主要有两个原因
1。防止上一次连接中的包,迷路后重新出现,影响新连接
(经过2MSL,上一次连接中所有的重复包都会消失)
2。可靠的关闭TCP连接
在主动关闭方发送的最后一个 ack(fin) ,有可能丢失,这时被动方会重新发
fin, 如果这时主动方处于 CLOSED 状态 ,就会响应 rst 而不是 ack。所以
主动方要处于 TIME_WAIT 状态,而不能是 CLOSED 。

TIME_WAIT 并不会占用很大资源的,除非受到攻击。

还有,如果一方 send 或 recv 超时,就会直接进入 CLOSED 状态

netstat -an | grep SYN | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | more

  1. netstat -tna | cut -b 49- |grep TIME_WAIT | sort
    取出目前所有 TIME_WAIT 的连接 IP ( 排序过 )

  2.   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 = 30 表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。
      net.ipv4.tcp_keepalive_time = 1200 表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。
      net.ipv4.ip_local_port_range = 1024 65000 表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。
      net.ipv4.tcp_max_syn_backlog = 8192 表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
      net.ipv4.tcp_max_tw_buckets = 5000 表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。默认为180000,改 为5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于Squid,效果却不大。此项参 数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。

     

     

    在怀疑有Dos攻击的时候,可以输入

    1 netstat -na | grep :80 |awk '{print $5}'|awk -F '::ffff:' '{print $2}' grep ':' awk -F: '{print $1}' sort uniq -c | sort -r | awk -F' ' '{if ($1 > 50) print $2}' sed's/^.*$/iptables -I firewall 1 -p tcp -s & --dport 80 --syn -j REJECT/' | sh

    先把冲击量最大的前50个IP给封了.

    还可以加几个例外的白名单IP

    1 netstat -na | grep :80 |awk '{print $5}'|awk -F '::ffff:' '{print $2}' grep ':' awk -F: '{print $1}' sort uniq -c | sort -r | awk -F' ' '{if ($1 > 50) print $2}' grep-v xxx.xxx.xxx.xxx | sed 's/^.*$/iptables -I RH-Firewall-1-INPUT 1 -p tcp -m tcp -s & --dport 80 --syn -j REJECT/' | sh
    以上的命令还没有实际考证过, 放在这里做参考.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

服务端Too many open files解决方案 的相关文章

  • 如何指定配置脚本的包含目录

    我的工作场所有一个 Linux 系统 其中包含相当旧的软件包 并且没有 root 访问权限 我正在从源代码编译我需要的包 prefix somewhere in homedir 我的问题是我只是不知道如何说服配置在特定目录中查找头文件 源码
  • 隐式声明“gets”

    据我所知 隐式声明 通常意味着该函数必须在调用之前放置在程序的顶部 或者我需要声明原型 然而 gets应该在stdio h文件 我已包含 有没有什么办法解决这一问题 include
  • 如果输入被重定向则执行操作

    我想知道如果我的输入被重定向 我应该如何在 C 程序中执行操作 例如 假设我有已编译的程序 prog 并且我将输入 input txt 重定向到它 我这样做 prog lt input txt 我如何在代码中检测到这一点 一般来说 您无法判
  • 打印本周星期一的日期(在 bash 中)

    我想获取本周星期一的 YYYYMMdd 格式的日期 例如 今天是 20110627 从明天到周日 我仍然想打印周一 今天 的日期 然后下周重复这个过程 monday date dmonday Y m d last monday date d
  • 当在 python linux 中执行命令 os.system() 时,在 python 中给出响应 yes/no

    考虑一个像这样的命令 yum install boto 当我在终端中执行时 要继续 会询问我是 否 我可以像这样用 python 回应它吗 os system yum install boto Next Yes 将通过相同的 python
  • 无法连接到 Azure Ubuntu VM - 公钥被拒绝

    我们在 Azure 上使用 Ubuntu VM 一段时间了 很少遇到任何问题 然而 其中一台虚拟机最近出现了问题 出乎意料的是 Ubuntu VM 开始拒绝公钥 ssh i azure key email protected cdn cgi
  • 如何将命令输出作为多个参数传递给另一个命令

    我想将命令的每个输出作为多个参数传递给第二个命令 例如 grep pattern input returns file1 file2 file3 我想复制这些输出 例如 cp file1 file1 bac cp file2 file2 b
  • Linux 中有没有一种轻量级的方法来获取当前进程数?

    我希望我的 基于 C C 的 程序显示一个数字指示器 指示本地系统上当前有多少个进程 将经常查询正在运行的进程数值 例如每秒一次 以更新我的显示 有没有一种轻量级的方法来获取该数字 显然我可以调用 ps ax wc l 但我不想强迫计算机生
  • grep 彩色线条

    我编写了一个简单的 PHP shell 脚本 它解析文件并输出某些元素 它产生大量的输出 采用不同的 bash 颜色 绿色表示正常 黄色表示警告 红色表示错误等 在开发过程中我想过滤掉一些行 例如 所有包含红色文本的行 我可以使用grep
  • 通过名称获取进程ID

    我想在 Linux 下获得一个给定其名称的进程 ID 有没有一种简单的方法可以做到这一点 我还没有在 C 上找到任何可以轻松使用的东西 如果追求 易于使用 char buf 512 FILE cmd pipe popen pidof s p
  • 虚拟内存澄清——大连续内存的分配

    我有一个应用程序 我必须在 Windows 上分配 使用运算符 new 相当大的内存空间 数百 MB 该应用程序是 32 位 我们现在不使用 64 位 即使在 64 位系统上也是如此 我启用了 LARGEADDRESSAWARE 链接器选项
  • 使用 Python 将阿拉伯语或任何从右到左书写系统的字符串打印到 Linux 终端

    非常简单的例子是 city print city 我期望输出是 但实际上输出是相反的字符串 字母看起来有点不同 因为它们有开始 中间和结束形式 我无法将其粘贴到此处 因为复制粘贴会再次更正字符串的顺序 如何在 Linux 终端上正确打印阿拉
  • EULA 接受 Bash 脚本

    我有一个尝试安装垃圾箱的脚本 除了 bin 在 more 中打开 EULA 之外 一切正常 在脚本再次开始并自行完成安装之前 您必须手动 ctrl c 退出此 more 实例 因为这更多的是逃离 shell 所以脚本在打开后不知道要运行什么
  • 如何使用 PyAudio 选择特定的输入设备

    通过 PyAudio 录制音频时 如何指定要使用的确切输入设备 我的电脑有两个麦克风 一个内置 一个通过 USB 我想使用 USB 麦克风进行录音 这流类 https people csail mit edu hubert pyaudio
  • X 按键/释放事件捕获,与焦点窗口无关

    我想记录所有传入的按键事件 无论哪个窗口处于焦点状态或指针位于何处 我编写了一个示例代码 它应该捕获当前焦点窗口的按键事件 include
  • PHP 日志文件颜色

    我正在编写一个 PHP 日志文件类 但我想为写入文件的行添加颜色 我遇到的问题是颜色也会改变终端的颜色 我想要实现的是仅更改写入日志文件的行的颜色 class logClass extends Singleton private funct
  • 如何从 Linux 命令行确定 LCD 显示器是否打开

    如何通过 Linux 命令行判断计算机的显示器是否打开 关闭 我传统上认为显示器是仅输出的设备 但我注意到 Gnome 显示器首选项对话框具有 检测显示器 功能 这可以推广到确定显示器是否物理关闭吗 VESA DDC 连接是I2C http
  • 我们可以在 Bash 脚本中使用 PHP 吗?

    我有一个 bash 脚本abcd sh bin sh for i in seq 8 do ssh w i uptime ps elf grep httpd wc l free m mpstat done pid sleep 1 kill 9
  • 有没有办法只安装mysql客户端(Linux)? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有没有不需要安装整个mysql db安装包的Linux mysql命令行工具 我想做的是从服务器 1 应用程序服务器 执行将在服务器 2
  • 如何获取 bash 中从 Ping 接收到的数据包的百分比?

    当 ping 主机时 我希望输出仅显示收到的数据包 已发送 5 个 的百分比 我想我需要使用grep不知怎的 但我不知道如何 我是 bash 编程的新手 这是我所在的地方 ping c 5 q host grep grep 中应该包含什么

随机推荐

  • 2021-07-11

    如何使用Microsoft Your Phone 很多小伙伴在Win10上想要使用 Microsoft Your Phone 的时候 发现会提示 您所在的地区不可用 解决方法很简单 不需要翻墙 在设置里将 地区 改成国外 美国英国都可以 然
  • jsp中文乱码如何解决_Kali Linux 2020版 中文乱码和中文设置问题解决方案

    kali linux 2020版 虚拟机文件默认为英语状态 好多小伙伴表示英语看的太费劲了或者出现乱码的情况 下面来教大家如何处理 以乱码为例 包含中文设置 方便大家看 以中文演示 注 因为我的新装的kali 当前用户并不是root用户 并
  • Codeforces Round #552 (Div. 3)

    A Restoring Three Numbers time limit per test 1 second memory limit per test 256 megabytes input standard input output s
  • opengl绘制的图形在前面不显示,绕到后面才显示

    具体说一下情况 就是带相机漫游功能的场景中 绘制的多边形物体 从z轴正向看的话 显然没有图像 但是把相机绕到z轴负方向就绘制出了图像 这个问题主要是因为在工程中glEnable GL CULL FACE 造成的 注释掉即可 下面摘抄自网上
  • 如何查看动态代理中$Proxy0.class文件 如何生成

    如图 System getProperties put jdk proxy ProxyGenerator saveGeneratedFiles true
  • Python socket 访问网站发送 HTTP POST请求,从而深刻理解 HTTP 协议

    用最原始的包 socket 居然可以访问网站模拟发送 POST 请求 只要发送的字符串符合 HTTP 协议 这是最大的收获 更进一步的参考 https www jianshu com p f196c74e72dd import socket
  • UE4蓝图(很经典) 间隔1秒就执行一次,间隔循环执行

    首先 我们理解一个东西 这个东西是刷新次数 一般来说就是delta就是 如果你的刷新频率为 那么delta就是1 60 0 016 所以说 每一秒中大概要60次 按刷新频率为60hz来算 这样子看呢 我的电脑就差很多了啦 不过道理都一样子
  • 系统异常重启检测-mcelog

    mcelog 是Linux 系统上用来检查硬件错误 特别是内存和CPU错误的工具 比如服务器隔一段时间莫名的重启一次 而message和syslog又检测不到有价值的信息 通常发生MCE报错的原因有如下 1 内存报错或者ECC问题 2 处理
  • 小程序抛出Unterminated string literal异常的处理

    Unterminated string literal的异常原因是因为JS编程中对var对象赋值时 字符串出现回车导致的 如下图所示 如何解决这个问题 如果不需要回车 那么用 的形式取消掉回车 或者手动退格键删除回车 如果需要回车那么在字符
  • 嗯,我们出了一套做爬虫必备的 JS 逆向课程

    阅读本文大概需要 4 分钟 爬虫是大数据时代不可或缺的数据获取手段 它是综合技术的应用体现 有取就有失 有攻就有防 开发者为了保护数据 不得已想出了很多办法来限制爬虫对数据的获取 WEB 网站的构成使得 JavaScript 成为了开发者阻
  • selenium java自动化测试_《Selenium3 Java 自动化测试实战》--测试环境搭建

    1 测试环境搭建 1 1 安装Java 1 1 1 下载地址 https www java com zh CN download windows 64bit jsp 1 1 2 配置环境变量 1 2 安装 IntelliJ IDEA 1 2
  • 二、进程管理(一)进程与线程

    目录 1 1 进程的概念 1 1 1 进程的作用和组织 1 1 2 进程的状态与转换 1 1 3 进程控制 1 1 4 进程的通信 1 2 线程的概念 1 2 1线程的概念 1 2 2用户级线程和内核级线程 1 2 3多线程模型 1 1 进
  • 树莓派can总线_CAN总线知识点荟萃

    CAN协议和标准规范有哪些 表1 CAN协议和标准 从 CAN 总线协议颁布以来 CAN 总线经过了 ISO11898 1 ISO11898 2 ISO11898 3 ISO11898 4 ISO11898 5 ISO11898 6 国际标
  • 第五章:(1)S7-200 SMART PLC的编程语言及编程元件

    编程语言 1 梯形图 LAD 2 功能块图 FBD 3 语句表 STL S7 200 SMART PLC的编程元件 常用分类 中文 英文 注释 例 输入继电器 I I0 0 输出继电器 Q Q0 0 使用时不能超过PLC所提供的最大外部接线
  • Not allowed to load local resource: file:///D:/xxx.jpg

    问题 Not allowed to load local resource file D xxx jpg 出现以上情况的原因是浏览器不允许访问本地路径 所以你需要配置一个虚拟的路径代替本地的路径 解决方法 思路 通过tomcat代理 在to
  • 常见提高并发量的方式

    1 避免锁表操作 2 缓存常用数据 3 Redis使用时 连接串参数设置
  • Logstash将日志产生时间替换@timestamp

    一 跟着官网学习一下date插件 日期过滤器用于从字段中解析日期 然后使用该日期或时间戳作为事件的logstash时间戳 例如 syslog事件通常具有这样的时间戳 Bash Apr 17 09 32 01 你可以使用日期格式MMM dd
  • 互信息

    互信息 Mutual Information 是信息论里一种有用的信息度量 它可以看成是一个随机变量中包含的关于另一个随机变量的信息量 或者说是一个随机变量由于已知另一个随机变量而减少的不肯定性 设两个随机变量 X Y X Y
  • openwrt web界面添加 菜单选项

    一 添加一级菜单选项 例如下图probe菜单选项 1 在 usr lib lua luci controller admin目录下 创建probe lua文件 如下 module luci controller admin probe pa
  • 服务端Too many open files解决方案

    服务端Too many open files解决方案 转自 http zhumeng8337797 blog 163 com blog static 1007689142012428104618670 cat proc sys fs fil