Home Operation and Maintenance Safety How to analyze gunicorn Arbiter source code

How to analyze gunicorn Arbiter source code

May 12, 2023 pm 04:28 PM
gunicorn arbiter

As mentioned earlier, Arbiter is the core of the gunicorn master process. Arbiter is mainly responsible for managing worker processes, including starting, monitoring, and killing worker processes. At the same time, Arbiter can also hot update (reload) App applications or upgrade gunicorn online when certain signals occur. The core code of Arbiter is in one file, and the amount of code is not large. The source code is here: https://github.com/benoitc/gunicorn.

Arbiter mainly has the following methods:

setup:

Processing configuration items, the most important ones are the number of workers and the worker working model

init_signal

Register signal processing function

handle_xxx:

Specific processing function for each signal

kill_worker, kill_workers:

Send a signal to the worker process

spawn_worker, spawn_workers:

Fork to create a new worker Process

murder_workers:

Kill worker processes that have not responded for a period of time

manage_workers:

Based on the number of workers in the configuration file and the number of currently active workers, decide whether to fork or kill the worker process

reexec:

After receiving the signal SIGUSR2 call, online Upgrade gunicorn

#reload:

After receiving the signal SIGHUP call, the worker process will be started based on the new configuration and the previous worker process will be killed

sleep

When there is no signal processing, use the select timeout to sleep and can be woken up

wakeup

Wake up the process by writing messages to the pipe

run:

Main loop

The only functions of Arbiter that are actually called by other codes (Application) __init__ and run methods, in one line of code:

Arbiter(self).run()

The self in the above code is the Application instance, where_ _init__ calls setup to set configuration items. The following is the pseudo code of the run method


def run()
    self.init_signal()
    self.LISTENERS = create_sockets(self.cfg, self.log)
    self.manage_workers()    while True:        if no signal in SIG_QUEUE
            self.sleep()        else:
            handle_signal()
Copy after login


## About fork child process

fork child process The code is in spawn_worker, the source code is as follows:

Arbiter.spawn_worker如何进行gunicorn Arbiter 源码解析

Main process:

(1) Load worker_class and instantiate (default is synchronous model SyncWorker)

(2) The parent process (master process) returns after forking, and all subsequent logic is run in the child process

(3) Call worker.init_process to enter the loop, and all the new channel IELTS training The work is all in this loop

(4) After the loop ends, call sys.exit(0)

(5) Finally, in finally, record the exit of the worker process

The following is a bit of code I wrote myself, which simplifies the main fork process


 1 # prefork.py 2 import sys 3 import socket 4 import select 5 import os 6 import time 7   8 def do_sub_process(): 9     pid = os.fork()10     if pid < 0:11         print &#39;fork error&#39;12         sys.exit(-1)13     elif pid > 0:14         print 'fork sub process %d'  % pid15         return16  17     # must be child process18     time.sleep(1)19     print 'sub process will exit', os.getpid(), os.getppid()20     sys.exit(0)21  22 def main():23     sub_num = 224     for i in range(sub_num):25         do_sub_process()26     time.sleep(10)27     print 'main process will exit', os.getpid()28  29 if __name__ == '__main__':30     main()
Copy after login


Output in the test environment:

fork sub process 9601

fork sub process 9602

sub process will exit 9601 9600

sub process will exit 9602 9600

Main process will exit 9600

It should be noted that line 20 calls

sys.exit to ensure the end of the child process, otherwise the for loop in the main function will continue. , and the subsequent logic. Comment out line 19 and run again, and you will understand by looking at the output.

About killing child processes

It is very simple for the master process to kill the worker process. It sends a signal directly. The source code is as follows:


 1     def kill_worker(self, pid, sig): 2         """\ 3         Kill a worker 4  5         :attr pid: int, worker pid 6         :attr sig: `signal.SIG*` value 7          """ 8         try: 9             os.kill(pid, sig)10         except OSError as e:11             if e.errno == errno.ESRCH:12                 try:13                     worker = self.WORKERS.pop(pid)14                     worker.tmp.close()15                     self.cfg.worker_exit(self, worker)16                     return17                 except (KeyError, OSError):18                     return19             raise
Copy after login


About sleep and wakeup

Let’s take a look at Arbiter’s sleep and wakeup. Arbiter will "sleep" when there is no signal to process. Of course, it does not actually call time.sleep, otherwise the signal will not be processed immediately when it comes. The implementation here is more clever, using pipes and select timeout. Just look at the code and you will know


        def sleep(self):        """\
        Sleep until PIPE is readable or we timeout.
        A readable PIPE means a signal occurred.        """
            ready = select.select([self.PIPE[0]], [], [], 1.0) # self.PIPE = os.pipe()
            if not ready[0]: 
                return
            while os.read(self.PIPE[0], 1):                pass
Copy after login

The comments in the code are very clear, either PIPE is readable and returns immediately, or the wait times out. The pipe is readable because a signal occurs. Here's a look at the pipe function

  • os.pipe()

  • Create a pipe. Return a pair of file descriptors

    (r,w) usable for reading and writing, respectively.

Then let’s take a look at when the pipe is readable: it must be to What is written to the pipe, this is the function of the wakeup function

        def wakeup(self):            """
            Wake up the arbiter by writing to the PIPE            """
            os.write(self.PIPE[1], b'.')
Copy after login

Finally, the signal processing of Arbiter is attached:

Exit, INT: Quick shutdown

TERM: Graceful shutdown. Waits for the worker to complete its current request until it times out.

HUP: Reload configuration, start new worker processes with new configuration, and shut down old worker processes gracefully. Gunicorn will also load the new version if the application is not preloaded (using the --preload option).

TTIN: Increase the number of processes by one

TTOU: Decrease the number of processes by one

USR1: Reopen the log file

USR2: Upgrade on the fly Gunicorn. A separate term signal should be used to terminate the old process. This signal can also be used to use preloaded new versions of the application.

Winch: Gracefully shut down worker processes when Gunicorn is daemonized.

The above is the detailed content of How to analyze gunicorn Arbiter source code. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
1 months ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Understand Gunicorn and Python GIL in one article Understand Gunicorn and Python GIL in one article Apr 12, 2023 am 10:40 AM

What is the Python GIL, how does it work, and how does it affect gunicorn. Which Gunicorn worker type should I choose for production? Python has a global lock (GIL) which only allows one thread to run (i.e. interpret bytecode). In my opinion, understanding how Python handles concurrency is essential if you want to optimize your Python services. Python and gunicorn give you different ways of handling concurrency, and since there's no magic bullet that covers all use cases, it's a good idea to understand the options, tradeoffs, and advantages of each option. Gunicorn worker typeGunico

Comparing the performance of Gunicorn and uWSGI for Flask application deployment Comparing the performance of Gunicorn and uWSGI for Flask application deployment Jan 17, 2024 am 08:52 AM

Flask application deployment: Comparison of Gunicorn vs suWSGI Introduction: Flask, as a lightweight Python Web framework, is loved by many developers. When deploying a Flask application to a production environment, choosing the appropriate Server Gateway Interface (SGI) is a crucial decision. Gunicorn and uWSGI are two common SGI servers. This article will describe them in detail.

Learn more about Gunicorn's fundamentals and features Learn more about Gunicorn's fundamentals and features Jan 03, 2024 am 08:41 AM

Basic concepts and functions of Gunicorn Gunicorn is a tool for running WSGI servers in Python web applications. WSGI (Web Server Gateway Interface) is a specification defined by the Python language and is used to define the communication interface between web servers and web applications. Gunicorn enables Python web applications to be deployed and run in production environments by implementing the WSGI specification. The function of Gunicorn is to

Gunicorn Deployment Guide for Flask Applications Gunicorn Deployment Guide for Flask Applications Jan 17, 2024 am 08:13 AM

How to deploy Flask application using Gunicorn? Flask is a lightweight Python Web framework that is widely used to develop various types of Web applications. Gunicorn (GreenUnicorn) is a Python-based HTTP server used to run WSGI (WebServerGatewayInterface) applications. This article will introduce how to use Gunicorn to deploy Flask applications, with

What is Gunicorn What is Gunicorn Nov 23, 2023 pm 03:07 PM

Gunicorn is a WSGI (HTTP server) web server gateway interface specification written in Python. It is a lightweight and efficient server specifically designed to run Python web applications. Its main features and functions include: 1. High performance, which can easily handle high concurrent requests; 2. Stable and reliable, which can provide durable long-term operation, greatly reducing the possibility of server crash; 3. Fault tolerance, which can do To maintain the stability of the service; 4. Multiple deployment methods, etc.

Deploy the unbeatable combination of Gunicorn and Flask Deploy the unbeatable combination of Gunicorn and Flask Jan 17, 2024 am 10:24 AM

Gunicorn and Flask: The perfect deployment combination, specific code examples required Overview: It is very important for developers to choose the appropriate deployment method, especially for Python web applications. Among Python web frameworks, Flask is a very popular choice, and Gunicorn is a server for deploying Python applications. This article will introduce the combination of Gunicorn and Flask and provide some specific code examples to help readers

CentOS installation Gunicorn and CentOS installation partition tutorial CentOS installation Gunicorn and CentOS installation partition tutorial Feb 10, 2024 pm 09:20 PM

LINUX is a powerful operating system that is widely used in servers and development environments. CentOS is an open source operating system based on Red Hat Enterprise Linux (RHEL) and is widely used in server environments. Installing Gunicorn and partitioning on CentOS can improve the performance of the server. Performance and security, this article will detail how to install Gunicorn on CentOS and how to partition it. Install Gunicorn on CentOS Gunicorn is a Python WSGIHTTP server for running Python web applications. The following is how to install Gunicorn on CentOS.

How to improve Flask application performance: use Gunicorn How to improve Flask application performance: use Gunicorn Jan 17, 2024 am 10:42 AM

How does Gunicorn improve the performance of Flask applications? With the rapid development of the Internet, the performance of web applications has become increasingly important for user experience and enterprise competitiveness. When handling high concurrent requests, the default development server of the Flask framework often cannot meet the demand. Therefore, we need to use Gunicorn (GreenUnicorn) to improve the performance of Flask applications. Gunicorn is a Python-based HTTP server that uses pre-forked

See all articles