Introduction to swoole 4 – getting to know swoole


Operation flow chart

Introduction to swoole 4 - getting to know swoole
Introduction to swoole 4 - getting to know swoole
Introduction to swoole 4 - getting to know swoole

When a swote application is started, a total of 2 + N + m processes will be created. 2 is a master process and a manager process, where n is the number of worker processes and M is the number of taskworker processes.

Explanation of terms

Master process

The main process, which will create manager process, reactor thread, UDP packet receiving thread, heartbeat detection thread and other threads

Manger process

The role of the process is to create and manage all worker processes and taskworker processes.
  • When a child process finishes running, the manager process is responsible for recycling the child process to avoid becoming a zombie process. And create a new child process
  • When the server is shut down, the manager process will send a signal to all child processes to notify them to shut down the service
  • When the server is reloaded, the manager process will shut down / restart the child processes one by one

Worker process

Work process, on which all business logic code runs. When the reactor thread receives the data from the client, it will package the data and send it to a worker process through the pipeline.
  • Accept the request packet delivered by the reactor thread and execute the PHP callback function to process the data
  • The response data is generated and sent to the reactor thread, which is sent to the TCP client by the reactor thread
  • It can be asynchronous non blocking mode or synchronous blocking mode
  • Worker runs as a multiprocess

Taskworker process

A special work process, the role of the process is to process some time-consuming tasks, in order to release the worker process.
  • Accept that the worker process passes through spool_ Tasks posted by the server > task / taskwait method
  • Process the task and return the result data (using swote_ Server > finish) to the worker process
  • It’s completely synchronous blocking mode
  • Taskworker runs in a multi process manner

Reactor thread

The epoll instance in Linux and kqueue instance in MacOS are used to accept client connection and receive client data.

The main process of swoole is a multithreaded program. There is a very important set of threads, called reactor threads. It is the real processing of TCP connections, sending and receiving data threads.

After accepting a new connection, the main thread of swote will assign the connection to a fixed reactor thread, which is responsible for listening to the socket.

When the socket is read, the data is read, the protocol is parsed, and the request is delivered to the worker process. Send data to TCP client when socket is writable.
  • Responsible for maintaining client TCP connection, processing network IO, processing protocol, sending and receiving data
  • It’s completely asynchronous and non blocking
  • All of them are C code, and no PHP code is executed except for the start / shutdown event callback
  • The data from TCP client is buffered, spliced and split into a complete request packet
  • Reactor runs in a multithreaded manner

operating mechanism

Spoole is an extension of PHP. Once running, it takes over the control of PHP and enters the event loop. 

When an IO (network IO) event occurs, swote will call back the specified callback function set by the user.
Spoole is responsible for monitoring the underlying network events and processing various underlying events. When a request is received, it will trigger an event reminder, and then transfer the control right to a pre registered event callback function for subsequent processing.

It can be understood that reactor is nginx and worker is PHP FPM. The reactor thread processes network requests asynchronously and in parallel, and then forwards them to the worker process for processing. Reactor and worker communicate through unixsocket.

The taskworker provided by swoole is a more complete solution, which integrates the task delivery, queue and PHP task processing process management. Through the API provided by the bottom layer, it is very simple to realize the processing of asynchronous tasks.

In addition, taskworker can return a result to the worker after the task is completed.

Swote's reactor, worker and taskworker can be closely combined to provide a more advanced way to use it.

A more popular analogy, suppose that the server is a factory, the master is the chairman of the board, the manager is the CEO, and the reactor is the sales manager, accepting customer orders. And the worker is the worker, when the sales receive the order, the worker goes to work to produce what the customer wants.

And taskworker can be understood as administrative staff, can help workers do some chores, let workers concentrate on their work.

The so-called callback function is like a mousetrap with a clip open. We set that when a mouse steps on the mousetrap, it will close the trap and catch the mouse. When we place the mousetrap, the mousetrap does not really catch the mouse. This setting is called callback. It will not be executed immediately, but will be executed when the trigger condition (event) is encountered. In the above example, we have placed three mousetrap (callback function). We only need to know that it will perform the desired function when a specific mouse (event) steps on it (when it happens).

  • The bottom layer will assign a unique ID to the worker process and the taskworker process
  • Different worker and taskworker processes can communicate through the SendMessage interface

Operation period

Program global period

In swote_ The object created before server > start is called program global life cycle.
 These variables will exist after the program is started and will not be destroyed until the whole program is finished.
 Some server programs may continue to run for months or even years before shutting down / restarting, so the objects in the global phase of the program will stay in memory during this period.
 The memory occupied by the global object of the program is shared between worker processes, and no extra memory is consumed.
 This part of memory will be separated at write time (cow). When these objects are written in the worker process, they will be automatically separated from the shared memory and become process global objects.
 The code of program global period include / require can only be released when the whole program is shut down, and reload is invalid.

Process Global Period

Swote has a process life cycle control mechanism, and the number of requests processed by a worker child process exceeds max_ After request is configured, it will be destroyed automatically.
 The object created after the worker process starts (the object created in onworker start) is resident in memory during the lifetime of the child process.
 It can be accessed in onconnect / onReceive / onclose.
 The memory occupied by the process global object is in the current child process memory heap, not shared memory. Modifications to this object are only valid in the current worker process.
 Include / require files during the process will be reloaded after reload.

Conversational period

The session period is created after onconnect, or created at the first onReceive and destroyed when onclose. After a client connection enters, the created object will reside in memory and will not be destroyed until the client leaves.
 The object of session time in swote is directly resident memory and does not need session_ Start and so on.
 You can directly access an object and execute its methods.

Request period

The request period refers to a complete request sent, that is, onReceive receives the request and starts processing until the return result sends the response.
 Objects created in this cycle are destroyed after the request is completed.
 The request time object in droole is the same as that in normal PHP program.
 It is created when the request arrives and destroyed when the request is finished.

Four PHP callback function styles

Anonymous function

$server->on('Request', function ($req, $resp) use ($a, $b, $c) {
       echo "hello world";

You can use use use to pass arguments to anonymous functions

Class static method

class A
    static function test($req, $resp)
        echo "hello world";
$server->on('Request', 'A::Test');
$server->on('Request', array('A', 'Test'));

Object method

class A
    function test($req, $resp)
        echo "hello world";

$object = new A();
$server->on('Request', array($object, 'test'));


function my_onRequest($req, $resp)
    echo "hello world";
$server->on('Request', 'my_onRequest');

Programming instructions

matters needing attention

  • Do not execute sleep and other sleep functions in the code, which will cause the whole process to block
  • It is forbidden to use exit / die in the swote program. If exit / die exists in the PHP code, the current working worker process, task process, user process, and swote_ The process exits immediately. After using exit / die, the worker process will exit abnormally and be pulled up again by the master process. Finally, the process will continue to exit, start and generate a large number of alarm logs.
  • Mt_ If MT is called in the parent process_ Rand, and then call MT in different subprocesses_ Rand will return the same result. Therefore, MT must be called within each subprocess_ Srand replanted.
  • If an asynchronous program encounters a dead loop, the event will not be triggered. The asynchronous IO program uses the reactor model and must be polled at reactor > wait. If an endless loop is encountered, the control of the program will be in while. Reactor cannot get control and cannot detect events, so the IO event callback function will not be triggered.
  • You can use the register_ shutdown_ Function to catch fatal errors and do some cleaning when the process exits abnormally
  • If there is an exception thrown in PHP code, you must try / catch the exception in the callback function, otherwise it will cause the worker process to exit
  • Set is not supported_ exception_ Handler, you must use try / catch to handle exceptions
  • The worker process must not share the same redis or MySQL and other network service clients. The code related to the connection creation of redis / MySQL can be put into the onworkerstart callback function.

Asynchronous programming

  • Asynchronous programs require that code should not contain any synchronous blocking operations
  • Asynchronous and synchronous code cannot be mixed. Once an application uses any code blocked by synchronization, the program will degenerate to synchronous mode

Class / function repeated definition

It is very easy for novices to make this error. Because the tool is memory resident, the file defined by class / function will not be released after loading. Therefore, you must use include when introducing PHP files of classes / functions_ Once or require_ Once, whether the fatal error of cannot redeclare function / class will occur.

Process isolation

Process isolation is also a common problem for novices. The reason why the value of the global variable is not effective is that the memory space of the global variable is isolated in different processes, so it is invalid. So we need to understand the problem of process isolation to develop server programs with swote.
  • PHP variables are not shared in different processes. Even if they are global variables, if their values are modified in process a, they are invalid in process B
  • If you need to share data in different worker processes, you can use redis, mysql, files, swotetable, APCU, shmget and other tools
  • The file handles of different processes are isolated, so the files connected or opened by socket created in process a are invalid in process B, and even sending its FD to process B is not available