天天看點

php中的system方法偶爾會出現unable to fork

背景

php代碼中調用了system方法,執行了shell腳本,一開始運作正常,過一段時間偶爾會出現unable to fork的報錯

問題原因

system調用會fork新的程序,因為每個使用者有最大程序數限制,簡單的說就是達到使用者的程序上限了

如何限制linux使用者的程序數

這個可以通過修改如下檔案來設定:

vi /etc/security/limits.conf

vpsee hard nproc 32

@student hard nproc 32

@faculty hard nproc 64

限制vpsee這個使用者隻能 fork 32 個程序

限制 student 這個使用者組的每個成員最多能fork 32 個程序

限制 faculty 這個使用者組的每個成員最多能 fork 64 個程序。

不過要事先檢查系統是否有pam_limits.so 這個子產品以及是否已經加載:

ls /lib64/security/pam_limits.so

/lib64/security/pam_limits.so

vi /etc/pam.d/login

session required pam_loginuid.so

如果自己是 Linux 普通使用者,不是 root 使用者不能修改 limits.conf 和重新開機系統的話,可以用 ulimit來臨時限制自己允許建立的程序數,ulimit 有 Hard 和 Soft 兩種方法限制

用 Hard的話可以減少最大可用的程序數,但是就不能重新增大這個限制了;用 Soft 的話可以自己自由增大和減小限制(ulimit,-H 和 -S的詳細說明可以參看 man ulimit)。

不同的 Linux 版本對這個 ulimit -u 的預設值不同,在 CentOS上預設情況下最大運作程序數是 8256,在 Fedora 上是1024,不過改成32後就不能再改成比32更大的了(比如64),隻能再改成比32小的

ulimit 不帶 -H 和 -S 參數的時候同時設定 Hard 和 Soft:

ulimit -u

65535

ulimit -u 65534

ulimit -u 65535

-bash: ulimit: max user processes: cannot modify limit: Operation not permitted

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) 30493

max locked memory       (kbytes, -l) 64

max memory size         (kbytes, -m) unlimited

open files                      (-n) 65535

pipe size            (512 bytes, -p) 8

POSIX message queues     (bytes, -q) 819200

real-time priority              (-r) 0

stack size              (kbytes, -s) 10240

cpu time               (seconds, -t) unlimited

max user processes              (-u) 65534

virtual memory          (kbytes, -v) unlimited

file locks                      (-x) unlimited

檢視各系統使用者的程序數(LWP)

預設情況下采用 ps 指令并不能顯示出所有的程序。因為 Linux 環境下執行多線程,每個線程都将以一個輕量級程序(light-weight process [LWP])的形式執行,而 ps 指令如果不帶 -L 選項将無法檢視 LWP。

檢視各系統使用者的程序數的指令如下所示,執行後可得類似如下結果。

ps h -Led -o user | sort | uniq -c | sort -n

      2 nobody

      3 redis

     34 www

     64 mysql

    174 root

如果某個使用者的 nproc 的軟限制小于其運作中的程序數,則切換使用者時将報錯 "su: cannot set user id: Resource temporarily unavailable"

參數詳解:

h  :   No header. (or, one header per screen in the BSD personality) ,The h option is problematic. Standard BSD ps uses this option to print a header on each page of output, but older Linux ps uses this option to totally disable the header. This version of ps follows the Linux usage of not printing the header unless the BSD personality has been selected, in which case it prints a header on each page of output. Regardless of the current personality,you can use the long options --headers and --no-headers to enable printing headers each page or disable headers entirely, respectively.

譯:簡單說就是不輸出header,但是Standard BSD 會用它展示header,最好用  --no-headers 參數更明确

-L  :Show threads, possibly with LWP and NLWP columns

譯:展示輕量級程序

-e :  Select all processes.  Identical to -A

-d :  Select all processes except session leaders.

什麼是session leader。參考該解釋:​​http://www.win.tue.nl/~aeb/linux/lk/lk-10.html#ss10.3​​

-o : user-defined format

譯:隻輸出哪些列  user:所屬使用者  nlwp:輕量級程序數量 lwp: 輕量級程序ID   args:指令

确定某使用者的程序(LWP)數的分布情況

根據上面的指令可确定 nproc 參數接近上限的問題使用者,随後應确定該使用者程序數(LWP)的分布情況。

ps -o nlwp,pid,lwp,args -u username | sort -n

其中 username 為系統使用者名,根據查詢結果,便可輕易确定存在問題的程式。如果程式均正常,而 nproc 參數已接近上限值,則需修改 nproc 參數。

解決方法

繼續閱讀