天天看點

SSH遠端連接配接指令執行沒反應不報錯問題解決(-bash: fork: retry: Resource temporarily unavailable.[資源暫時不可用])

寫在前面

我遇到了什麼問題:

  • 很老的一個系統

    bug

    原因更新,大概五六年沒有重新開機機器了,4A平台上面通過

    ssh

    遠端連接配接

    Linux

    機器,偶爾連接配接不上
  • 即使連接配接之後指令無法正常執行,執行了沒有反應。
  • 即使可以執行,執行命名報

    -bash: fork: retry: Resource temporarily unavailable.

    (資源暫時不可用)

出現問題的原因是什麼:

Linux程序數超過了設定的最大程序數。會對系統進行資源限制,是以配置設定給ssh程序的資源時有時無,一些指令的bash程序會被殺調,以保證系統程序不超過設定的最大程序數,無法正常執行。即下面的第一個輸出要遠遠小與第二個和第三個輸出。如果有些接近就會出現這種問題

┌──[[email protected]]-[/]
└─$ ps -eLf | wc -l  # 目前程序數
221
┌──[[email protected]]-[/]
└─$ ulimit  -u  # 使用者的最大程序數
15665
┌──[[email protected]]-[/]
└─$ sysctl kernel.pid_max # 核心設定的最大程序數
kernel.pid_max = 150000
┌──[[email protected]]-[/]
└─$           

我是怎樣解決的

修改核心參數,調整最大程序數限制。這裡修改的話需要root權限,同時需要修改兩個地方。

其一:

使用者登入會加載

pam_limit

子產品,

pam_limit

子產品讀取配置檔案

/etc/security/limits.conf

來限制使用者資源的占用。可以使用

ulimit

的指令來檢視和臨時設定資源資訊,也可以通過 寫入

/etc/security/limits.conf

來永久配置,配置檔案在每次登入時會加載。可以用來設定

ssh

連接配接數,最大程序數等。

其二:

Linux系統中核心kernel子產品,有個全局的設定最大程序數的核心參數,需要修改這個參數,核心參數的設定方式有臨時設定和永久設定兩種方式,臨時設定完就會重新整理,重新開機失效。可以先臨時設定後檢視效果,然後永久設定。

人生當苦無妨,良人當歸即好.——烽火戲諸侯《雪中悍刀行》

檢視目前使用者的活躍程序數

┌──[[email protected]]-[/]
└─$ ps -eLf | wc -l  # 目前程序數
221           

檢視使用者允許運作的最大程序數

┌──[[email protected]]-[~]
└─$ 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) 15665
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
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) 15665
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited  # 無限大
┌──[[email protected]]-[~]
└─$           

ulimit為shell内建指令,可用來控制shell執行程式的資源。

文法:

ulimit [-aHS][-c <core檔案上限>][-d <資料節區大小>][-f <檔案大小>][-m <記憶體大小>][-n <檔案數目>][-p <緩沖區大小>][-s <堆棧大小>][-t <CPU時間>][-u <程式數目>][-v <虛拟記憶體大小>]

參數: --
-a  顯示目前資源限制的設定。
-c <core檔案上限>  設定core檔案的最大值,機關為區塊。
-d <資料節區大小>  程式資料節區的最大值,機關為KB。
-f <檔案大小>  shell所能建立的最大檔案,機關為區塊。
-H  設定資源的硬性限制,也就是管理者所設下的限制。
-m <記憶體大小>  指定可使用記憶體的上限,機關為KB。
-n <檔案數目>  指定同一時間最多可開啟的檔案數。
-p <緩沖區大小>  指定管道緩沖區的大小,機關512位元組。
-s <堆棧大小>  指定堆棧的上限,機關為KB。
-S  設定資源的彈性限制。
-t <CPU時間>  指定CPU使用時間的上限,機關為秒。
-u <程序數目>  使用者最多可開啟的程序數目。
-v <虛拟記憶體大小>  指定可使用的虛拟記憶體上限,機關為KB。
┌──[[email protected]]-[~]
└─$ ulimit  -u
15665           
預設值
使用者 描述

root 賬号

ulimit -u

的值 預設是

/proc/sys/kernel/threads-max

的值

/2

,即

系統線程數的一半

普通賬号

ulimit -u

/etc/security/limits.d/20-nproc.conf

修改使用者允許運作的最大程序數

臨時修改

┌──[[email protected]]-[~]
└─$ ulimit  -u 75535
┌──[[email protected]]-[~]
└─$ ulimit  -u
75535
┌──[[email protected]]-[~]
└─$           

永久修改

/etc/security/limits.conf

檔案裡添加如下内容

* soft nproc 65535      

* hard nproc 65535               
關鍵字

nproc

是作業系統級别對每個使用者建立的程序數的限制

nofile

是每個程序可以打開的檔案數的限制

soft

xxx
代表警告的設定,可以超過這個設定值,但是超過後會有警告。

hard

代表嚴格的設定,不允許超過這個設定的值。
┌──[[email protected]]-[~]
└─$  echo "* soft nproc 65535"  >> /etc/security/limits.conf
┌──[[email protected]]-[~]
└─$ echo "* hard nproc 65535"  >> /etc/security/limits.conf
┌──[[email protected]]-[~]
└─$ cat /etc/security/limits.conf  | grep nproc
#        - nproc - max number of processes
#@student        hard    nproc           20
#@faculty        soft    nproc           20
#@faculty        hard    nproc           50
#ftp             hard    nproc           0
* soft nproc 65535
* hard nproc 65535
┌──[[email protected]]-[~]
└─$           

從新通過ssh的方式登入,就會重新整理 ulimit -u的值

檢視Linux核心子產品kernel允許的最大程序數

檢視

kernel.pid_max

的核心參數

┌──[[email protected]]-[~]
└─$ sysctl -a | grep pid_max  #檢視pid的核心參數
kernel.pid_max = 131072
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.br-0e0cdf9c70b0.stable_secret"
sysctl: reading key "net.ipv6.conf.br-4b3da203747c.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.docker0.stable_secret"
sysctl: reading key "net.ipv6.conf.ens32.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
┌──[[email protected]]-[/]
└─$ sysctl kernel.pid_max
kernel.pid_max = 131072           

根據變量找到對應的核心參數檔案位置

┌──[[email protected]]-[~]
└─$ cd /proc/sys/kernel/;cat pid_max
131072           

調整

kernel.pid_max

核心參數

臨時調整核心參數

┌──[[email protected]]-[/proc/sys/kernel]
└─$ echo 150000 > pid_max
┌──[[email protected]]-[/proc/sys/kernel]
└─$ cat pid_max  # 臨時調整核心參數
150000           

永久調整

kernel.pid_max

┌──[[email protected]]-[/]
└─$ echo "kernel.pid_max = 150000" >> /etc/sysctl.conf # 永久調整
┌──[[email protected]]-[/]
└─$ cat /etc/sysctl.conf | grep kernel
kernel.pid_max = 150000
┌──[[email protected]]-[/]
└─$ sysctl -p
net.ipv4.ip_forward = 1
vm.swappiness = 20
kernel.pid_max = 150000
┌──[[email protected]]-[/]
└─$           

繼續閱讀