[Debian] Systemd loading configuration twice
OneCricketeer opened this issue · comments
Quick background
- Running a Debian-like distribution and installed
supervisor
viaapt-get
. - Using supervisor to run a Python Tornado Web Server on a total of 4 ports which is load-balanced via an Nginx reverse proxy
Problem
I am seeing 2 sets of my Python configuration for a total of 8 python
processes, 2 for each of the 4 ports that I run my web-app on. 1 of these sets seems to randomly be started and not managed by supervisor
. I have no idea where this set could be started from or how to properly manage it.
For example
Checking the supervisor service
sudo systemctl status supervisor
You can see there is 8 distinct processes, but 2 sets of port numbers (8000-8003).
● supervisor.service - LSB: Start/stop supervisor
Loaded: loaded (/etc/init.d/supervisor)
Active: active (running) since Wed 2015-12-23 18:19:58 CST; 13min ago
Process: 754 ExecStart=/etc/init.d/supervisor start (code=exited, status=0/SUCCESS)
CGroup: /system.slice/supervisor.service
├─760 /usr/bin/python /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
├─765 python server.py --port=8002
├─770 python server.py --port=8003
├─771 python server.py --port=8000
├─772 python server.py --port=8001
├─777 python server.py --port=8001
├─778 python server.py --port=8002
├─779 python server.py --port=8003
└─780 python server.py --port=8000
Can see the same thing with ps
sudo ps -aux | egrep "supervisor|python"
root 760 0.2 2.7 14496 9892 ? Ss 18:19 0:01 /usr/bin/python /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
www-data 765 0.3 3.9 16860 14156 ? S 18:19 0:02 python server.py --port=8002
www-data 770 0.3 3.9 16872 14216 ? S 18:19 0:02 python server.py --port=8003
www-data 771 0.3 3.8 16872 14008 ? S 18:19 0:02 python server.py --port=8000
www-data 772 0.3 3.9 16860 14220 ? S 18:19 0:02 python server.py --port=8001
www-data 777 0.0 3.4 17116 12420 ? S 18:20 0:00 python server.py --port=8001
www-data 778 0.0 3.0 16860 11184 ? S 18:20 0:00 python server.py --port=8002
www-data 779 0.0 3.1 16872 11264 ? S 18:20 0:00 python server.py --port=8003
www-data 780 0.0 3.4 17128 12456 ? S 18:20 0:00 python server.py --port=8000
Stop supervisor
via systemctl
sudo systemctl stop supervisor
sudo systemctl status supervisor
● supervisor.service - LSB: Start/stop supervisor
Loaded: loaded (/etc/init.d/supervisor)
Active: inactive (dead)
sudo supervisorctl status
unix:///var/run/supervisor.sock no such file
So, supervisor
has destroyed the socket file, BUT running ps
again shows
sudo ps -aux | egrep "supervisor|python"
www-data 777 0.0 3.4 17116 12420 ? S 18:20 0:00 python server.py --port=8001
www-data 778 0.0 3.0 16860 11184 ? S 18:20 0:00 python server.py --port=8002
www-data 779 0.0 3.1 16872 11264 ? S 18:20 0:00 python server.py --port=8003
www-data 780 0.0 3.4 17128 12456 ? S 18:20 0:00 python server.py --port=8000
Here are my relevant config files. And I am using the default initscript that was included with apt-get install supervisor
. That is located at /etc/init.d/supervisor
.
/etc/supervisor/supervisord.conf
[unix_http_server]
file=/var/run/supervisor.sock
chmod=0700
[supervisord]
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
childlogdir=/var/log/supervisor
logfile_maxbytes=50MB
logfile_backups=5
loglevel=error
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock
[include]
files = /etc/supervisor/conf.d/*.conf
/etc/supervisor/conf.d/tornado.conf
[program:tornado]
numprocs = 4
numprocs_start = 8000
process_name = %(program_name)s_%(process_num)02d
directory=/home/username/webapp
environment=PATH="/home/username/.virtualenvs/tornado_env/bin"
command = python server.py --port=%(process_num)s
user=www-data
redirect_stderr=true
stdout_logfile=/var/log/webapp/%(program_name)s_%(process_num)02d.log
loglevel=info
Running a Debian-like distribution and installed supervisor via apt-get.
Please report this to the maintainers of the Debian package you installed with apt-get
. The Debian packages are created and maintained by people that are not part of the Supervisor project. Those packages use their own init scripts. Those init scripts are not provided by the Supervisor project itself. The developers of the Debian package would be the only ones that could provide support and make fixes to their scripts.
This repository contains various user-contributed init scripts for Supervisor. Since you are not using one of these scripts, I'll close this issue.
@mnaberez And what if the only difference between the Ubuntu version here and the Debian package version I have is the status command? The start, stop, and restart are the same.
The example Ubuntu init script in this repository was submitted by a user and is just copied from Ubuntu itself. The best place to get support or fixes for the package you installed with apt-get
is to contact the Debian or Ubuntu maintainers responsible for the package.
Per the README, the scripts in this repository are user-contributed and the Supervisor maintainers can't provide support. We are just collecting them in one place at the request of users.
@mnaberez Okay. I've now determined the Debian package nor the initscript is the problem.
Using the same configs as previously stated.
$ which supervisord
/usr/bin/supervisord
$ sudo apt-get purge supervisor
$ sudo pip install supervisor
$ which supervisord
/usr/local/bin/supervisord
$ sudo /usr/local/bin/supervisord -c /etc/supervisor/supervisor.conf
$ ps -aux | grep python
root 546 0.1 2.6 16104 9644 ? Ss 01:11 0:00 /usr/bin/python /usr/local/bin/supervisord -c /etc/supervisor/supervisor.conf
www-data 547 1.2 3.9 17988 14176 ? S 01:11 0:02 python server.py --port=8002
www-data 548 1.2 3.8 17988 14120 ? S 01:11 0:02 python server.py --port=8003
www-data 549 1.2 3.9 17988 14136 ? S 01:11 0:02 python server.py --port=8000
www-data 550 1.2 3.9 17988 14196 ? S 01:11 0:02 python server.py --port=8001
www-data 559 0.0 3.0 17988 11156 ? S 01:12 0:00 python server.py --port=8003
www-data 560 0.0 3.0 17988 11220 ? S 01:12 0:00 python server.py --port=8000
www-data 561 0.0 3.0 17988 11172 ? S 01:12 0:00 python server.py --port=8002
www-data 562 0.0 3.0 17988 11188 ? S 01:12 0:00 python server.py --port=8001
If I understand correctly, you expected supervisord
to spawn 4 processes but you see more than that in the ps
output.
Minimal supervisord.conf
:
[supervisord]
loglevel=info
[inet_http_server]
port = 127.0.0.1:9001
[supervisorctl]
serverurl = http://127.0.0.1:9001
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[program:cat]
command = /bin/cat
numprocs = 4
numprocs_start = 8000
process_name = %(program_name)s_%(process_num)02d
program = /bin/cat
Start supervisord
in the foreground with that config:
$ supervisord --version
3.2.0
$ supervisord -n -c /path/to/supervisord.conf
Four processes are spawned:
2015-12-23 23:30:35,273 INFO Increased RLIMIT_NOFILE limit to 1024
2015-12-23 23:30:35,285 INFO RPC interface 'supervisor' initialized
2015-12-23 23:30:35,285 CRIT Server 'inet_http_server' running without any HTTP authentication checking
2015-12-23 23:30:35,285 INFO supervisord started with pid 65707
2015-12-23 23:30:36,291 INFO spawned: 'cat_8003' with pid 65710
2015-12-23 23:30:36,293 INFO spawned: 'cat_8002' with pid 65711
2015-12-23 23:30:36,295 INFO spawned: 'cat_8001' with pid 65712
2015-12-23 23:30:36,297 INFO spawned: 'cat_8000' with pid 65713
2015-12-23 23:30:37,302 INFO success: cat_8003 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2015-12-23 23:30:37,302 INFO success: cat_8002 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2015-12-23 23:30:37,302 INFO success: cat_8001 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2015-12-23 23:30:37,302 INFO success: cat_8000 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
I watched the log while doing various combinations of supervisorctl stop
, start
, and status
. I never saw supervisord
spawn more than 4, and I never saw it orphan any processes.
I think if the above works for you, then the orphaned processes you see are probably being caused by one of the following:
supervisord
receivedSIGKILL
and thus exited immediately, orphaning its children.- Your program
python server.py
forks its own children (trypstree
to check this). Ifsupervisord
sentSIGKILL
to your program, and you did not setkillasgroup=true
, then your program exited immediately and orphaned its children.
You were correct about my python server.py
forking its own children (I didn't have pstree
to see this, so had to search the Python Tornado Documentation for the example I took). So, yeah, apparently one server process is started per CPU, which doesn't make any sense on my single core Raspberry Pi, but whatever.
Adding stopasgroup=true
does seem to fix the unmanaged child processes.
Thank you very much.
Another question, though. From your minimal conf, I see you use [inet_http_server]
. I am trying to use [unix_http_server]
since I don't need the Web UI.
I believe I have the correct configuration between [unix_http_server]
and [supervisorctl]
as I was able to successfully use the supervisorctl
command via a socket before I installed the lastet supervisor
from pip
.
When I run supervisorctl
now, all I get is http://localhost:9001 refused connection
. If I keep [inet_http_server]
, it works and I can see the page from http://localhost:9001
, but as I said, I don't need it. So, I removed [inet_http_server]
, added [unix_http_server]
, and set the appropriate values.
My question is if I replaced [inet_http_server]
with [unix_http_server]
and my [supervisorctl]
section has serverurl = unix:///var/run/supervisord.sock
, why does it try to connect over http and how do I properly setup the socket?
When I run supervisorctl now, all I get is http://localhost:9001 refused connection. If I keep [inet_http_server], it works and I can see the page from http://localhost:9001, but as I said, I don't need it. So, I removed [inet_http_server], added [unix_http_server], and set the appropriate values.
If you ran supervisorctl
with no arguments, then supervisorctl
is searching for a config file. If it doesn't find a config file, it will still run, but will use built-in defaults. To make sure you are running supervisorctl
with the correct config file, specify the path with -c
:
$ supervisorctl -c /etc/supervisor/supervisord.conf
You said you changed from using a Debian-packaged version (apt-get install
) of Supervisor to the PyPI version (pip install
). I have seen Debian packaged versions where the Debian maintainers have modified supervisord
and supervisorctl
to additionally search for /etc/supervisor/supervisord.conf
. No PyPI version of Supervisor has ever searched for this path as of Supervisor 3.2.0 (see the page linked above). If your config file is still in /etc/supervisor/supervisord.conf
, that could explain the behavior.