首頁 php框架 Swoole Swoole實戰:如何運用協程提升應用的效能

Swoole實戰:如何運用協程提升應用的效能

Nov 07, 2023 pm 03:09 PM
效能 協程 swoole

Swoole實戰:如何運用協程提升應用的效能

Swoole實戰:如何使用協程提升應用程式的效能

#隨著網路應用越來越複雜,效能成為了一個越來越重要的問題。而Swoole作為一個面向協程的高效能網路通訊框架,可以很好地解決這個問題。本文將介紹Swoole協程的一些基礎概念,並以實例為例,示範如何使用協程提升應用的效能。

一、什麼是協程

協程(Coroutine)是一種輕量級的線程,可以在單一線程上實現多任務協作,並且可以在協程之間自由切換。在Swoole中,協程可以簡化非同步程式設計的複雜性,透過協程,我們可以像編寫同步程式碼一樣編寫非同步程式碼,提高程式碼的可讀性和可維護性。

二、協程的基礎使用

在Swoole中,協程是透過swoole_coroutine_create函數來建立的,程式碼如下:

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

//若主线程不阻塞,则协程无法执行
登入後複製

建立協程後,需要使用swoole_event_wait函數來等待協程的執行,程式碼如下:

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

//等待协程执行
swoole_event_wait();
登入後複製

以上程式碼可以輸出"Hello Coroutine",表示協程已經成功執行。

在協程中,也可以使用swoole_coroutine_yield函數來將目前協程讓出,讓其他協程執行,程式碼如下:

$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();
登入後複製

以上程式碼中,先建立了兩個協程,然後使用swoole_coroutine_resume函數將兩個協程分別恢復執行,由於協程中調用了swoole_coroutine_yield函數,因此協程會分別輸出"Coroutine 1"和"Coroutine 2",然後都暫停執行並讓出CPU,最後協程執行完了一次循環後,獲得CPU,分別輸出"Coroutine 1 resume"和"Coroutine 2 resume"。

三、協程常用技巧

  1. 並發任務的處理

在Swoole中,使用swoole_coroutine_wait函數可以實現多個協程的並發執行和同步處理,程式碼如下:

$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);
登入後複製

以上程式碼中,先定義了兩個任務,執行任務的函數中都加了sleep(1)來模擬任務執行的時間,然後使用foreach循環創建兩個協程,將執行結果儲存在$results陣列中,最後呼叫swoole_coroutine_wait函數來等待協程的完成,得到執行結果。

  1. IO任務的處理

在Swoole中,使用swoole_coroutine_system_exec函數可以實現非同步執行系統指令並傳回結果,程式碼如下:

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
";
登入後複製

以上程式碼中,使用async_exec函數非同步執行系統指令,並使用yield逐步讀取輸出結果,最後輸出指令執行的時間。

  1. 連接池技術

在Swoole中,內建了資料庫連線池的功能,可以透過swoole_mysql協程客戶端簡化資料庫操作,並提高並發執行效率。程式碼如下:

$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);
});
登入後複製

以上程式碼中,先建立一個連接池,使用for循環建立10個MySQL連線並加入連線池,然後使用go函數建立一個協程,並從連線池中取出一個連接執行資料庫查詢操作,最後將該連線放回連線池。連接池的優點是可以減少連接建立和銷毀帶來的開銷,提高資料庫操作的效能。

四、使用Swoole提升微服務應用效能的實例

Swoole的協程程式設計能力非常強,能夠幫助開發者高效地編寫出高效能和高並發的服務端應用程式。以下以微服務應用為例,示範如何使用Swoole的協程技術來提升應用的效能。

  1. 微服務模擬程序

首先,我們創建一個簡單的微服務程序,程式碼如下:

<?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;
}
登入後複製

以上程序是一個簡單的微服務模擬程序,分別提供了兩個服務:service1和service2。服務1會呼叫服務2並將回傳結果轉換為大寫格式,服務2會對輸入的字串進行MD5加密並傳回。

  1. 使用Swoole實作微服務的協程版本

使用Swoole實作微服務的協程版本,程式碼如下:

<?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);
}
登入後複製

在以上程式碼中,使用Swoole的HTTP協程伺服器提供微服務,對請求的URI進行解析並呼叫對應的服務。在服務1處理中,呼叫了service2服務並將結果傳回,但透過go函數將呼叫方法異步化,使用await關鍵字等待非同步呼叫結果。在各微服務實作中,使用了非同步IO操作來模擬真實的網路IO,以更能體現Swoole協程的特性。

總結

Swoole提供了非常強大的協程程式設計能力,可以幫助開發者編寫高效的、高效能的網路通訊程式。在應用程式實作中,開發者可以採用協程技術來簡化非同步程式設計、提高並發執行效率等。在上述的範例中,我們使用Swoole實作了一個微服務的協程版本,大大提升了應用程式的效能和可維護性。在實際實作中,還需要根據應用的特性選擇合適的非同步IO操作、連接池等技術,以進一步優化應用程式的效能。

以上是Swoole實戰:如何運用協程提升應用的效能的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

golang函數與goroutine的父子關係 golang函數與goroutine的父子關係 Apr 25, 2024 pm 12:57 PM

Go中函數與goroutine存在父子關係,父goroutine創建子goroutine,子goroutine可以存取父goroutine的變數但不反之。建立子goroutine使用go關鍵字,子goroutine透過匿名函數或命名的函數執行。父goroutine可以透過sync.WaitGroup等待子goroutine完成,以確保在所有子goroutine完成之前不會退出程式。

不同Java框架的效能對比 不同Java框架的效能對比 Jun 05, 2024 pm 07:14 PM

不同Java框架的效能比較:RESTAPI請求處理:Vert.x最佳,請求速率達SpringBoot2倍,Dropwizard3倍。資料庫查詢:SpringBoot的HibernateORM優於Vert.x及Dropwizard的ORM。快取操作:Vert.x的Hazelcast客戶端優於SpringBoot及Dropwizard的快取機制。合適框架:根據應用需求選擇,Vert.x適用於高效能Web服務,SpringBoot適用於資料密集型應用,Dropwizard適用於微服務架構。

PHP 陣列鍵值翻轉:不同方法的效能比較分析 PHP 陣列鍵值翻轉:不同方法的效能比較分析 May 03, 2024 pm 09:03 PM

PHP數組鍵值翻轉方法效能比較顯示:array_flip()函數在大型數組(超過100萬個元素)下比for迴圈效能更優,耗時更短。手動翻轉鍵值的for迴圈方法耗時相對較長。

並發和協程在Golang API設計中的應用 並發和協程在Golang API設計中的應用 May 07, 2024 pm 06:51 PM

並發和協程在GoAPI設計中可用於:高效能處理:同時處理多個請求以提高效能。非同步處理:使用協程非同步處理任務(例如傳送電子郵件),釋放主執行緒。流處理:使用協程高效處理資料流(例如資料庫讀取)。

如何控制 Golang 協程的生命週期? 如何控制 Golang 協程的生命週期? May 31, 2024 pm 06:05 PM

控制Go協程的生命週期可以透過以下方式:建立協程:使用go關鍵字啟動新任務。終止協程:等待所有協程完成,使用sync.WaitGroup。使用通道關閉訊號。使用上下文context.Context。

C++中如何優化多執行緒程式的效能? C++中如何優化多執行緒程式的效能? Jun 05, 2024 pm 02:04 PM

優化C++多執行緒效能的有效技術包括:限制執行緒數量,避免爭用資源。使用輕量級互斥鎖,減少爭用。優化鎖的範圍,最小化等待時間。採用無鎖定資料結構,提高並發性。避免忙等,透過事件通知執行緒資源可用性。

PHP 數組轉物件對效能的影響是什麼? PHP 數組轉物件對效能的影響是什麼? Apr 30, 2024 am 08:39 AM

在PHP中,陣列到物件的轉換會對效能產生影響,主要受陣列大小、複雜度、物件類別等因素影響。為了優化效能,可以考慮使用自訂迭代器、避免不必要的轉換、批次轉換數組等技巧。

Java框架的效能比較 Java框架的效能比較 Jun 04, 2024 pm 03:56 PM

根據基準測試,對於小型、高效能應用程序,Quarkus(快速啟動、低記憶體)或Micronaut(TechEmpower優異)是理想選擇。 SpringBoot適用於大型、全端應用程序,但啟動時間和記憶體佔用稍慢。

See all articles