current position:Home>Introduction to Python gunicorn

Introduction to Python gunicorn

2022-02-01 20:12:32 waws520

gunicorn It's a python Wsgi http server, Only in Unix Running on the system , originate Ruby Of unicorn project .Gunicorn Use prefork master-worker Model ( stay gunicorn in ,master go by the name of arbiter), Be able to work with all kinds of wsgi web Framework collaboration .gunicorn The document is relatively perfect , here There are also some Chinese translations , However, it is recommended to read English documents directly .

  gunicorn The installation of is very simple ,pip install guncorn that will do . If asynchronous is used later worker Model , You also need to install the corresponding module ( Such as gevent)

   I'm putting it on gunicorn after , Let's see gunicorn Of hello world. Code from official website , Put the following code into gunicorn_app.py in :

def app(environ, start_response):
    data = b"Hello, World!\n"
    start_response("200 OK", [("Content-Type", "text/plain"),("Content-Length", str(len(data)))])  
    return iter([data])
 Copy code 

You can see app It's very standard wsgi application , And then we start gunicorn:gunicorn -w 2 gunicorn_app:app. Output is as follows :

The figure above shows two very important information :
First of all : Started two worker, This is through "-w 2" Appoint ( The default is 1)
second :worker The working model is sync( Default ), More on that later worker Model

And then on the other terminal function :ps -ef | grep python 

It can be seen that worker process (pid:19469, 19470) yes master process (pid:19464) Can be inherited by child processes. .

A new one terminal, use curl test :  curl 127.0.0.1:8000, In the terminal Output “Hello, World!”

Mentioned earlier , official gunicorn Only in Unix Up operation ( It seems that there are non official website patches , To enable it to be in windows Up operation , Without verification ), Mainly because the source code uses fcntl,os.fork Wait only unix Modules and interfaces that exist on .pre-fork Is refers to gunicorn When it starts , In the main process, there will be fork Give out the specified quantity (-w) Of worker process . Here is a brief introduction Master Worker workflow , The code will be introduced in detail later .

start-up gunicorn, Initialize first gunicorn.app.base.Application( Or base class , For example, when starting from the command line above , yes wsgiApplication), The most important thing in initialization is to read the configuration , Support files or command lines . And then call Application.run(), The method code is as follows :

def run(self):
    try:
        Arbiter(self).run()
    except RuntimeError as e:
        print("\nError: %s\n" % e, file=sys.stderr)
        sys.stderr.flush()
        sys.exit(1)
 Copy code 

call Arbiter(self).run() after , The main process (master) All the logic of runs in Arbiter In class .

Arbiter First read the configuration item , Such as worker Number ,worker Working mode , Listening address, etc ; Then initialize the signal processing function , Then build socket, But not listen; Next fork Out of all the worker process ; Finally enter the cycle : Process signals in the signal queue , Kill and restart the unresponsive child process , If you have nothing to do , Just “sleep” For a while .

worker The process is simpler , The first is to read the configuration , Initialize the signal processing function , Then enter the cycle : Handle requests on the listening port ( That is, it will call wsgi app The place of ), And then to master Report yourself alive . in addition ,worker In, the signal is processed directly when the signal occurs , Not like it master Put it into the signal queue .

You can change it a little app Code , So that when the client requests , The server can print the call stack , Here is the output on my machine , It will be right Arbiter and worker To introduce .

  • 0: FUNC:app(...)                  /home/xxx/gunicorn_app.py::16
  • 1: FUNC:handle_request(...)       /usr/local/lib/python2.7/dist-packages/gunicorn/workers/sync.py::176
  • 2: FUNC:handle(...)               /usr/local/lib/python2.7/dist-packages/gunicorn/workers/sync.py::135
  • 3: FUNC:accept(...)               /usr/local/lib/python2.7/dist-packages/gunicorn/workers/sync.py::30
  • 4: FUNC:run_for_one(...)          /usr/local/lib/python2.7/dist-packages/gunicorn/workers/sync.py::68
  • 5: FUNC:run(...)                  /usr/local/lib/python2.7/dist-packages/gunicorn/workers/sync.py::124
  • 6: FUNC:init_process(...)         /usr/local/lib/python2.7/dist-packages/gunicorn/workers/base.py::132
  • 7: FUNC:spawn_worker(...)         /usr/local/lib/python2.7/dist-packages/gunicorn/arbiter.py::557
  • 8: FUNC:spawn_workers(...)        /usr/local/lib/python2.7/dist-packages/gunicorn/arbiter.py::590
  • 9: FUNC:manage_workers(...)       /usr/local/lib/python2.7/dist-packages/gunicorn/arbiter.py::524
  • 10: FUNC:run(...)                  /usr/local/lib/python2.7/dist-packages/gunicorn/arbiter.py::189
  • 11: FUNC:run(...)                  /usr/local/lib/python2.7/dist-packages/gunicorn/app/base.py::72
  • 12: FUNC:run(...)                  /usr/local/lib/python2.7/dist-packages/gunicorn/app/base.py::192
  • 13: FUNC:run(...)                  /usr/local/lib/python2.7/dist-packages/gunicorn/app/wsgiapp.py::74
  • 14: FUNC:(...)             /usr/local/bin/gunicorn::11

copyright notice
author[waws520],Please bring the original link to reprint, thank you.
https://en.pythonmana.com/2022/02/202202012012305944.html

Random recommended