First, Swoole’s operation mode

What’s the difference between Swoole efficiency and traditional Web development? What’s the difference between Swoole’s asynchronous development mode and traditional LAMP/LNMP synchronous development mode?

My official group click here. Get more swoole learning materials and video source notes.

1.1. Traditional Web development mode

The PHP Web development approach is LAMP/LNMP architecture, namely Linux, Nginx, Mysql and PHP. Here is an example of nginx:

When a request comes in, the Web Server forwards it to php-FPM, a process-pooled FastCGI service with a built-in PHP interpreter. The FPM is responsible for interpreting the response generated by executing the PHP file, which is eventually returned to the Web Server for presentation to the front end. PHP files implement a lot of business logic, including Mysql and Nosql access, calling third party applications and so on.

This structure of PHP-FPM and nginx works well enough, but because phP-FPM itself is a synchronous blocking process model that releases all resources (including a set of objects initialized by the framework) at the end of the request, the PHP process “idles” (create <–> destroy <–> create) and consumes a lot of CPU resources Source, resulting in a single machine throughput capacity is limited.

Each request processing process means a PHP file parsing, environment Settings and other unnecessary time-consuming operations in the PHP process to destroy the process, can not be used in THE PHP program to achieve performance optimization using connection pooling technology.

1.2. Swoole Operation mode

Swoole addresses the traditional architecture problem by starting with PHP extensions, which we’ve just learned about swoole’s process model.

Compared with traditional architecture, the biggest characteristic of Swoole process model lies in its multithreaded Reactor model to deal with network requests, which makes it easy to deal with a large number of connections.

In addition, the advantages include:

Full asynchronous non – blocking, small occupation of resources, high efficiency program execution

The program only parses and loads the PHP file once to avoid repeated loading with each request

1.3. Disadvantages of using Swoole and traditional PHP development

1. Harder to get started. This requires developers to have a clearer understanding of the multi-process operation mode. 2. More prone to memory leaks. Be careful when handling global and static variables, because variables that are not cleaned up by the GC will last their entire life cycle and can easily run out of memory if not handled correctly. Under PHP-FPM, memory is completely freed as soon as the PHP code executes.

Second, annotation mechanism

Generally speaking, annotations are a parallel concept to annotations in programming Session. Before explaining annotations, we need to define the difference between annotations and annotations:

Comments: for programmers to see, to help understand the code, to explain the code, explain the role.

Annotations: To an application, annotations often serve as a declaration and configuration of code, providing additional machine-available information to executable code that can affect program execution under certain circumstances.

Frameworks can provide a variety of additional functions to code based on this meta-information, and annotations are essentially just another way to understand that annotations are just another representation of configuration:

For example, it is more convenient to control permissions through annotations than through configuration files

For example, annotations are used to configure routes and scheduled tasks

Many of the existing Swoole-based frameworks are developed based on annotations, so we need to understand the annotation mechanism and then implement the annotations in code

Second, the container

3.1. What is a container?

A container is a giant factory that houses and manages the life cycle of objects and can decouple program dependencies.

3.2 Simple understanding of dependency injection through code

/** */ class db {public staticfunction get_db() {
        return new mysqli('127.0.0.1'.'user'.'pass'.'dbname', 3306); } } class post { private$db;
public function __construct($db){// Suppose the database driver changes? If you die, you have to change the code directly$this->db =new mysqli('127.0.0.1'.'user'.'pass'.'dbname', 3306); } publicfunction get_post($id) {return $this->db->query('SELECT * FROM post WHERE id ='.$id); }}$post = new post();
$post->get_post(12); /* * Dependency injection mode */ <? php class db { public staticfunction get_db() {
        return new mysqli('127.0.0.1'.'user'.'pass'.'dbname', 3306); } } class post { private$db;
    public function set_db(db $db) {$this->db = $db;
    }
    public function get_post($id) {return $this->db->query(select xx from xxx); }}$post = new post();
$post->set_db( db::get_db() ); // Inject the database connection object that the POST class depends on and call the static method get_db directly from the class name$post->get_post(11);
Copy the code

When there is no Ioc/DI container

When you have an IoC/DI container, the POST class no longer actively creates the DB class, as shown in the following figure:


Dependency injection: When an instance of class B is used in class A, the construction of the B object is not initialized in A class A method, but passed in as A class B object after it is initialized outside of class A. This process is called dependency injection. The required classes are passed in as parameters and are called dependency injection.

Dependency injection: When an instance of class B is used in class A, the construction of the B object is not initialized in A class A method, but passed in as A class B object after it is initialized outside of class A. This process is called dependency injection. The required classes are passed in as parameters and are called dependency injection.

Inversion of Control (IoC of Control) refers to the transfer of Control of object creation. In the past, the initiative and timing of object creation were controlled by the IoC, but now the power is transferred to a third party, such as the IoC container, which is a factory for object creation. With the IOC container, the dependencies are changed, the old dependencies are gone, they all depend on the IOC container, and the relationship between them is established through the IOC container. Inversion of control means handing over control of the dependent class from active to passive.

3.3. Why does it make sense to use containers in Swoole?

Traditional PHP framework without permanent memory, so every request in all need to use a class is instantiated, each instantiation to apply for a memory, when the request processing after the need to release again, specific please see the first point, so we can at server startup when put the class instantiation prior to memory, cut into the object creation time.

A simple bean container

class BeanFactory{
    private static $container= []; public staticfunction set(string $name,callable $func){
        self::$container[$name] =$func;
    }


    public static function get(string $name) {if(isset(self::$container[$name])){
            return (self::$container[$name) (); }returnnull; }}Copy the code

3.4. Swoole process structure

Swoole’s efficiency is not limited to the fact that it is written in C at the bottom, but its process structure model enables it to process business efficiently. We want to learn more about Swoole, and we need to understand it when we use it in real scenarios. Let’s look at the structure diagram first

First of all, what do these swoole processes do

From the names of these levels, let’s first outline what each of the following levels does, and make a detailed explanation.

1. Master process: the main process

2. Manger process: Management process

3. Worker processes: Worker processes

Task process: asynchronous Task worker process

1. Master process

The first layer, the Master process, this is swoole’s main process, this process is used to deal with swoole’s core event driver, so in this process you can see that it has a MainReactor and a number of reactors, Swoole All listening for events, such as connections from clients, signal processing, etc., is performed in these threads.

Each thread has its own purpose, and here is an overview of each thread

1.1. MainReactor

The main thread listens for server sockets and evaluates the number of connections per Reactor thread if new connections are accepted. Assign this connection to the reactor thread with the fewest connections for load balancing.

1.2 Reactor Thread Group

The Reactor thread maintains TCP connections to the client machine, processes network IO, and sends and receives data in a completely asynchronous, non-blocking mode.

After accepting a new connection, Swoole’s main thread assigns the connection to a fixed Reactor thread, reads the data when the socket is readable, performs protocol resolution, and delivers the request to the Worker process. Sends data to the TCP client when the socket is writable.

1.3 Heartbeat Packet Detection Thread (HeartbeatCheck)

Swoole configures heartbeat detection, and the heartbeat packet thread makes calls to all previously online connections for a fixed amount of time

Sending detection packets

1.4 UDP Packet Receiving Thread (UdpRecv)

Receives and processes client UDP packets

2. Manage process Manager

Swoole must create multiple Worker processes to help handle tasks in order to achieve the best performance, but the Worker process must fork, but the fork operation is not safe, if there is no management, there will be a lot of zombie processes, which will affect the server performance. At the same time, the worker process is mistakenly killed or abnormally exits due to the program. In order to ensure the stability of the service, the worker process needs to be created again.

Swoole creates a single admin process at run time, and all worker and task processes are Fork out of the admin process. The management process monitors the exit events of all child processes. When the worker process has a fatal error or the run life cycle ends, the management process reclaims the process and creates a new one. In other words, the “nanny” Manager process has full authority to manage the creation and recycling of worker and task processes.


Here is another diagram to tease out the relationship between Manager processes and Worker/Task processes.

3. Worker processes

Worker process belongs to swoole’s main logical process. The user processes a series of requests from the client, receives the request packet sent by Reactor thread, and performs PHP callback function to process data and generate response data, which is sent to Reactor thread. Sent by the Reactor thread to the TCP client in either asynchronous non-blocking mode or synchronous blocking mode

4. Task processes

The taskWorker process is an asynchronous work process provided by Swoole. These processes are mainly used to handle some time-consuming synchronous tasks and are posted to the worker process.

5. Interaction between client and server:

1. The client request reaches the Main Reactor, and the client connects to a Reactor thread in the Master process.

2. Main Reactor Registers the request to the corresponding Reactor according to the situation of the Reactor

3. When the client changes, the Reactor sends the data to the worker for processing

4. When the worker finishes processing, it is sent to the reactor through inter-process communication (such as pipeline, shared memory, message queue).

5. Reactor sends the response result to the corresponding connection request for processing

Schematic diagram:

To use a more popular analogy, assume that Server is a factory and Reactor is a sales agent that takes orders from customers. Worker is a Worker. When the salesman receives an order, Worker goes to work to produce what the customer wants. Task_Worker can be understood as an executive who can help workers do some chores and make them concentrate on their work.

6. Process binding events

A callback function within the Master process

OnStart Server starts on the main thread of the main process by calling this function onShutdown This event occurs when the Server ends normallyCopy the code

A callback function within the Manager process

OnManagerStart this function is called when the management process starts onManagerStop this function is called when the management process ends onWorkerError This function is called when the worker/task_worker process is abnormalCopy the code

The callback function within the Worker process

OnWorkerStart This event occurs when the Worker /Task process starts. OnWorkerStop This event occurs when the Worker process terminates. OnClose: this function is called when the TCP client connection is closed. OnReceive: this function is called when the data is received. This function is called when onRequest enters a new connection in the worker process and onPacket receives UDP packets in the worker process. OnFinish Occurs in worker process onFinish When a task posted by worker process is completed in task_worker, the task process sends the result of the task processing to the worker process through finish(). OnWorkerExit is valid only after reload_async is enabled. Asynchronous restart onPipeMessage Triggers an event when a worker process receives a pipe message sent by sendMessageCopy the code

A callback function within the Task process

OnTask is called within the task_worker process. The worker process can use the swoole_server_task function to deliver a new Task to the task_worker process. OnWorkerStart This event occurs when the worker /Task process starts. OnPipeMessage Occurs when the worker process receives a message The event is triggered when sendMessage sends a pipe messageCopy the code

3.5 swoole operation mode and hot restart

Swoole performs well because it reduces the overhead of loading and initialization a PHP file per request. However, this advantage also prevents developers from being able to modify the PHP file and request again to get the results of the new code, as in the past. If new code is required to start executing, the server often needs to be shut down and then restarted so that the new file can be loaded into memory and run, which is obviously not what the developer needs. Fortunately, Swoole provides just that.

In Swoole, we can send different kinds of signals to the main process, and the main process does different things depending on the type of signal it receives. Like these guys

1. Kill-sigterm master_PID Terminates a Swoole program, an elegant termination signal that interrupts the process after it finishes executing the current program rather than killing it

2. Kill -usr1 master_pid Restart all Worker processes

3, kill USR2 | – 12 master_pid restart all the Task of the Worker process

When the USR1 signal is sent to the Master process, the Master process will forward the same signal to the Worker process through the Manager process. The Worker process that receives this signal will release the process memory and close itself after processing the logic being executed. The Manager process then restarts a new Worker process. The new Worker process takes up new memory and reloads the file.

Specific scene:

For live projects, a busy back-end server is processing requests all the time, and if an administrator terminates/restarts the server program by using the kill process, it may terminate in the middle of the code execution.

In this case, inconsistencies in the data can occur. For example, in a transaction system, the next step in the payment logic is shipment, assuming that the process is terminated after the payment logic. This will result in the user paying the currency but not delivering the goods, and the consequences will be very serious.

How to solve it?

At this point, we need to consider how to smoothly restart the server. The so-called smooth restart, also called “hot restart”, is to restart the service without affecting users and update the PHP program code loaded in the memory to update the service logic.

Swoole provides us with a smooth restart mechanism. We only need to send a specific signal to the swoole_server main process to complete the restart of the server.

Matters needing attention:

1. Update is only for worker processes, that is, the update code written in the master process and manger process does not take effect, that is, only files loaded after onWorkerStart callback, restart is meaningful. The file has been loaded into memory before the Worker process starts. If you want to make it take effect again, you can only shut down the server and restart it.

2. Logic written directly in worker code will not take effect, even if signals are sent. Relevant business logic codes need to be included to take effect

Why is distributed service needed

4.1 Problems caused by early monomer architecture

Monomer architecture works well in a relatively small scale, but with the expansion of the system scale, it is exposed to more and more problems, mainly as follows:

1. Complexity increases

For example, some projects have hundreds of thousands of lines of code, and the differences between modules are vague and the logic is confused. The more codes there are, the more complexity there is, and the more difficult it is to solve the problems.

2. Technology debt is rising

The company’s turnover is normal things, some employees before departure, neglect the self discipline code quality, leads to stay a lot of pit, because of the huge amount of monomer project code, pit is hard to find, it creates a lot of trouble for the new staff, the greater the flow of people left by the hole, the more the so-called technical debt more and more.

3. Hindering technological innovation

Such as a project using tp3.2 written before, because of the connected between each module, the volume of the code of logic is not clear, if you want to use tp5 to rebuild this project will be very difficult, costs will be very big, so more companies have to bite the bullet and continue to use the old monomer architecture, This hampers technological innovation.

4. Cannot scale as required

Recommended for example module is CPU intensive modules, and orders module is IO intensive modules, if we want to improve the performance of the order module, such as more memory, hard drives, but because of all the modules in a framework, so we have to consider when extended order module performance factors of other modules, Because we cannot extend the performance of one module to the detriment of the performance of others, we cannot scale on demand.

5. The high availability of the system is poor

Because all feature development ends up being deployed in the same framework and running in the same process, problems with code or resources involved in one feature can affect the functionality deployed in the entire framework.

5. What is RPC?

Remote Procedure Call (RPC) is a protocol that requests services from Remote computer programs over the network without understanding the underlying network technology.

For example, two servers, A and B, have one application deployed on server A and want to call the function/method provided by the application on server B, but they cannot be called directly because they are not in the same memory space. Therefore, they need to express the semantics of the call and convey the data of the call through the network, and this method is RPC

5.1. Why is RPC needed?

The primary functional goal of RPC is to make it easier to build distributed computing (applications) without losing the semantic simplicity of local invocation while providing powerful remote invocation capabilities. To achieve this goal, the RPC framework needs to provide a transparent call mechanism so that consumers do not have to explicitly distinguish between local and remote calls.

Call (” listServices “) – > info ();

RPC hides the details of communication. Calling remote services is just like calling local code, and the calling protocol usually includes transport protocol and encoding protocol. Transport protocol: TCP, HTTP, and Websockect encoding protocols, such as XML and JSON based on text encoding, protobuf and binpack based on binary encoding.

5.2 What protocol is used?

RPC is a concept of software structure, which is the theoretical basis for building distributed applications. Like why do you use electricity from a power plant? Because electricity can be transmitted. The question of whether to use copper wire or wire or some other kind of wire is HTTP or some other protocol. It depends on what scenario and what the performance requirements are. 5.3 is RPC just an interface call?

In fact, a complete RPC also contains another piece of content. Besides the communication protocol, there are “service registration discovery”, error retry, service flow limiting, load balancing of service invocation, etc. RPC is not only a set of design specifications, but also includes service governance.

5.4 Actual Operations

Transport protocol: TCP

Encoding protocol: JSON encoding

I hope the above content can help you, my zhihu column, join my official group click here. Get more swoole learning materials and video source notes.



Swoole recommends learning videos

PHP — Swoole Path to the Great God: AV77924246

How to use swoole+websocket to achieve outdoor live monitoring (general set) : AV79087951

Learn how to use Swoole to develop online games: AV79264440

PHP Advanced Technology Handwriting Swoole distributed framework: AV78383962

PHP Advanced Technology Handwriting Swoole distributed framework (ii) : AV78632435

PHP Advanced Technology Handwriting Swoole distributed framework (iii) : AV78748923

PHP Advanced Technology Handwriting Swoole distributed framework (frame optimization): AV78856427

PHP Advanced Technology Handwriting Swoole Distributed framework (distributed RPC): AV79012272

Implement message push with Swoole: AV79874641

Swoole + Docker + Redis master/slave replication and read-write separation AV78781841


Akik: Today is also a full day


Link: https://juejin.cn/post/6844903822603583502


Source: Nuggets


Copyright belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please indicate the source.