Home  >  Article  >  PHP Framework  >  Swoole in action: How to use coroutines to improve application performance

Swoole in action: How to use coroutines to improve application performance

WBOY
WBOYOriginal
2023-11-07 15:09:371168browse

Swoole in action: How to use coroutines to improve application performance

Swoole in action: How to use coroutines to improve application performance

As Internet applications become more and more complex, performance has become an increasingly important issue. As a high-performance network communication framework for coroutines, Swoole can solve this problem very well. This article will introduce some basic concepts of Swoole coroutines, and take examples to demonstrate how to use coroutines to improve application performance.

1. What is a coroutine?

Coroutine is a lightweight thread that can achieve multi-task collaboration on a single thread and can be freely moved between coroutines. switch. In Swoole, coroutines can simplify the complexity of asynchronous programming. Through coroutines, we can write asynchronous code just like writing synchronous code, improving the readability and maintainability of the code.

2. Basic use of coroutine

In Swoole, the coroutine is created through the swoole_coroutine_create function. The code is as follows:

//创建协程
$cid = swoole_coroutine_create(function(){
    echo "Hello Coroutine
";
});

//若主线程不阻塞,则协程无法执行

After creating the coroutine, you need to use The swoole_event_wait function is used to wait for the execution of the coroutine. The code is as follows:

//创建协程
$cid = swoole_coroutine_create(function(){
    echo "Hello Coroutine
";
});

//等待协程执行
swoole_event_wait();

The above code can output "Hello Coroutine", indicating that the coroutine has been successfully executed.

In the coroutine, you can also use the swoole_coroutine_yield function to give up the current coroutine and let other coroutines execute. The code is as follows:

$cid1 = swoole_coroutine_create(function(){
    echo "Coroutine 1
";
    swoole_coroutine_yield();
    echo "Coroutine 1 resume
";
});

$cid2 = swoole_coroutine_create(function(){
    echo "Coroutine 2
";
    swoole_coroutine_yield();
    echo "Coroutine 2 resume
";
});

swoole_coroutine_resume($cid1);
swoole_coroutine_resume($cid2);
swoole_event_wait();

In the above code, two coroutines are first created. process, and then use the swoole_coroutine_resume function to resume execution of the two coroutines respectively. Since the swoole_coroutine_yield function is called in the coroutine, the coroutine will output "Coroutine 1" and "Coroutine 2" respectively, and then both suspend execution and give up the CPU. Finally After the coroutine completes a cycle, it obtains the CPU and outputs "Coroutine 1 resume" and "Coroutine 2 resume" respectively.

3. Commonly used skills of coroutines

  1. Handling of concurrent tasks

In Swoole, the concurrent execution of multiple coroutines can be achieved by using the swoole_coroutine_wait function and synchronization processing, the code is as follows:

$tasks = [
    "task1" => function () {
        sleep(1);
        return "Task 1 Done
";
    },
    "task2" => function () {
        sleep(1);
        return "Task 2 Done
";
    },
];

$results = [];

foreach ($tasks as $name => $task) {
    $cid = swoole_coroutine_create(function () use ($name, $task, &$results) {
        $result = $task();
        $results[$name] = $result;
    });
    swoole_coroutine_resume($cid);
}

swoole_coroutine_wait();
print_r($results);

In the above code, two tasks are first defined, sleep(1) is added to the function that executes the task to simulate the task execution time, and then a foreach loop is used to create two tasks. A coroutine, save the execution results in the $results array, and finally call the swoole_coroutine_wait function to wait for the completion of the coroutine and obtain the execution results.

  1. Processing of IO tasks

In Swoole, the swoole_coroutine_system_exec function can be used to execute system commands asynchronously and return results. The code is as follows:

function async_exec($cmd)
{
    $fp = popen($cmd, "r");
    if ($fp) {
        while (!feof($fp)) {
            yield fread($fp, 8192);
        }
        pclose($fp);
    }
}

$s = microtime(true);
$coroutine = async_exec('ls /');
foreach ($coroutine as $stdout) {
    echo $stdout;
}
$e = microtime(true);
echo "Time used: " . ($e - $s) . "s
";

Above In the code, the async_exec function is used to asynchronously execute system commands, and yield is used to gradually read the output results, and finally output the command execution time.

  1. Connection pool technology

In Swoole, the database connection pool function is built-in, which can simplify database operations and improve concurrent execution efficiency through the swoole_mysql coroutine client. The code is as follows:

$pool = new SwooleCoroutineChannel(10);
for ($i = 0; $i < 10; $i++) {
    $conn = new SwooleCoroutineMySQL();
    $conn->connect([
        'host' => '127.0.0.1',
        'user' => 'root',
        'password' => '123456',
        'database' => 'test',
    ]);
    $pool->push($conn);
}

go(function () use ($pool) {
    $conn = $pool->pop();
    $result = $conn->query('select * from users');
    //...
    $pool->push($conn);
});

In the above code, first create a connection pool, use a for loop to create 10 MySQL connections and add them to the connection pool, then use the go function to create a coroutine and take out a connection from the connection pool Perform database query operations, and finally put the connection back into the connection pool. The advantage of the connection pool is that it can reduce the overhead caused by connection creation and destruction and improve the performance of database operations.

4. Examples of using Swoole to improve the performance of microservice applications

Swoole has very strong coroutine programming capabilities and can help developers efficiently write high-performance and high-concurrency server-side applications. . The following takes a microservice application as an example to demonstrate how to use Swoole's coroutine technology to improve application performance.

  1. Microservice simulation program

First, we create a simple microservice program, the code is as follows:

<?php
//微服务1
function service1($str)
{
    $result = file_get_contents("http://127.0.0.1:8888/service2?str=".$str);
    return strtoupper($result);
}

//微服务2
function service2($str)
{
    return md5($str);
}

//路由处理
$uri = $_SERVER['REQUEST_URI'];
if (preg_match("/^/service1?str=(.*)$/", $uri, $match)) {
    echo service1($match[1]);
} elseif (preg_match("/^/service2?str=(.*)$/", $uri, $match)) {
    echo service2($match[1]);
} else {
    echo "Unknown Request: ".$uri;
}

The above program is a simple microservice program The service simulation program provides two services: service1 and service2. Service 1 will call Service 2 and convert the return result into uppercase format. Service 2 will encrypt the input string with MD5 and return it.

  1. Use Swoole to implement the coroutine version of microservices

Use Swoole to implement the coroutine version of microservices. The code is as follows:

<?php
$http = new SwooleHttpServer("0.0.0.0", 8888);

$http->on("request", function ($request, $response) {
    $uri = $request->server['request_uri'];
    if (preg_match("/^/service1?str=(.*)$/", $uri, $match)) {
        $result = go(function () use ($match) {
            $str = $match[1];
            $result = await service2($str);
            return strtoupper($result);
        });
        $response->end($result);
    } elseif (preg_match("/^/service2?str=(.*)$/", $uri, $match)) {
        $result = go(function () use ($match) {
            $str = $match[1];
            $result = await service2($str);
            return $result;
        });
        $response->end($result);
    } else {
        $response->end("Unknown Request: ".$uri);
    }
});

$http->start();

async function service1($str)
{
    $result = await service2($str);
    return strtoupper($result);
}

async function service2($str)
{
    //模拟异步IO操作
    usleep(1000000);
    return md5($str);
}

In the above code , using Swoole's HTTP coroutine server to provide microservices, parse the requested URI and call the corresponding service. In service 1 processing, the service 2 service is called and the result is returned, but the calling method is asynchronous through the go function, and the await keyword is used to wait for the asynchronous call result. In each microservice implementation, asynchronous IO operations are used to simulate real network IO to better reflect the characteristics of Swoole coroutines.

Summary

Swoole provides very powerful coroutine programming capabilities, which can help developers write efficient and high-performance network communication programs. In application implementation, developers can use coroutine technology to simplify asynchronous programming, improve concurrent execution efficiency, etc. In the above example, we used Swoole to implement a coroutine version of microservices, which greatly improved the performance and maintainability of the application. In actual implementation, it is also necessary to select appropriate asynchronous IO operations, connection pools and other technologies based on the characteristics of the application to further optimize the performance of the application.

The above is the detailed content of Swoole in action: How to use coroutines to improve application performance. For more information, please follow other related articles on the PHP Chinese website!

Statement:
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