Summary
Python server used for serving Django web requests at ICTC Solution Delivery
Commands
- Restart
service uwsgi-emperor status
service uwsgi-emperor restart
Installation
Emperor
- name: Install uWSGI emperor
apt: name=uwsgi-emperor state=present
- name: Configure uWSGI emperor
template:
src: emperor.ini.j2
dest: /etc/uwsgi-emperor/emperor.ini
owner: root
group: root
mode: 0644
notify: Restart uWSGI Emperor
- name: Create log directory
file:
path: /var/log/uwsgi/vassals
state: directory
owner: root
group: root
notify: Restart uWSGI Emperor
- name: Enable app server configuration (uWSGI emperor)
template:
src: uwsgi.ini.j2
dest: "/etc/uwsgi-emperor/vassals/{{ uwsgi_app_name }}.ini"
owner: root
group: root
mode: 0644
notify: Restart application vassal
- name: Configure logrotate for uwsgi-emperor vassal
template:
src: logrotate-emperor-vassals.j2
dest: /etc/logrotate.d/uwsgi-emperor-vassals
owner: root
group: root
mode: 0644
uwsgi
---
##########################
# Remove uWSGI Emperor
##########################
# Remove configuration files before purging package to allow apt to delete all
# configuration directories
- name: Remove uWSGI Emperor configuration
file:
path: "{{ item }}"
state: absent
loop:
- /etc/uwsgi-emperor/emperor.ini
- /etc/uwsgi-emperor/vassals
- name: Uninstall uWSGI emperor
apt: name=uwsgi-emperor state=absent purge=yes
#########################################
# Install and configure uWSGI
#########################################
- name: Install uWSGI
apt: name=uwsgi state=present
- name: Configure uWSGI
template:
src: uwsgi.ini.j2
dest: "/etc/uwsgi/apps-available/{{ uwsgi_app_name }}.ini"
owner: root
group: root
mode: 0644
notify: Restart uWSGI
- name: Enable app server configuration (uwsgi)
file:
src: "/etc/uwsgi/apps-available/{{ uwsgi_app_name }}.ini"
dest: "/etc/uwsgi/apps-enabled/{{ uwsgi_app_name }}.ini"
state: link
owner: root
group: root
notify: Restart uWSGI
- name: Disable app server configuration (uwsgi)
file:
path: "/etc/uwsgi/apps-enabled/{{ uwsgi_app_name }}.ini"
state: absent
when: uwsgi_disable_app|bool
notify: Restart uWSGI
Sample /etc/uwsgi-emperor/emperor.ini
[uwsgi]
emperor = /etc/uwsgi-emperor/vassals
Sample /etc/uwsgi-emperor/vassals/chemistry.ini
[uwsgi]
processes = 2
chdir = /opt/chemistry/code/chemistry
wsgi-file = chemistry/wsgi.py
virtualenv = /opt/chemistry/venv
env = DJANGO_SETTINGS_MODULE=chemistry.settings
master = true
vacuum = true
uid = chemistry
gid = chemistry
umask = 022
socket = 127.0.0.1:8125
chown-socket = chemistry:www-data
chmod-socket = 660
cpu-affinity = 1
max-requests = 5000
no-orphans = true
log-date = true
die-on-term = true
auto-procname = true
procname-prefix = chemistry|
thunder-lock = true
plugins = python3
logto = /var/log/uwsgi/vassals/chemistry.log
buffer-size = 4096
#listen = 100
#strict = true
#memory-report = true
#harakiri = 20
# For APM server
# https://www.elastic.co/guide/en/apm/agent/python/current/django-support.html
enable-threads = true
# https://uwsgi-docs.readthedocs.io/en/latest/articles/TheArtOfGracefulReloading.html#preforking-vs-lazy-apps-vs-lazy
lazy-apps = true
Issue I faced when I killed uwsgi processes
I wanted to stop a uwsgi vassal to make the service unavailalbe for Apache web server. I tried:
- `service uwsgi-emperor stop`
- `service uwsgi-emperor status`
● uwsgi-emperor.service - LSB: Start/stop uWSGI server instance(s)
Loaded: loaded (/etc/init.d/uwsgi-emperor; generated)
Active: active (running) since Thu 2021-06-17 12:30:06 +03; 2s ago
Docs: man:systemd-sysv-generator(8)
Process: 1396 ExecStart=/etc/init.d/uwsgi-emperor start (code=exited, status=0/SUCCESS)
Tasks: 10 (limit: 4701)
Memory: 96.8M
CGroup: /system.slice/uwsgi-emperor.service
├─1405 /usr/bin/uwsgi --ini /etc/uwsgi-emperor/emperor.ini --die-on-term --pidfile /run/uwsgi-emperor.pid -
├─1406 chemistry|uWSGI master
├─1407 chemistry|uWSGI worker 1
└─1408 chemistry|uWSGI worker 2
I tried killing the processes with PID 1405, but the vassals respawned.
- `killall uwsgi` This killed all the uwsgi process and vassals to the service unavailable.
The issue
but I could restart the emperor and vassals properly. Even tried deleting whole uswgi-emperor and re-installing it.
The Solution
restarting the emperor with `service uwsgi-emperor restart` was resuling in
root@apps-cms-1:~# journalctl -u uwsgi-emperor -f
-- Logs begin at Thu 2021-06-17 12:22:24 +03. --
Jun 17 12:22:40 apps-cms-1 systemd[1]: Starting LSB: Start/stop uWSGI server instance(s)...
Jun 17 12:22:42 apps-cms-1 uwsgi-emperor[745]: [uWSGI] getting INI configuration from /etc/uwsgi-emperor/emperor.ini
Jun 17 12:22:42 apps-cms-1 systemd[1]: Started LSB: Start/stop uWSGI server instance(s).
Jun 17 12:23:55 apps-cms-1 systemd[1]: Stopping LSB: Start/stop uWSGI server instance(s)...
Jun 17 12:23:55 apps-cms-1 uwsgi-emperor[1214]: *start-stop-daemon: matching on world-writable pidfile /run/uwsgi-emperor.pid is insecure*
I checked the file `/run/uwsgi-emperor.pid`
cat /run/uwsgi-emperor.pid
# result: 1405
I killed this process id(pid), deleted the `/run/uwsgi-emperor.pid` and re-deployed the application with ansible, and it worked.
-
Reason(not sure)
I killed all the uwsgi process with `killall uwsgi` but the file was referring to the already killed process, deleting the file forced uwsgi to re-creat the file with correct PID for the emperror.
banner-api performance optimization for registration
The issue
During the registration a Django application, course offering, was freezing because too many students trying to access it. Backend of this service is banner-api, Django application which sqlalchemy to connect with Oracle server, which fetches the course data.
Things to try
- try harakirir https://stackoverflow.com/a/58935674/5305401
- Other parameters tried https://adamj.eu/tech/2019/09/19/working-around-memory-leaks-in-your-django-app/?utm_source=pocket_mylist ``` max-requests = 500 max-requests-delta = 20 # percentage ```
https://www.cloudbees.com/blog/getting-every-microsecond-out-of-uwsgi ``` max-worker-lifetime = 30 ```
How uwsgi servers requests, threads, processes and optimizations?
https://www.reddit.com/r/Python/comments/4s40ge/understanding_uwsgi_threads_processes_and_gil/
Comparison of performance between uWSGI, gunicorn and other WSGI server
https://www.appdynamics.com/blog/engineering/a-performance-analysis-of-python-wsgi-servers-part-2/ Bjoern is a good option to try with Django.