Linux 下应用程序最大打开文件数的理解和修改

运行在Linux系统上的Java程序运行了一段时间后出现"Too many open files"的异常情况。

这种情况常见于高并发访问文件系统,多线程网络连接等场景。程序经常访问的文件、socket在Linux中都是文件file,系统需要记录每个当前访问file的name、location、access authority等相关信息,这样的一个实体被称为file entry。“open files table”(图中橙色标识)存储这些file entry,以数组的形式线性管理。文件描述符(file descriptor)作为进程到open files table的指针,也就是open files table的下标索引,将每个进程与它所访问的文件关联起来了。



每个进程中都有一个file descriptor table管理当前进程所访问(open or create)的所有文件,文件描述符关联着open files table中文件的file entry。细节不表,对于open files table能容纳多少file entry。Linux系统配置open files table的文件限制,如果超过配置值,就会拒绝其它文件操作的请求,并抛出Too many open files异常。这种限制有系统级和用户级之分。

系统级:

系统级设置对所有用户有效。可通过两种方式查看系统最大文件限制

1 cat /proc/sys/fs/file-max

2 sysctl -a 查看结果中fs.file-max这项的配置数量

如果需要增加配置数量就修改/etc/sysctl.conf文件,配置fs.file-max属性,如果属性不存在就添加。

配置完成后使用sysctl -p来通知系统启用这项配置

用户级:

Linux限制每个登录用户的可连接文件数。可通过 ulimit -n来查看当前有效设置。如果想修改这个值就使用 ulimit -n 命令。

对于文件描述符增加的比例,资料推荐是以2的幂次为参考。如当前文件描述符数量是1024,可增加到2048,如果不够,可设置到4096,依此类推。

在出现Too many open files问题后,首先得找出主要原因。最大的可能是打开的文件或是socket没有正常关闭。为了定位问题是否由Java进程引起,通过Java进程号查看当前进程占用文件描述符情况:

lsof -p $java_pid 每个文件描述符的具体属性

lsof -p $java_pid | wc -l 当前Java进程file descriptor table中FD的总量

分析命令的结果,可判断问题是否由非正常释放资源所引起。

如果我们只是普通用户,只是暂时的修改ulimit -n,可以直接shell命令来修改(ulimit -n 1024000)。但是这个设置时暂时的保留!当我们退出bash后,该值恢复原值。

如果要永久修改ulimit,需要修改/etc/security/limits.conf。

vim /etc/security/limits.conf

# 添加如下的行

* soft nofile 2048

* hard nofile 2048

以下是说明:

* 代表针对所有用户

noproc 是代表最大进程数

nofile 是代表最大文件打开数

添加格式:

[username | @groupname] type resource limit

[username | @groupname]:设置需要被限制的用户名,组名前面加@和用户名区别。也可以用通配符*来做所有用户的限制。

type:有 soft,hard 和 -,soft 指的是当前系统生效的设置值。hard 表明系统中所能设定的最大值。soft 的限制不能比hard 限制高。用 - 就表明同时设置了 soft 和 hard 的值。

resource:

core - 限制内核文件的大小(kb)

date - 最大数据大小(kb)

fsize - 最大文件大小(kb)

memlock - 最大锁定内存地址空间(kb)

nofile - 打开文件的最大数目

rss - 最大持久设置大小(kb)

stack - 最大栈大小(kb)

cpu - 以分钟为单位的最多 CPU 时间

noproc - 进程的最大数目

as - 地址空间限制

maxlogins - 此用户允许登录的最大数目

实例:

username soft nofile 2048

username hard nofile 2048

@groupname soft nofile 2048

@groupname hard nofile 2048

(0)

相关推荐

  • Linux下MySQL忘记root密码怎么办

    Linux下如果忘记MySQL的root密码,可以通过修改配置的方法,重置root密码 操作方法 01 修改MySQL的配置文件(默认为/etc/my.cnf),在[mysqld]下添加一行skip- ...

  • Linux下如何实现shell多线程编程以提高应用程序的响应

    Linux中多线程编程拥有提高应用程序的响应、使多cpu系统更加有效等优点,下面小编将通过Linux下shell多线程编程的例子给大家讲解下多线程编程的过程,一起来了解下吧。 #!/bin/bash ...

  • ubuntu Linux下gcc/g++编译c++程序,优化编译

    在工作中,常常需要不同的优化级别来编译c++,当需要布在linux服务器上,或者其他情况下,我们需要用到linux下的c++编译器编译c++,常用的gcc/g++.下面笔者分享一些简单的编译选项 操作 ...

  • Linux 下用 Python 连接 MSSql Server 2008

    缘起 因为客户要求在应用上部署 mssql server 2008,而我们习惯了开发 Linux 下的服务器程序,所以就有了在 linux 下用 python 连接 mssql server 2008 ...

  • linux下Samba服务和NFS服务配置的方法

    linux下Samba服务和NFS服务配置 一、Samba服务配置过程 samba的功能很简单,就是为了使linux和windows之间能够实现共享。并且利用samba搭建文件服务器,不仅比windo ...

  • 如何在Linux下自学各类需要的知识

    安装好了Unix/Linux类操作系统,却不知道拿它做点什么、也不知道它能做些什么……这是大多数初这朋友的疑惑。 我认为首先要做的是学会如何在Unix/Linux下获得知识,掌握学习方法。如何真有一天 ...

  • linux下文件解压

    对于刚刚接触Linux的人来说,一定会给Linux下一大堆各式各样的文件名给搞晕。别个不说,单单就压缩文件为例,我们知道在Windows下最常见的压缩文件就只有两种,一是,zip,另一个是.rap。可 ...

  • Linux下备份恢复技术的应用

    本文讲述Linux环境下,如何使用备份的脚本和命令以及商业化的软件来合理高效地保护磁盘数据安全。 备份与恢复系统承担着事前备份与事后恢复的职能。在当前高速发展的网络环境下,任何一个网络上的信息 系统 ...

  • Linux下的用户管理总结(含禁止用户和IP登录的方法)

    在Linux中,用户的管理分为组和用户两种。这个Windows下也是这个样子,组是一类用户的统称。组和用户的关系是:多对多的关系。即用户可以存在于多个组中,组中也可以有多个用户。组的权限会被赋予组中的 ...