成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

高性能PHP框架Workerman與Webman協程應用

開發 前端
因為PHP的協程方案是單線程的,同一時刻只能運行一個任務,所以需要在事件循環內盡可能地non-blocking出讓控制權,才可能讓事件循環驅動在有限的時間內執行更多的任務。

前言

workerman v5在經歷了幾年的開發和測試,于2025年元旦正式發布,webman開發框架及眾多周邊插件也緊隨其后更新兼容了v5版本;作為PHP界老牌的網絡容器,workerman的穩定性及易用性毋庸置疑,常駐內存的運行模式、多進程、多協議支持等高性能高效率的特性讓許多PHPer接觸到了之前不曾觸摸過的技術方向;那么v5版本相較于之前版本給開發者帶來了什么比較明顯且用的上的特性呢?

  • 以revolt/event-loop為基建的事件驅動庫
  • 兼容多方協程實現的協程功能

以上是變化較大且意義重大的特性,除此之外還有許多的優化內容及特性升級,請參考官方文檔

“前生”

我個人一直認為所謂‘協程’其實是至少包含了上下文管理、協程調度器、協程執行器三部分的完整方案,在沒有Fiber之前,原生PHP中其實已經有了無棧協程的相關實現,借助yield完成,但不論是Fiber還是yield,都不是完整的‘協程’,只是和上下文相關的一些功能而已,并沒有調度及執行兩部分。而非原生PHP中僅有swoole是一套完整的協程實現方案,不論是它早期底層類yield的異步還是現如今比較現代化的Coroutine,它們都包含了成熟的事件循環驅動(調度/執行)和豐富的上下文管理工具。

可能有人會問了,workerman也有事件循環驅動,為什么沒有協程?先說結論,因為不好管理且生態不夠統一,生態的支持度也不足夠。

在沒有Fiber之前,借助yield來實現協程方案需要保存特別特別多的棧上下文,你可以把它們理解為因為手動中斷的入參參數,他們需要存放在比如靜態變量(也就是內存)中等待下一次的喚醒,喚醒后繼續從中斷的地方執行,再主動中斷的這個過程中,進程就可以交給其他的事務進行執行,整個進程內的所有不同事務呈現無序的交替運行狀態,就像是我們人在工作的時候時不時去上個廁所、接杯咖啡,回來繼續工作;

Fiber其實也類似,只不過它并沒有像yield一樣直接返回暫停時的棧上下文,而是主動保存在一個特定的地方自行管理,這樣就省去了自行使用內存管理的問題,簡化了操作,在我每一次歸來后無需再翻看我的記事本查看我到底寫到那里了,而是直接就可以銜接。

workerman之前也有利用yield+promise包做的異步方案,但都要進行很多侵入式的改造,代價大于收益。

“今世”

workerman v5基于revolt/event-loop作為事件驅動引擎,一方面是由此引入Fiber,一方面是減少目前PHP開發中過多的事件驅動引擎的分化問題,另外還兼容了swow、swoole的事件驅動引擎,是支持中國本土化的內容,另外本質上也是為了減少分化和加強協程的引入;就此,在workerman v5中就可以使用以上三種驅動的協程方案。

那么協程能干什么呢?

假設一個場景,我們需要創建一個異步導出任務,這個異步導出任務可能的實現方式就會是:

開源技術小棧

  • 前端請求接口 -> 接口創建任務 -> 將任務投遞至消息隊列
  • 消息隊列消費導出 -> 修改任務狀態
  • 前端輪詢查詢任務狀態及下載連接

而有了協程我們可以實現以下兩種方案:

1.  自輪詢消費(查詢數據如果使用阻塞方法還是會阻塞)

public function test(): Response
{
    $id = 'your_file_id';
    // 根據請求參數獲取分片數量
    $count = YourData::getShardingCount($request = request()->all());
    for ($i = 0; $i < $count; $i++) {
        // 分片獲取數據
        if ($data = YourData::getListBySharding($request, $i)) {
            // 導出追加
            YourExcel::append($id, $data);
        }
        // 協程隨機出讓1-10 ms
        Timer::sleep(rand(1, 10) / 1000);
    }

    return new Response(200, body: json_encode(YourExcel::getUrl($id)));
}

2.  自輪詢查詢方式

public function test(): Response
{
    $id = 'your_file_id';
    // 發布至消息隊列
    YourMessageMQ::publish($id, $request = request()->all());
    while (1) {
        // 查詢消息隊列消費情況
        if (YourMessageMQ::isComplete($id)) {
            break;
        }
        // 協程隨機出讓1-10 ms
        Timer::sleep(rand(1, 10) / 1000);
    }

    return new Response(200, body: json_encode(YourMessageMQ::getReturn($id)));
}

以上兩種方式都不會特別的阻塞當前進程而實現一個長輪詢接口,避免了前端短輪詢的資源消耗問題;類似SSE的實現方式也會更簡單一些,只需要利用Timer::sleep主動出讓當前協程控制權給事件驅動引擎就可以,而且這樣的好處是既保留了PHP系統層面的CPU控制權出讓sleep/usleep又提供了事件驅動控制權的出讓,區別于Swow和Swoole對系統函數的hook改造,但缺點又是無法改變已經存在的阻塞式函數的阻塞調用邏輯。

“來世”

因為PHP的協程方案是單線程的,同一時刻只能運行一個任務,所以需要在事件循環內盡可能地non-blocking出讓控制權,才可能讓事件循環驅動在有限的時間內執行更多的任務;而目前PHP生態大多數的組件工具都是blocking的,協程所能覆蓋的業務范圍很窄,現存的很多協程組件并不能照顧大部分開發者的情緒,所以我真的希望在未來,PHP能夠涌現更多的開發者來貢獻協程相關的生態,而不是分裂,希望在有限的時間和空間內,看到這門歷史不算太久的老編程語言能夠煥發青春。

責任編輯:武曉燕 來源: 開源技術小棧
相關推薦

2024-10-18 10:27:50

PHP框架webma

2024-08-12 08:43:09

2024-11-06 11:25:06

2024-10-21 09:06:15

2025-02-08 09:13:40

2023-11-01 11:27:10

Linux協程

2024-11-01 11:46:59

2017-08-10 15:50:44

PHP協程阻塞

2025-03-26 01:22:00

NtyCo協程框架

2021-09-16 09:59:13

PythonJavaScript代碼

2016-10-28 17:39:47

phpgolangcoroutine

2017-05-02 11:38:00

PHP協程實現過程

2023-11-17 11:36:59

協程纖程操作系統

2018-12-04 14:00:41

協程編程模式PHP

2025-06-26 04:10:00

2012-08-08 10:10:31

PHP

2021-05-28 05:18:08

PHP語言roadrunnner

2024-02-26 07:43:10

大語言模型LLM推理框架

2024-09-27 11:03:38

2023-07-27 13:46:10

go開源項目
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 中文字幕第十五页 | 亚洲欧美中文日韩在线v日本 | 国产美女黄色片 | 国产激情自拍视频 | 一级在线观看 | 免费a级毛片在线播放 | 色综合久 | 日韩中文字幕高清 | 一区二区三区国产好的精 | 免费久久网 | 久久九九99 | 成人在线视 | 午夜视频一区二区 | 国产99热 | 国产精品久久av | 蜜桃av一区二区三区 | 日韩午夜一区二区三区 | 中文字幕日韩欧美一区二区三区 | 免费在线观看一级毛片 | 精品成人av | 成人欧美一区二区三区在线观看 | 国产一级电影在线 | 精品视频久久久久久 | 欧美一区二区三区在线播放 | 亚洲免费三级 | 精品视频一区二区三区在线观看 | 波多野结衣一区二区 | 国产欧美在线 | 日韩精品在线观看视频 | 99精品在线| 久久久区| 欧美中文字幕一区二区 | 福利精品 | 午夜精品一区二区三区免费视频 | 久久成人精品视频 | 成人三级视频 | 天天干天天操天天射 | 欧美中文字幕一区二区三区亚洲 | 午夜黄色 | 久久国产免费 | 欧美国产精品一区二区 |