服務(wù)器運(yùn)行一段時間出現(xiàn)了Too many open files這個錯誤夜焦,應(yīng)用無法訪問。
原因一:Linux 的open files 數(shù)不夠
root@iZj6c3zjaww2fbthj1qxlxZ:~# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 78454
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 10240
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 31792
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
lsof -n |awk '{print $2}'|sort|uniq -c |sort -nr|more
#查一下當(dāng)前已有的連接數(shù),再來判斷open files 為1024 是不是小
lsof -p $java_pid | wc -l
#加大打開的文件數(shù)
ulimit -n 10240
#用戶級別的修改
#系統(tǒng)級設(shè)置對所有用戶有效。
#可通過兩種方式查看系統(tǒng)最大文件限制
cat /proc/sys/fs/file-max
#修改配置/etc/sysctl.conf文件
fs.file-max=10240
#通知系統(tǒng)啟用這項(xiàng)配置
sysctl -p
修改以上配置后历帚,服務(wù)器運(yùn)行一段時間后還是出現(xiàn)以上問題铺浇,文件句柄數(shù)不斷增加叛赚,需要查找分析以下兩個方面
原因二:代碼打開文件操作未關(guān)閉(沒有文件操作的可跳過)
排查代碼夹厌,如果有大量文件操作,本地壓測定位代碼责蝠,如若未出現(xiàn)則可排除
如果web容器使用的是自己用Netty開發(fā)的請注意:出現(xiàn)大量的CLOSE_WAIT要把參數(shù)EpollChannelOption.SO_LINGER 改成 EpollChannelOption.SO_KEEPALIVE 具體的參數(shù)詳細(xì)說明請查看以下鏈接
Netty:option和childOption參數(shù)設(shè)置說明
原因三:使用了Nginx等其它代理(端口范圍監(jiān)聽)党巾,TCP 參數(shù)配置不對
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 7091
CLOSE_WAIT 2
ESTABLISHED 716
LISTEN 10
常用的三個狀態(tài)是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主動關(guān)閉霜医,CLOSE_WAIT 表示被動關(guān)閉
服務(wù)器保持了大量TIME_WAIT狀態(tài)
#內(nèi)核參數(shù)優(yōu)化
#表示如果套接字由本端要求關(guān)閉齿拂,這個參數(shù)決定了它保持在FIN-WAIT-2狀態(tài)的時間
net.ipv4.tcp_fin_timeout = 30
#表示當(dāng)keepalive起用的時候,TCP發(fā)送keepalive消息的頻度肴敛。缺省是2小時署海,改為300秒,原因是:當(dāng)前都是圖片医男,不需要建立長鏈接
net.ipv4.tcp_keepalive_time = 300
#表示開啟SYN Cookies砸狞。當(dāng)出現(xiàn)SYN等待隊列溢出時,啟用cookies來處理镀梭,可防范少量SYN攻擊刀森,默認(rèn)為0,表示關(guān)閉
net.ipv4.tcp_syncookies = 1
#表示如果套接字由本端要求關(guān)閉丰辣,這個參數(shù)決定了它保持在FIN-WAIT-2狀態(tài)的時間
net.ipv4.tcp_tw_reuse = 1
#表示開啟TCP連接中TIME-WAIT sockets的快速回收撒强,默認(rèn)為0,表示關(guān)閉笙什,當(dāng)前TIME-WAIT 過多,所以開啟快速回收
net.ipv4.tcp_tw_recycle = 1
net.ipv4.ip_local_port_range = 5000 65000
以下是服務(wù)器上用的配置文件(Ubuntu18.04 單CPU 4核 8線程 8G內(nèi)存)
user root;
worker_processes 4;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
use epoll;
worker_connections 102400;
}
http {
include mime.types;
default_type application/octet-stream;
#日志每日分割
log_format '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
map $time_iso8601 $logdate {
'~^(?<ymd>\d{4}-\d{2}-\d{2})' $ymd;
default 'date-not-found';
}
open_log_file_cache max=10;
#緩存
server_names_hash_bucket_size 128;
client_header_buffer_size 2k;
large_client_header_buffers 4 4k;
client_max_body_size 8m;
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
tcp_nodelay on;
##cache##
proxy_connect_timeout 5;
proxy_read_timeout 60;
proxy_send_timeout 5;
proxy_buffer_size 16k;
proxy_buffers 4 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
proxy_temp_path /home/temp_dir;
proxy_cache_path /home/cache levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g;
##end##
gzip on;
gzip_min_length 1k;
gzip_buffers 4 8k;
gzip_http_version 1.1;
gzip_types text/plain application/x-javascript text/css application/javascript application/json application/xml;
gzip_disable "MSIE [1-6]\.";
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream flash-web {
server 127.0.0.1:80;
ip_hash;
}
server {
listen 1000-10000;
server_name ~^(www\.)?(.+)$;
access_log logs/access-$logdate.log;
error_log 'logs/error-$logdate.log';
location ~.*\.(gif|jpg|png|htm|html|css|js|flv|ico|swf)(.*) {
add_header Cache-Control no-cache;
proxy_pass http://flash-web;
proxy_redirect off;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache cache_one;
proxy_cache_valid 200 302 1h;
proxy_cache_valid 301 1d;
proxy_cache_valid any 1m;
expires 10d;
}
location / {
uwsgi_send_timeout 600; # 指定向uWSGI傳送請求的超時時間胚想,完成握手后向uWSGI傳送請求的超時時間琐凭。
uwsgi_connect_timeout 600; # 指定連接到后端uWSGI的超時時間。
uwsgi_read_timeout 600; # 指定接收uWSGI應(yīng)答的超時時間浊服,完成握手后接收uWSGI應(yīng)答的超時時間统屈。
fastcgi_read_timeout 240;
proxy_pass http://flash-web;
proxy_redirect off;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
配置生效后,觀察結(jié)果牙躺,TIME_WAIT 明顯減少愁憔。
TIME_WAIT 8
ESTABLISHED 16
linux進(jìn)程數(shù)和句柄數(shù)基礎(chǔ)概念了解
持續(xù)觀察系統(tǒng),有問題再更新