uWSGI

Configuration example #

[uwsgi]

strict = true
master = true
enable-threads = true
vacuum = true                        ; Delete sockets during shutdown
single-interpreter = true
die-on-term = true                   ; Shutdown when receiving SIGTERM (default is respawn)
need-app = true

; logging
disable-logging = true
log-4xx = true
log-5xx = true
log-slow = true

; worker recycling
max-requests = 1000                  ; restart workers after this many requests
max-worker-lifetime = 3600           ; seconds, restart workers after this many seconds
reload-on-rss = 2048                 ; MB, restart workers after this much resident memory
worker-reload-mercy = 60             ; seconds, how long to wait before forcefully killing workers

; dynamic worker scaling (busyness)
cheaper-algo = busyness
processes = 500                      ; Maximum number of workers allowed
cheaper = 8                          ; Minimum number of workers allowed
cheaper-initial = 16                 ; Workers created at startup
cheaper-overload = 1                 ; Length of a cycle in seconds
cheaper-step = 16                    ; How many workers to spawn at a time

cheaper-busyness-multiplier = 30     ; How many cycles to wait before killing workers
cheaper-busyness-min = 20            ; Below this threshold, kill workers (if stable for multiplier cycles)
cheaper-busyness-max = 70            ; Above this threshold, spawn new workers
cheaper-busyness-backlog-alert = 16  ; Spawn emergency workers if more than this many requests are waiting in the queue
cheaper-busyness-backlog-step = 2    ; How many emergegency workers to create if there are too many requests in the queue

;
harakiri = 60                        ; Forcefully kill workers after 60 seconds

;
py-call-osafterfork = true

;
auto-procname = true
procname-prefix-spaced = myapp


; autoreload in development, when this file is touched
touch-reload = /etc/myapp.ini

Explanation #

Basic #

  • strict mode

tells uWSGI to fail to start if any parameter in the configuration file isn’t explicitly understood by uWSGI.

  • master

The master uWSGI process is necessary to gracefully re-spawn and pre-fork workers, consolidate logs, and manage many other features (shared memory, cron jobs, worker timeouts…). Without this feature on, uWSGI is a mere shadow of its true self.

  • enable-threads

By default the Python plugin does not initialize the GIL. This means your app-generated threads will not run.

  • vacuum

This option will instruct uWSGI to clean up any temporary files or UNIX sockets it created, such as HTTP sockets, pidfiles, or admin FIFOs.

  • single-interpreter

By default, uWSGI starts in multiple interpreter mode, which allows multiple services to be hosted in each worker process.

  • die-on-term

it makes uWSGI behave in the way that any sane developer would expect.

  • need-app

This parameter prevents uWSGI from starting if it is unable to find or load your application module.

Logging #

By default, uWSGI has rather verbose logging. It is reasonable to disable uWSGI’s standard logging, especially if your application emits concise and meaningful logs.

  • hard timeouts: harakiri

SIGKILL workers after a specified number of seconds

  • request log format

https://uwsgi-docs.readthedocs.io/en/latest/LogFormat.html

Default request logging format:

log-format = [pid: %(pid)|app: -|req: -/-] %(addr) (%(user)) {%(vars) vars in %(pktsize) bytes} [%(ctime)] %(method) %(uri) => generated %(rsize) bytes in %(msecs) msecs (%(proto) %(status)) %(headers) headers in %(hsize) bytes (%(switches) switches on core %(core))

references #

https://uwsgi-docs.readthedocs.io/en/latest/Options.html https://uwsgi-docs.readthedocs.io/en/latest/Configuration.html https://uwsgi-docs.readthedocs.io/en/latest/ConfigLogic.html https://uwsgi-docs.readthedocs.io/en/latest/ThingsToKnow.html https://www.bloomberg.com/company/stories/configuring-uwsgi-production-deployment/ https://stackoverflow.com/questions/69396898/trying-to-figure-out-uwsgi-thread-workers-configuration https://www.cnblogs.com/zhouej/archive/2012/03/25/2379646.html