LWP進程資源耗盡,Resource temporarily unavailable

微信公衆號:《小姐姐味道》,文末附二維碼,歡迎關注。html

服務器環境使用root帳戶運行應用程序是很是危險的,容易讓人拿到shell變成肉雞。因此有點意識的團隊,都會創建一個低權限的普通用戶用來運行java程序。java

權限低,有點不像親兒子,在資源緊張的困難時刻尤爲能看出來。linux

現象

問題是在一臺公用的測試環境機器發生的,正式環境並無復現。這臺服務器部署了幾十個服務,且部署帳戶最近從root切換到了xjjbotshell

運行一段時間後,服務器頻繁發生問題了。首先,有大量鏈接處於CLOSE_WAIT狀態,一度覺得是被動關閉的問題。但並非。bootstrap

netstat -antp | grep CLOSE | awk '{print $7}'  | sort | uniq -c
複製代碼

奇怪的是,使用root帳戶或者其餘帳戶登陸系統,操做一切正常。然而當切換到xjjbot帳戶,則會報如下錯誤:bash

# 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由內核管理並像普通進程同樣被調度jvm

使用如下命令能夠看到某個用戶使用了多少進程資源

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安裝都須要改哪些系統配置。這些經驗都是公用的,能夠觸類旁通。

www.elastic.co/guide/en/el…

禁用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 -.- 因此,不要隨便開一大堆線程,除了增長調度時間,還容易頂到系統的天花板。

馮諾依曼架構下,這些軟件,不都一個套路麼? 有着同樣的命運,掙扎着卻沒法逃脫。

相關文章
相關標籤/搜索