亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

RoadRunner有哪些特性

發布時間:2022-09-24 10:39:45 來源:億速云 閱讀:153 作者:iii 欄目:編程語言

這篇文章主要介紹“RoadRunner有哪些特性”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“RoadRunner有哪些特性”文章能幫助大家解決問題。

常規 PHP 開發環境#

在講述 Go 如何改善 PHP 死亡模型前,先了解一下常規 PHP 開發環境。

通常,應用運行于 nginx 和 PHP-FPM 上。nginx 處理靜態請求,而動態請求則被重定向給 PHP-FPM,并由其執行 PHP 代碼。也許你用的是 Apache 和 mod_php,但是他們原理相同,運行起來只有細微的差別。

看看 PHP-FPM 是如何執行代碼的。當收到請求,PHP-FPM 初始化 PHP 子進程,并將請求的詳細信息轉發給它,作為其狀態的一部分(_GET, _POST, _SERVER 等)。

在 PHP 腳本執行期間,狀態將無法更改,因此只能通過一種方式獲取一組新的輸入數據:清除進程內存并再次初始化它。

這種性能模型有許多優點。你不需要太擔心內存消耗,所有進程都是完全隔離的,如果其中一個進程「死亡」,它將自動重新創建,并且不會影響其他進程。但是,當你嘗試擴展應用程序時,這種方式會有缺點產生。

典型 PHP 環境的缺點和低效性

如果你從事 PHP 的專業開發,那么你就知道從哪兒開始創建一個新項目 —— 選擇框架。它是一個用于依賴注入、ORM、轉化和模板方法的庫。當然,所有用戶輸入的數據都可以方便地放在一個對象中(Symfony / HttpFoundation 或者 PSR-7)。這些框架很棒!

但一切都有它的代價。在任何企業框架中,為了處理一個簡單的用戶請求或訪問數據庫,您必須加載至少幾十個文件,創建許多類,并解析多個配置。但最糟糕的是,在每個任務完成后,您需要重置所有內容并重新啟動:您剛剛啟動的所有代碼都將變得無用,在它的幫助下,您將無法處理另一個請求。把這件事告訴任何用其他語言編寫的程序員 —— 你會看到他臉上的困惑。

多年來,PHP 工程師一直在尋找解決此問題的方法,他們使用了延遲加載技術、微幀、優化庫、緩存等。但最終,您仍然必須放棄整個應用程序,重新開始 *(譯者注:隨著 PHP7.4 中預加載的出現,這個問題將得到部分解決)

一個 PHP 進程能處理多個請求嗎?

您可以編寫持續時間超過幾分鐘的 PHP 腳本(最多幾小時或幾天):例如 Cron 任務、CSV 解析器、隊列處理程序。所有這些工作遵循一個模式:他們獲取一條任務,處理完它,然后獲取下一個任務。代碼常駐在內存中,因此避免了額外的操作來加載框架和應用程序,節約了寶貴時間。

但是開發長時間運行的腳本并不是那么容易。任何錯誤都會殺死進程,內存溢出會導致崩潰,而且不能用 F5 來調試程序了。

自 PHP 7 后情況有所改善:可靠的垃圾收集器出現了,它變得更容易處理錯誤,內核的擴展可以避免內存泄漏。是的,工程師仍然需要仔細處理內存并記住代碼中的狀態的問題(有哪一種語言能讓你可以不關注這些事情呢?)當然,在 PHP 7 中,驚喜并不多。

是否可以采用一種 常駐 PHP 腳本的模型,將其用于處理 HTTP 請求等更瑣碎的任務,從而消除對每個請求都從頭開始下載所有內容的需要?

要解決這個問題,首先需要實現一個服務器應用程序,該應用程序可以接收 HTTP 請求并將它們逐個重定向到 PHP worker,而不是每次都殺死它。

我們知道我們可以用純 PHP(PHP-PM)或 C 擴展(Swoole)編寫 web 服務器。盡管每種方法都有其優點,但這兩種選擇都不適合我們 —— 我想要更多的東西。我們需要的不僅僅是一個 web 服務器 —— 我們希望得到一個解決方案,可以使我們避免與 PHP 中的「重啟動」相關的問題,同時可以輕松地為特定的應用程序進行調整和擴展。也就是說,我們需要一個應用服務器。

Go 可以幫助解決這個問題嗎?我們知道它可以,因為這種語言將應用程序編譯成單個的二進制文件; 它是跨平臺的; 使用自己的并行處理模型(并發)和用于處理 HTTP 的庫; 最后,我們可以把更多的開源庫集成到我們的程序中。

合并兩種編程語言遇到的困難

首先,有必要確定兩個或多個應用程序之間如何相互通信。

例如,使用 Alex Palaestras 的 go-php 庫,可以實現 PHP 和 Go 進程 (如 Apache 中的 mod_php) 之間的內存共享。但是這個庫的功能限制了我們使用它解決問題。

我們決定使用另一種更常見的方法:通過使用 sockets /pipelines 來構建進程之間的交互。 這種方法在過去十年中已經證明了其可靠性,并且在操作系統級別得到了很好的優化。

首先,我們創建了一個簡單的二進制協議,用于在進程之間交換數據和處理傳輸錯誤。在其最簡單的形式中, 這種類型的協議類似于 一個具有固定大小的 packet 頭 (在我們的示例中為 17 個字節) 的 netstring ,其中包含的信息有 packet 的類型,其大小和二進制掩碼的信息,用來檢查數據的完整性。

在 PHP 端,我們使用了 pack 函數 ,在 Go 端,使用了 編碼 / 二進制 庫。

有一個協議對我們來說有點過時,我們添加了直接 從 PHP 調用 net /rpc Go 服務 的功能。 這個功能在后面的開發中對我們有很大的幫助,因為我們可以輕松地將 Go 庫集成到 PHP 應用程序中。這項工作的結果可以在我們的另一個開源產品 Goridge 中看到。

在多個 PHP Worker 之間分配任務

在交互機制實現之后,我們開始思考如何更好地將任務轉移到 PHP 進程中。當任務到達時,應用服務器必須選擇一個空閑的 worker 來執行它。 如果 worker 進程因錯誤而終止或「死亡」,我們將清除它并創建一個新的。 如果 worker 進程成功執行,我們會將它返回到可用于執行任務的 worker 池中。

RoadRunner有哪些特性

為了存儲活躍的 worker 進程池,我們使用了一個 緩沖通道 , 為了從池中清除意外「死亡」的工作進程,我們添加了一種跟蹤錯誤和 worker 進程狀態的機制。

最終,我們得到了一個可以運行的 PHP 服務器,它能夠處理任何以二進制形式呈現的請求。

為了讓我們的應用程序作為 web 服務器開始工作,我們必須選擇一個可靠的 PHP 標準來處理任何傳入的 HTTP 請求。在我們的例子中,我們只需將簡單的 net /http 請求從 Go  轉換 為 PSR-7 格式,這樣它就可以與目前大多數可用的 PHP 框架兼容。

由于 PSR-7 被認為是不可變的(有人會說在技術上不是),開發人員必須編寫那些在原則上不將請求視為全局實體的應用程序。這完全符合 PHP 常駐進程的概念。我們的最終實現(尚未收到名稱)如下所示:

RoadRunner有哪些特性

RoadRunner - - 性能 PHP 應用服務器

我們的第一個測試任務是一個 API 后端,在該后端上,會周期性地出現不可預測的突發請求(比平時更頻繁)。雖然在大多數情況下 nginx capabilities 是足夠的,但是我們經常因為無法在預期的負載增加下快速平衡系統而遇到 502 錯誤。

為解決此問題,我們在 2018 年初部署了第一臺 PHP / Go 應用服務器。并立即取得了驚人的效果!我們不僅完全消除了 502 錯誤,并且還將服務器的數量減少了三分之二,節省了大量資金并解決了令工程師和產品經理頭痛的問題。

在年中的時候,我們改進了我們的方案,在 MIT 許可下將其發布在 GitHub 上,并命名為 RoadRunner, 從而強調了它驚人的速度和效率。

RoadRunner 是如何改進你的開發堆棧的

RoadRunner 的使用允許我們在 Go 端使用中間件 net/http ,甚至在請求進入 PHP 之前進行 JWT 驗證,以及在 Prometheus 中處理 WebSocket 和全局聚合狀態。

由于內置的 RPC,你可以在不編寫擴展包的情況下,在 PHP 中打開任何 Go 庫的 API。更重要的是,使用 RoadRunner,你可以部署不同于 HTTP 的新服務器。示例包括在 PHP 中運行 AWS Lambda 處理器,創建強大的隊列 選擇器, 甚至將  gRPC 添加到我們的應用程序中。

同時使用 PHP 和 Go ,對解決方案有了穩定的提升,在一些測試中將應用程序性能提高了 40 倍,改進了調試工具,實現了與 Symfony 框架的集成,并添加了對 HTTPS、HTTP/2、插件和 PSR-17 的支持。

關于“RoadRunner有哪些特性”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

张家口市| 鹤峰县| 安吉县| 靖边县| 嘉荫县| 津南区| 桃园县| 建瓯市| 三都| 新宁县| 宁河县| 曲水县| 盐山县| 万源市| 旬阳县| 长泰县| 滨州市| 张掖市| 洛川县| 吴江市| 青州市| 广丰县| 安化县| 濮阳县| 邵东县| 濉溪县| 南和县| 葵青区| 佛冈县| 旌德县| 南投县| 邵阳市| 阜宁县| 琼海市| 扎兰屯市| 清原| 宁德市| 天祝| 子长县| 吴江市| 余干县|