LWP進程資源耗盡,Resource temporarily unavailable
- 2019 年 10 月 6 日
- 筆記
服務器環境使用root賬戶運行應用程序是非常危險的,容易讓人拿到shell變成肉雞。所以有點意識的團隊,都會建立一個低權限的普通用戶用來運行java程序。
權限低,有點不像親兒子,在資源緊張的困難時刻尤其能看出來。
現象
問題是在一台公用的測試環境機器發生的,正式環境並沒有復現。這台服務器部署了幾十個服務,且部署賬戶最近從root
切換到了xjjbot
。
運行一段時間後,服務器頻繁發生問題了。首先,有大量連接處於CLOSE_WAIT狀態,一度以為是被動關閉的問題。但並不是。
netstat -antp | grep CLOSE | awk '{print $7}' | sort | uniq -c
奇怪的是,使用root
賬戶或者其他賬戶登錄系統,操作一切正常。然而當切換到xjjbot
賬戶,則會報以下錯誤:
# sudo su - xjjbot bash: fork: retry: no child processes bash: fork: retry: no child processes bash: fork: retry: no child processes bash: fork: retry: no child processes bash: fork: Resource temporarily unavailable
以上是系統級別的報錯信息。這種情況下,jvm也會有相應報錯,但恐怕你也沒有機會去看了(可以使用其他系統用戶查看哦)。
- Cannot create GC thread. Out of system resources - java.lang.OutOfMemoryError: unable to create new native thread
原因
引起的原因就是資源不夠用了,具體來說是進程資源。
Linux的線程其實是一個進程,所以java的也是,具體來說,叫做「light weight process(LWP)」—輕量級進程。
LWP與其它進程共享所有(或大部分)邏輯地址空間和系統資源,一個進程可以創建多個LWP,這樣它們共享大部分資源;LWP有它自己的進程標識符,並和其他進程有着父子關係;。LWP由內核管理並像普通進程一樣被調度
使用以下命令可以看到某個用戶使用了多少進程資源
ps -eLf | grep xjjbot(uid) | wc -l
使用下面命令可以查看具體每個進程開啟了多少線程
ps -o nlwp,pid,lwp,args -u xjjbot(uid) | sort -n
解決
根據linux一切都是文件的規則,首先想到的,是修改ulimit的參數,然而也不是,因為它已經足夠大了。交叉回想一下elasticsearch,在安裝的時候,需要配置一個叫做nproc
的東西,問題大概就出在這,是進程資源不夠用啦。
相關的配置文件: /etc/security/limits.conf
在不同的內核版本上,也有一些小差異。比如 /etc/security/limits.d/* 下的文件,會在某些時候覆蓋limits.conf的配置。所以配置不生效的情況下,記得檢查一下。
鑒於以上原因,可以將limits.d中的配置全部注釋掉,統一在limits.conf中配置。
以下是原始配置
* soft nproc 4096 root soft nproc unlimited
將4096改為大點的數字,或者直接改成unlimited就可以了。
ElasticSearch系統參數配置
既然提到了es,那麼我們看一下es安裝都需要改哪些系統配置。這些經驗都是公用的,可以舉一反三。
https://www.elastic.co/guide/en/elasticsearch/reference/master/setting-system-settings.html
禁用swap
swap是性能殺手,所以ES也忍受不住了,直接關掉。
sudo swapoff -a
在配置文件里也可以加入這個參數,jvm鎖住內存,不讓它們和交換分區交換。
bootstrap.memory_lock: true
虛擬內存
ES使用mmapfs
來映射一些數據,但默認的系統參數對它來說太小了,也需要修改。
sysctl -w vm.max_map_count=262144
永久生效需要修改 /etc/sysctl.conf
文件句柄
ulimit
linux打開的文件描述符數量是有限的。如果你的應用需要同時和很多小文件打交道,則需要配置此參數。
sudo su ulimit -n 65536 su elasticsearch
/etc/security/limits.conf
ok,這就是我們剛才改動的文件。要想上面的配置永久生效,則需要改動此文件。
elasticsearch - nofile 65536
線程數量
就是我們上面說的啦,能夠快速想到它,也是因為安裝過es -.- 所以,不要隨便開一大堆線程,除了增加調度時間,還容易頂到系統的天花板。
馮諾依曼架構下,這些軟件,不都一個套路么? 有着一樣的命運,掙扎着卻無法逃脫。