Home Backend Development PHP Tutorial Implementing high-concurrency server with PHP

Implementing high-concurrency server with PHP

Jun 19, 2019 am 10:55 AM
php High concurrency

Implementing high-concurrency server with PHP

When it comes to high concurrency, there is no way to bypass I/O multiplexing and then specify the specific platform Linux, there is no way to bypass epoll. I won’t go into the principle of why epoll is efficient. Interested students can search and study it by themselves.

How to play epoll in php? First, you must install a libevent library, and then install an event extension or libevent extension, and you can play happily.

Some people are confused about the difference between the libevent library and the libevent extension. Simply put, the libevent library It is the encapsulation of epoll in C language and has nothing to do with PHP; the libevent extension is the communication bridge between PHP and the libevent library. In fact, many extensions of PHP do this. There are some excellent C language libraries. If PHP wants to use them directly, it can be connected to PHP through PHP extensions.

Choose between libevent extension and event extension. Personally, I prefer event extension because it is more object-oriented. Go to http://pecl.php.net and search for extensions corresponding to your PHP version, download it, compile and install it and it will be OK. When compiling with multiple versions of PHP installed on your computer, pay attention to the version of phpize that matches the one. , make no mistake, the typical five steps:

phpize
./configure
make
make install
php -m | grep event #看看装上了没
Copy after login

The transport layer of the server we want to implement is the TCP protocol. There are too many application layer protocols and are too complicated. Due to space limitations, we will simply use the HTTP server as an example. For example, the HTTP protocol itself is very complex. There are many details to implement, and we will not fully implement the HTTP protocol.

First, create a socket, three steps, socket_create, socket_bind, socket_listen. Why these three steps? It's very simple. No matter what your transport layer protocol is, you have to choose a version of the network layer protocol below, IPV4 or IPV6. You have to choose a transport layer working method, full duplex, half duplex or simplex, TCP. Or UDP, you have to choose one, socket_create is these three options; after determining the network layer and transport layer, you have to tell me which port to listen to, which corresponds to socket_bind; then you have to enable monitoring and specify a client Queue length, this is what socket_listen does.

After creation, we will not introduce synchronous blocking. A process can hold at most one connection at the same time. If more connections are requested at the same time, you have to wait. If the queue length specified by socket_listen is exceeded, 504 must be returned. . The same goes for multiple processes. Several processes have several concurrent processes. Processes are expensive resources, and the context switching of processes is time-consuming and laborious, resulting in inefficiency of the entire system.

It doesn't matter, we have epoll, it is not a dream to hold thousands of requests, first implement a Reactor. The libevent library is the Reactor mode. Calling the function directly is using the Reactor mode, so there is no need to worry about how to implement the Reactor mode in PHP.

<?php

use Event;
use EventBase;

class Reactor
{
    protected $reactor;

    protected $events;

    public static $instance = null;

    const READ = Event::READ | Event::PERSIST;

    const WRITE = Event::WRITE | Event::PERSIST;

    public static function getInstance()
    {
        if (is_null(self::$instance)) {
            self::$instance = new self();
            self::$instance->reactor = new EventBase;
        }

        return self::$instance;
    }

    public function add($fd, $what, $cb, $arg = null)
    {
        switch ($what) {
            case self::READ:
                $event = new Event($this->reactor, $fd, self::READ, $cb, $arg);
                break;
            case self::WRITE:
                $event = new Event($this->reactor, $fd, self::WRITE, $cb, $arg);
                break;
            default:
                $event = new Event($this->reactor, $fd, $what, $cb, $arg);
                break;
        }

        $event->add();
        $this->events[(int) $fd][$what] = $event;
    }

    public function del($fd, $what = 'all')
    {
        $events = $this->events[(int) $fd];
        if ($what == 'all') {
            foreach ($events as $event) {
                $event->free();
            }
        } else {
            if ($what != self::READ && $what != self::WRITE) {
                throw new \Exception('不存在的事件');
            }

            $events[$what]->free();
        }
    }

    public function run()
    {
        $this->reactor->loop();
    }

    public function stop()
    {
        foreach ($this->events as $events) {
            foreach ($events as $event) {
                $event->free();
            }
        }
        $this->reactor->stop();
    }
}
Copy after login

The above code is very simple. Let me briefly explain the concept. EventBase is a container, which contains Event instances. In this way, the above code is very easy to understand. Then a Server.

<?php use Throwable;use Monolog\Handler\StreamHandler;class Server{	protected $ip;	protected $port;	protected $socket;	protected $reactor;	public function __construct($ip, $port)
	{		$this->ip = $ip;		$this->port = $port;
	}	public function start()
	{
	    $socket = $this->createTcpConnection();
	    stream_set_blocking($socket, false);

	    Reactor::getInstance()->add($socket, Reactor::READ, function($socket) {
                $conn = stream_socket_accept($socket);
                stream_set_blocking($conn, false);
                (new Connection($conn))->handle();
        });

            Reactor::getInstance()->run();
	}	public function createTcpConnection()
	{
		$schema = sprintf("tcp://%s:%d", $this->ip, $this->port);
		$socket = stream_socket_server($schema, $errno, $errstr);		if ($errno) {			throw new \Exception($errstr);
		}		return $socket;
	}
}
Copy after login

Connection

<?phpclass Connection{    protected $conn;    protected $read_buffer = &#39;&#39;;    protected $write_buffer = &#39;&#39;;    public function __construct($conn)
    {        $this->conn = $conn;
    }    public function handle()
    {
        Reactor::getInstance()->add($this->conn, Reactor::READ, \Closure::fromCallable([$this, 'read']));
    }    private function read($conn)
    {        $this->read_buffer = '';        if (is_resource($conn)) {            while ($content = fread($conn, 65535)) {                $this->read_buffer .= $content;
            }
        }        if ($this->read_buffer) {
            Reactor::getInstance()->add($conn, Reactor::WRITE, \Closure::fromCallable([$this, 'write']));
        } else {
            Reactor::getInstance()->del($conn);
            fclose($conn);
        }
    }    private function write($conn)
    {        if (is_resource($conn)) {
            fwrite($conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html;charset=utf8\r\nContent-Length:11\r\nConnection: keep-alive\r\n\r\nHello!world");
        }
    }

}
Copy after login

first creates a Socket in three steps and sets it to non-blocking mode. Then add the socket to the Reactor to listen for readable events. Readable means that it can only be read when there is data in the buffer. A readable event occurs, indicating that a new connection is coming. Use stream_socket_accept to receive the new connection Conn, and put Conn in Reactor to monitor readable events. If a readable event occurs, it indicates that the client has data sent. Read in a loop until there is no data, and then put Conn in the Reactor to listen for writable events. If a writable event occurs, it means that the client data has been sent. Assemble the protocol and write the response.

If the application layer is HTTP protocol, please pay attention to the Connection: keep-alive header, because the connection needs to be reused, so do not close the connection as soon as it is finished.

After finishing the work, use ab to test the concurrency, and add the -k parameter to multiplex the connection. There is no problem with i5 8G, 3W concurrency, of course we don’t have it here. Disk I/O, the actual situation is to read files from the disk, and read files through Linux system calls, and there are several file copy operations, which is relatively expensive. The common solution is sendfile, zero copy directly from an FD To another FD, the efficiency is relatively high. The disadvantage is that PHP does not have a ready-to-implement sendfile extension, so you have to do it yourself, and the development cost is a bit high.

ab test PO picture:

Implementing high-concurrency server with PHP

This is the idea of ​​​​implementing a high-concurrency server in PHP. As long as it is solved with EPOLL, the idea is the same. It is a three-step process. Put it under Reactor to monitor FD events. Of course, this is just the simplest model, and there are many areas that can be improved. For example, multi-process, copy nginx, one main process and N worker processes. The purpose of multi-process is to use multi-core parallel work. The same is true for C language implementation, but you may not use the libevent library and encapsulate EPOLL yourself. After all, the libevent library is a bit heavy, and you can’t use many things in libevent; of course, the C language has a bunch of data structures and functions defined on the data structures. The operations need to be written, there is no GC, the memory must be managed by yourself, and there must be good design. When running multiple processes, you need to work on IPC inter-process communication. The development difficulty is much greater than that of PHP, and the development cycle is also very long. If you are interested Students can play with one by themselves.

For more PHP related technical articles, please visit the PHP Tutorial column to learn!

The above is the detailed content of Implementing high-concurrency server with PHP. 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

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

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)

Hot Topics

Java Tutorial
1659
14
PHP Tutorial
1257
29
C# Tutorial
1231
24
How do you parse and process HTML/XML in PHP? How do you parse and process HTML/XML in PHP? Feb 07, 2025 am 11:57 AM

This tutorial demonstrates how to efficiently process XML documents using PHP. XML (eXtensible Markup Language) is a versatile text-based markup language designed for both human readability and machine parsing. It's commonly used for data storage an

Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Apr 05, 2025 am 12:04 AM

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

Explain late static binding in PHP (static::). Explain late static binding in PHP (static::). Apr 03, 2025 am 12:04 AM

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

PHP Program to Count Vowels in a String PHP Program to Count Vowels in a String Feb 07, 2025 pm 12:12 PM

A string is a sequence of characters, including letters, numbers, and symbols. This tutorial will learn how to calculate the number of vowels in a given string in PHP using different methods. The vowels in English are a, e, i, o, u, and they can be uppercase or lowercase. What is a vowel? Vowels are alphabetic characters that represent a specific pronunciation. There are five vowels in English, including uppercase and lowercase: a, e, i, o, u Example 1 Input: String = "Tutorialspoint" Output: 6 explain The vowels in the string "Tutorialspoint" are u, o, i, a, o, i. There are 6 yuan in total

What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? Apr 03, 2025 am 12:03 AM

What are the magic methods of PHP? PHP's magic methods include: 1.\_\_construct, used to initialize objects; 2.\_\_destruct, used to clean up resources; 3.\_\_call, handle non-existent method calls; 4.\_\_get, implement dynamic attribute access; 5.\_\_set, implement dynamic attribute settings. These methods are automatically called in certain situations, improving code flexibility and efficiency.

PHP and Python: Comparing Two Popular Programming Languages PHP and Python: Comparing Two Popular Programming Languages Apr 14, 2025 am 12:13 AM

PHP and Python each have their own advantages, and choose according to project requirements. 1.PHP is suitable for web development, especially for rapid development and maintenance of websites. 2. Python is suitable for data science, machine learning and artificial intelligence, with concise syntax and suitable for beginners.

PHP: A Key Language for Web Development PHP: A Key Language for Web Development Apr 13, 2025 am 12:08 AM

PHP is a scripting language widely used on the server side, especially suitable for web development. 1.PHP can embed HTML, process HTTP requests and responses, and supports a variety of databases. 2.PHP is used to generate dynamic web content, process form data, access databases, etc., with strong community support and open source resources. 3. PHP is an interpreted language, and the execution process includes lexical analysis, grammatical analysis, compilation and execution. 4.PHP can be combined with MySQL for advanced applications such as user registration systems. 5. When debugging PHP, you can use functions such as error_reporting() and var_dump(). 6. Optimize PHP code to use caching mechanisms, optimize database queries and use built-in functions. 7

PHP in Action: Real-World Examples and Applications PHP in Action: Real-World Examples and Applications Apr 14, 2025 am 12:19 AM

PHP is widely used in e-commerce, content management systems and API development. 1) E-commerce: used for shopping cart function and payment processing. 2) Content management system: used for dynamic content generation and user management. 3) API development: used for RESTful API development and API security. Through performance optimization and best practices, the efficiency and maintainability of PHP applications are improved.

See all articles