线上生产环境用 shell 脚本并发执行 php ,时间长了几乎每个脚本都有大量睡眠状态的进程一直挂在后台,像这样
:
8 号唤起的进程还挂在后台
以 994032 为例,用 strace 查看状态返回:
strace -p 994032
strace: Process 994032 attached
futex(0x563cb97ec830, FUTEX_WAIT_PRIVATE, 2, NUL
Google 了 FUTEX_WAIT_PRIVATE 说是等待唤醒,但是如果不 kill 的话永远不会唤醒
查看运行时间:
ps -p 994032 -p etime
ELAPSED
8-21:56:58
#!/bin/bash
pid=$$
name=`basename $0`
ps -ef|awk -v p=$pid -v n=$name '$2!=p && $NF~n{system("kill "p)}' #禁止重复运行
ids=$(/usr/bin/php /www/wwwroot/index_cli.php UploadImag/get_id) #获取 id ,一般会返回几万个 ID ,格式是这样的 (1 2 3 5 6 7)
temp_fifo_file=$$.info #以当前进程号,为临时管道取名
mkfifo $temp_fifo_file #创建临时管道
exec 6<>$temp_fifo_file #创建标识为 6 ,可以对管道进行读写
rm $temp_fifo_file #清空管道内容
temp_thread=80 #进程数
for ((i=0;i<temp_thread;i++)) #为进程创建相应的占位
do
echo #每个 echo 输出一个回车,为每个进程创建一个占位
done >&6 #将占位信息写入标识为 6 的管道
for loop in $ids
do
read #获取标识为 6 的占位
{
/usr/bin/php /www/wwwroot/index_cli.php UploadImag/upload_img/id/$loop #后台执行抓取程序
echo >&6 #>>>>>当任务执行完后,会释放管道占位,所以补充一个占位
}& #>>>>>在后台执行{}中的任务
done <&6 #将标识为 6 的管道作为标准输入
wait #等待所有任务完成
exec 6>&- #关闭标识为 6 的管道
*/5 * * * * /bin/sh /www/wwwroot/cron/UploadImag.sh
发展到现在已经有几百个这样的 shell 脚本,几乎全部存在进程卡住的情况
系统是 centos7
php5.4 版本
请教这种进程卡住的情况应该怎么解决?
1
zhoudaiyu 2022-05-17 23:59:41 +08:00 via iPhone
strace -fp 994032 看看
|
2
xyjincan 2022-05-18 05:31:51 +08:00 via Android
有些系统资源可能默认有限,不够了,ulimit -a
|
3
AnjingJingan OP @xyjincan 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) 513912 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) 513912 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited |
4
AnjingJingan OP @zhoudaiyu 994032 kill 了,换了个同样情况的 pid
strace: Process 911015 attached futex(0x56260c3e7af0, FUTEX_WAIT_PRIVATE, 2, NULL |
5
zhoudaiyu 2022-05-18 10:14:02 +08:00
@AnjingJingan #4 我的意思是追踪的时候加上参数 f ,这样可以跟踪子进程 /线程的系统调用
|
6
AnjingJingan OP @zhoudaiyu 加了 f 也是返回这个,4 楼回复就是加了 f 的
strace -fp 911015 strace: Process 911015 attached futex(0x56260c3e7af0, FUTEX_WAIT_PRIVATE, 2, NULL |
7
julyclyde 2022-05-18 12:40:10 +08:00
@xyjincan 肯定不是 rlmit 的问题啊;而且你用 ulimit 看的是自己 shell 的 rlimit ,并不是这个后台进程的 rlimit
|
8
AnjingJingan OP shell 脚本换了个执行用户,只要使用非 root 用户执行,就不会出现这种现象
不清楚原理,记录一下。。。 |