zoukankan      html  css  js  c++  java
  • nginx报错 too many open files in system

    系统进不去了,用ssh连接服务器也非常慢,负载均衡显示后端连接异常,重启mysql数据库,发现经常重启,或者直接关机,访问页面也访问不到。

    http://www.51testing.com/html/56/13956-209988.html

    查看mysql日志文件没发现问题,

    查看nginx.error的日志发现报错

    018/04/23 16:44:42 [crit] 11182#0: accept4() failed (23: Too many open files in system)
    2018/04/23 16:44:42 [crit] 11182#0: accept4() failed (23: Too many open files in system)
    2018/04/23 16:44:47 [crit] 11185#0: accept4() failed (23: Too many open files in system)
    2018/04/23 16:44:47 [crit] 11185#0: accept4() failed (23: Too many open files in system)

    当系统访问高峰的时间用root执行脚本出现如下结果:

    lsof -n | awk '{print $2}' | sort | uniq -c | sort -nr | more

        365 7220
        365 4500
        365 4423
        365 2057
        365 2056
        365 2055
        365 2054
        365 2053
        365 2052
        365 2051
        365 2050
        365 2049
        365 2048
        365 2047
        365 2046
        365 2045
        365 2044
        365 2043
        365 2042
        365 2041
        365 2040
        365 2039

    第一行是打开的文件的句柄数量,第二行为进程号.得到进程号后,可以通过ps命令得到进程的详细内容

    ps -ef | grep 7220

    mysql 7220 423 465 15:09 ?      /usr/sbin/mysqld

    原来是mysql进程打开最多文件句柄数量。但是他目前只打开了131个文件句柄数量,远远底于系统默认值1024

    但是如果系统并发特别大,尤其是某个进程,很有可能会超过1024。这时候就必须要调整系统参数,以适应应用变化

    关闭某个进程。

    综上所述:
    是因为系统对打开的文件做了限制。

    ulimit -n      查看当前用户的文件描述的数目

    该数值是显示的是1024,意思是显示文件打开的数目限制为1024,可以让数字更大些,让网站的访问并发更高些。

    修改ulimit限制数的方法:

    .首先你得修改nginx.conf配置文件,在定义error.log日志路径的位置添加一行

    vi nginx.conf

    worker_rlimit_nofile 655350;

    2.在/etc/bashrc文件最后面添加下面内容

      ulimit -n 655350

    3.在/etc/security/limits.conf文件最后面添加下面内容

      * sofe nofile 655350

      * sofe nofile 655350

    *代表所有用户,如果想代表某个用户的话,则user sofe/hard nofile 65535

    sofe代表软连接,hard代表硬限制


    4.要使 limits.conf 文件配置生效,必须要确保 pam_limits.so 文件被加入到启动文件中

    在/etc/bashrc后面加上ulimit -n 655350
    或者 先查找下pam_limits.so的位置。
    find / -name pam_limits.so
    /lib64/security/pam_limits.so
    vi /etc/pam.d/login
    session    required     /lib64/security/pam_limits.so



    若查看mysql文件报错:

    101029 16:09:24 [ERROR] Error in accept: Too many open files
    101029 16:17:20 [ERROR] Error in accept: Too many open files
    101029 16:21:37 [ERROR] Error in accept: Too many open files

    101029 16:25:53 [ERROR] Error in accept: Too many open files
    101029 16:30:09 [ERROR] Error in accept: Too many open files

    /proc/sys/fs/file-max

    这是系统资源分配的最高档案数,设定值与内存大小有关,早期 ram 很贵的时代,这个值通常不会太大,所以 mysql 开的档案数如果太多,确实可能被这个值限制住,但是现在动辄数 G  memory,这个值在我的 linux 系统上都内定开到 20 万以上,因此问题不在这个值。 (若真想修改这个值,可以用 sysctl -w fs.file-max=##### 来修改,但系统重开后自动改回,可写入/etc/rc.local 开机执行)

    cat /proc/sys/fs/file-max

    203457

    sysctl -w fs.file-max=406914

    fs.file-max=406914

    cat /proc/sys/fs/file-max

    406914

    vi /etcc/rc.local

    sysctl -w fs.file-max=

    开机重启时候加上该文件保证其生效

    cat /etc/security/limits.conf |grep mysql
    mysql soft nofile 24000
    mysql hard nofile 32000

    ulimit -n

    ulimit 可以查看每个 shell 的使用资源大小,-n 参数在 man page 中是写 The maximum number of open file descriptors,换句话说,mysql 所处的 shell,真的能开的档案只是ulimit -n 的值,在我的系统上 ulimit -n 的值仅有 1024,所以就算 fs.file-max 有几十万,mysql shell 可以开的就是 1024 而已,这才是关键所在。

    my.cnf 中的 table_open_cache,max_connections, open_files_limit 三个参数

    table_open_cache,指 mysql 开启 table 的 cache file 数,一般 mysql 开一个 table就会开启 *.MYI 和 *.MYD 两个档,比方说我们用 phpMyAdmin 开一个有 100 个 tables 的 DB,mysql 会 cache 住 200 个files。 (default: 64)

    open_files_limit: mysqld 开启的最高档案数。 (default: 0)

    max_connections最高联机数。 (default: 100)

    mysqld  open file 后会 cache 住,那它要开到多少个档案之后,才会去释放掉 cache 的档案?

    那就得看 my.cnf 里面,table_cache, max_connections, open_files_limit 的值,

    如果:open_files_limits 的值为 0,就看 table_cache max_connections 透过某个函数计算出来的值;

    table_cache * 2 + max_connections

    如果 open_files_limits 的值不为 0,那应该是要看这个值的大小设定。

    不管我们要将我们的 mysql 设置 open_files_limit 或是使用 table_cache * 2 + max_connections,都应该要注意ulimit -n 的值才是正解,跟 fs.file-max关联反而较小了。

    要查看 mysql 开启的 files 数,可先用 ps aux| grep mysql  mysql PID,再利用 lsof -p PID# | wc -l 来统计。

  • 相关阅读:
    程序员年后离职跳槽指南
    程序员年后离职跳槽指南
    程序员为什么会有职业瓶颈?
    程序员为什么会有职业瓶颈?
    年过35岁的程序员都去哪了?一张图道尽老程序员们的花样出路
    年过35岁的程序员都去哪了?一张图道尽老程序员们的花样出路
    对于Ping的过程,你真的了解吗?
    对于Ping的过程,你真的了解吗?
    shell解析命令行的过程以及eval命令
    shell的命令替换和命令组合
  • 原文地址:https://www.cnblogs.com/fengzhongzhuzu/p/8946631.html
Copyright © 2011-2022 走看看