运维实战案例之“Too many open files”错误与解决方法

 

技术小甜 2017-11-16 15:02:00 浏览869

 

一、问题现象

这是一个基于Java的Web应用系统,在后台添加数据时提示无法添加,于是登录服务器查看tomcat日志,发现了如下异常信息:

java.io.IOException: Too many open files

通过这个错误,基本判断是系统可用的文件描述符不够了,由于tomcat服务是系统www用户启动的,于是用www用户登录系统,通过“ulimit -n”命令查看系统可以打开最大文件描述符的数量,输出如下:

[www@tomcatserver ~]$ ulimit  -n

65535

可以看到这个服务器设置的最大可打开的文件描述符已经是65535了,这么大的一个值应该够用了,但是为什么还是提示这么个错误呢?

二、解决思路

这个案例涉及到linux下ulimit命令的使用,这里简单介绍下ulimit的作用和使用技巧。ulimit主要是用来限制进程对资源的使用情况的,它支持各种类型的限制,常用的有:

内核文件的大小限制

进程数据块的大小限制

Shell进程创建文件大小限制

可加锁内存大小限制

常驻内存集的大小限制

打开文件句柄数限制

分配堆栈的最大大小限制

CPU占用时间限制用户最大可用的进程数限制

Shell进程所能使用的最大虚拟内存限制

ulimit使用的基本格式为:

ulimit [options] [limit]

具体的options参数含义如下表所示:

选项 含义

-a 显示当前系统所有的limit资源信息。

-H 设置硬资源限制,一旦设置不能增加。

-S 设置软资源限制,设置后可以增加,但是不能超过硬资源设置。

-c 最大的core文件的大小,以 blocks 为单位。

-f 进程可以创建文件的最大值,以blocks 为单位.

-d 进程最大的数据段的大小,以Kbytes 为单位。

-m 最大内存大小,以Kbytes为单位。

-n 可以打开的最大文件描述符的数量。

-s 线程栈大小,以Kbytes为单位。

-p 管道缓冲区的大小,以Kbytes 为单位。

-u 用户最大可用的进程数。

-v 进程最大可用的虚拟内存,以Kbytes 为单位。

-t 最大CPU占用时间,以秒为单位。

-l 最大可加锁内存大小,以Kbytes 为单位。

在使用ulimit时,有以下几种使用方法:

(1)在用户环境变量中加入

如果用户使用的是bash,那么就可以在用户目录的环境变量文件.bashrc或者.bash_profile中加入“ulimit -u 128”来限制用户最多可以使用128个进程。

(2)在应用程序的启动脚本中加入

如果应用程序是tomcat,那么就可以在tomcat的启动脚本startup.sh脚本中加入“ulimit -n 65535”来限制用户最多可以使用65535个文件描述符。

(3)直接在shell命令终端执行ulimit命令

这种方法的资源限制仅仅在执行命令的终端生效,退出或者关闭终端后,设置失效,并且这个设置不影响其它shell终端。

有时候为了方便起见,也可以将用户资源的限制统一由一个文件来配置,这个文件就是/etc/security/limits.conf,该文件不但能对指定用户的资源进行限制,还能对指定组的资源进行限制。该文件的使用规则如下:

<domain> <type> <item> <value>

其中:

domain表示用户或者组的名字,还可以使用 * 作为通配符,表示任何用户或用户组。

Type 表示限制的类型,可以有两个值,soft 和 hard,分别表示软、硬资源限制。

item 表示需要限定的资源名称,常用的有nofile、cpu、stack等。分别表示最大打开句柄数、占用的cpu时间、最大的堆栈大小。

value 表示限制各种资源的具体数值。

除了limits.conf文件之外,还有一个/etc/security/limits.d目录,可以将资源限制创建一个文件放到这个目录中,默认系统会首先去读取这个目录下的所有文件,然后才去读取limits.conf文件。所有资源限制设置完成后,退出shell终端,再次登录shell终端后,ulimit设置即可自动生效。

三、解决问题

在介绍了ulimit知识后,紧接着上面的案例,既然ulimit设置没问题,那么一定是设置没有生效导致的,接下来检查下启动tomcat的www用户环境变量下是否添加了ulimit限制,检查发现,www用户下并无ulimit资源限制,于是继续检查tomcat启动脚本startup.sh文件中,是否添加了ulimit限制,检查发现也并无添加,最后考虑是否将限制加到了limits.conf文件中,于是检查limits.conf文件,操作如下:

1
2
3
[root@tomcatserver ~]# cat /etc/security/limits.conf|grep www
www soft nofile 65535
www hard nofile 65535

从输出可知,ulimit限制是加在了limits.conf文件中,既然限制已经加了,配置也没有错,为何还是报错呢,经过长时间思考,判断只有一种可能,那就是tomcat的启动时间早于ulimit资源限制的添加时间,于是首先查看下tomcat的启动时间,操作如下:

1
2
3
4
5
6
7
8
9
[root@tomcatserver ~]# more /etc/issue
CentOS release 6.3 (Final)
Kernel \r on an \m
[root@tomcatserver ~]# uptime
 15:10:19 up 283 days,  5:37,  4 users,  load average: 1.20, 1.41, 1.35
[root@tomcatserver ~]# pgrep –f  tomcat                     
4667
[root@tomcatserver ~]# ps -eo pid,lstart,etime|grep 4667
4667 Sat Jul  6 09:33:39 2013 77-05:26:02

从输出看,这台服务器已经有283天没有重启过了,而tomcat是在2013年7月6号9点多启动的,启动了近77天零五个半小时了,接着继续看看limits.conf文件的修改时间,操作如下图所示:

通过stat命令可以很清楚的看出,limits.conf文件最后的修改时间是2013-07-12,通过查问相关的Linux系统管理人员,他们基本确认就是在这个时候添加的ulimit资源限制,这样此案例的问题就很明确了。由于ulimit限制的添加时间晚于tomcat最后一次的启动时间,而在此期间内,tomcat服务一直未重启过,操作系统也一直未重启过,那么ulimit资源限制对于tomcat来说始终是不生效的,同时,由于此操作系统是Centos6.3,系统默认的最大可用句柄数是1024,那么java进程还是用的Linux默认的这个值,出现“Too many open files”的错误,也是合乎情理的。

问题清楚之后,解决问题的方法非常简单,重启tomcat服务即可。

运维实战案例之“Too many open files”错误与解决方法的更多相关文章

  1. 企业Shell面试题及企业运维实战案例(三)

    1.企业Shell面试题1:批量生成随机字符文件名案例 使用for循环在/oldboy目录下批量创建10个html文件,其中每个文件需要包含10个随机小写字母加固定字符串oldboy,名称示例如下: ...

  2. LINUX运维实战案例之文件已删除但空间不释放问题的分析与解决办法

    1.错误现象 运维的监控系统发来通知,报告一台服务器空间满了,登陆服务器查看,根分区确实没有空间了,如下图所示: 这里首先说明一下服务器的一些删除策略,由于Linux没有回收站功能,我们的线上服务器所 ...

  3. Istio 运维实战系列(2):让人头大的『无头服务』-上

    本系列文章将介绍用户从 Spring Cloud,Dubbo 等传统微服务框架迁移到 Istio 服务网格时的一些经验,以及在使用 Istio 过程中可能遇到的一些常见问题的解决方法. 什么是『无头服 ...

  4. 《Splunk智能运维实战》——1.7 为本书加载样本数据

    本节书摘来自华章计算机<Splunk智能运维实战>一书中的第1章,第1.7节,作者 [美]乔史·戴昆(Josh Diakun),保罗R.约翰逊(Paul R. Johnson),德莱克·默 ...

  5. CentOS7系统管理与运维实战

    CentOS7系统管理与运维实战 下载地址 https://pan.baidu.com/s/1KFHVI-XjGaLMrh39WuhyCw 扫码下面二维码关注公众号回复100007 获取分享码 本书目 ...

  6. Istio 运维实战系列(3):让人头大的『无头服务』-下

    本系列文章将介绍用户从 Spring Cloud,Dubbo 等传统微服务框架迁移到 Istio 服务网格时的一些经验,以及在使用 Istio 过程中可能遇到的一些常见问题的解决方法. 失败的 Eur ...

  7. 网易OpenStack部署运维实战

    OpenStack自2010年项目成立以来,已经有超过200个公司加入了 OpenStack 项目,目前参与 OpenStack 项目的开发人员有 17,000+,而且这些数字还在增加,作为一个开源的 ...

  8. 转 移动云基于MySQL Galera的PXC运维实战

    ##sample 1 : mysql 监控 1.phpadmin  比较简单,适合上手 2.mysql_web python 写的, https://github.com/ycg/mysql_web/ ...

  9. Istio 运维实战系列(1):应用容器对 Envoy Sidecar 的启动依赖问题

    本系列文章将介绍用户从 Spring Cloud,Dubbo 等传统微服务框架迁移到 Istio 服务网格时的一些经验,以及在使用 Istio 过程中可能遇到的一些常见问题的解决方法. 故障现象 该问 ...

随机推荐

  1. ELK查询命令详解总结

    目录 ELK查询命令详解 倒排索引 倒排索引原理 分词器介绍及内置分词器 使用ElasticSearch API 实现CRUD 批量获取文档 使用Bulk API 实现批量操作 版本控制 什么是Map ...

  2. 微信小程序授权登录以及用户信息相关接口调整导致授权框不弹出

    前言:4月8号升级了小程序业务后提交了版本并上线.突然一个同事说体验版的点击"登录"按钮无效.当时觉得应该不会呀,这几天一直用手机调试,每天也在不停的登录授权,弹框一直有的呀.然后 ...

  3. Vue 中的 mixin,component,render,hoc

    在项目中,一般我们经常会基于一套现有组件库进行快速开发,但是现实中往往需要对组件库进行定制化改造二次封装 混入(mixin) vue 官方介绍 混入 (mixin) 提供了一种非常灵活的方式,来分发 ...

  4. php添加excel更新数据表数据

    公司有个需求,是用excel更新数据的,把错误的行列放到一个数组返回出来,正常的数据则插入,且返回数量 1.先需要引入phpspreadsheet,这里使用composer 安装 composer r ...

  5. Linux 递归修改后缀名

    1 修改命令 需要用到: find awk xargs 递归修改命令如下: find . -name '*.XXX' | awk -F "." '{print $2}' | xar ...

  6. 5. linux 中“~”,“/”,“#”,”$“ 含义

    "~" ~ 是用户的home目录(又叫"用户家目录")linux存储是以挂载的方式,相当于是树状的,源头就是"/",也就是根目录.而每个用户 ...

  7. Deployment常用命令

    // 查询详细信息,获取升级速度 kubectl describe deployments // 暂停升级 kubectl rollout pause deployment/deploymentngi ...

  8. C#入门到精通系列课程——第1章软件开发及C#简介

    ◆本章内容 (1)了解软件 (2)软件开发相关概念 (3)认识.NET Framework (4)C#语言 (5)Visual Studio 2017 ◆本章简述 软件在现代人们的日常生活中随处可见, ...

  9. Python 3.10 中新的功能和变化

    随着最后一个alpha版发布,Python 3.10 的功能更改全面敲定! 现在,正是体验Python 3.10 新功能的理想时间!正如标题所言,本文将给大家分享Python 3.10中所有重要的功能 ...

  10. Ionic5路由跳转传值复用

    1. 路由技术 ( 详细记录 ) 是笔记不是博文,觉得写的不够详细的可以使用Ctrl + W组合键 路由跳转页面 1. HTML 中使用 routerLink 属性路由进行跳转,传值时使用 query ...