安装
https://www.yuque.com/docs/share/1d5ba458-e729-4059-afcf-d9ba3a33ede3?#
使用 docker
docker search php
webdevops/php-nginx
docker run -p 80:80 -p 443:443 -p 9000:9000 -p 9001:9001 -v /Users/mac/PhpstormProjects:/app -itd 4edee5cecbe7
1. 配置文件
配置简介 : https://www.kancloud.cn/dargon/supervisor/1134310
supervisor_demo.conf
[unix_http_server]
file=/run/supervisord.sock ; (the path to the socket file)
[inet_http_server] ; inet (TCP) server disabled by default
port=0.0.0.0:9001 ; (ip_address:port specifier, *:port for all iface)
username=admin ; (default is no username (open server))
password=123456 ; (default is no password (open server))
[supervisord]
logfile=/var/log/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=100MB
logfile_backups=10
loglevel=info ; (log level;default info; others: debug,warn,trace)
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///run/supervisord.sock ; use a unix:// URL for a unix socket
[program:demo_worker_name1]
directory=/app/demo_supervisor
command=php main1.php
autostart=true
autorestart=true
startsecs=10
startretries=2
numprocs=1
process_name=%(process_num)02d
user=root
stdout_logfile=/var/log/demo1.log
stderr_logfile=/var/log/demo1_err.log
[program:demo_worker_name2]
directory=/app/demo_supervisor
command=php main2.php
autostart=true
autorestart=true
startsecs=10
startretries=2
numprocs=2
process_name=%(process_num)02d
user=root
stdout_logfile=/var/log/demo2.log
stderr_logfile=/var/log/demo2_err.log
[include]
files = /etc/supervisor.d/*.ini
1. 启动&应用配置
supervisord -c /app/demo_supervisor/supervisor_demo.conf
3. 重新应用配置文件
supervisorctl -c /app/demo_supervisor/supervisor_demo.conf
> reload
4. 测试文件
main1.php
<?php
$i = 0;
while (true) {
$i++;
print_r("num: " . $i . PHP_EOL);
sleep(1);
if ($i > 300) {
break;
}
}
print_r("end");
main2.php
<?php
for ($num = 1; $num <= 5; ++$num) {
$pid = pcntl_fork();
if (!$pid) {
printNum($num);
}
}
function printNum($num) {
$i = 0;
while (true) {
$i++;
print_r("num: " . $num . " i :" . $i . PHP_EOL);
sleep(1);
if ($i > 300) {
break;
}
}
exit($num . "fork end");
}
while (pcntl_waitpid(0, $status) != -1) {
$status = pcntl_wexitstatus($status);
echo "Child $status completed\n";
}
/**
$j = 0;
while (true) {
$j++;
print_r("now: " . $j . PHP_EOL);
sleep(1);
}
*/
监听事件到mysql中.
#!/usr/local/supervisord/bin/python
# coding:utf-8
# author: mk
from supervisor import childutils
import socket
import pymysql
import pymysql.cursors
import sys
import os
import time
def execute(hostname, ip, process_name, process_pid, from_state, curr_state, timestamp):
"""
数据写入/更新,由主机名,IP地址,进程名组成唯一索引
:param hostname: 主机名
:param ip: IP地址
:param process_name: 进程名
:param process_pid: 进程ID
:param from_state: 上次状态
:param curr_state: 当前状态
:param timestamp: 更新时间
:return: void
"""
user, passwd = ('root', '')
conn = pymysql.connect(
host="192.168.199.202",
port=3306,
user=user,
db='test',
password=passwd
)
with conn:
with conn.cursor() as cursor:
# 查询一条单记录
sql = "SELECT `id` FROM `supervisor` WHERE `hostname`=%s AND `ip`=%s AND `process_name`=%s"
count = cursor.execute(sql, (hostname,ip, process_name))
if count:
sql = "UPDATE `supervisor` SET `process_pid`=%s,`from_state`=%s,`curr_state`=%s, `timestamp`=%s WHERE `hostname`=%s AND `ip`=%s AND `process_name`=%s"
cursor.execute(sql, (process_pid, from_state, curr_state, timestamp, hostname,ip, process_name))
else:
sql = "INSERT INTO `supervisor` (`id`,`hostname`, `ip`, `process_name`, `process_pid`, `from_state`, `curr_state`,`timestamp`) VALUES (null,%s,%s,%s,%s,%s,%s,%s)"
cursor.execute(sql, (hostname, ip, process_name, process_pid, from_state, curr_state, timestamp))
conn.commit()
class Agent(object):
def __init__(self):
self.stdout = sys.stdout
self.stdin = sys.stdin
self.stderr = sys.stderr
def runForever(self, debug=False):
while True:
headers, payload = childutils.listener.wait(self.stdin, self.stdout)
if not headers['eventname'] in [
'PROCESS_STATE_EXITED', # 退出
'PROCESS_STATE_STARTING', # 启动
'PROCESS_STATE_RUNNING', # 运行
'PROCESS_STATE_BACKOFF', # 倒退
'PROCESS_STATE_STOPPING', # 停止
'PROCESS_STATE_STOPPED', # 停止
]:
pass
pheaders, pdata = childutils.eventdata(payload + '\n')
hostname = socket.gethostname()
ip = socket.gethostbyname(hostname)
process_name = pheaders['processname']
process_pid = pheaders['pid']
from_state = pheaders['from_state']
curr_state = headers['eventname'].split('_')[2]
if debug:
with open('/tmp/debug', 'w+') as file:
file.write(str(headers)+"\n")
file.write(str(payload)+"\n")
execute(hostname, ip, process_name, process_pid, from_state, curr_state, int(time.time()))
childutils.listener.ok(self.stdout)
def main():
if not 'SUPERVISOR_SERVER_URL' in os.environ:
sys.stderr.write('crashmail must be run as a supervisor event '
'listener\n')
sys.stderr.flush()
return
agent = Agent()
agent.runForever(True)
if __name__ == '__main__':
main()