目錄
典型PHP 環境的缺點和低效性
合併兩種程式語言遇到的困難
在多個 PHP Worker 之間分配任務
由於內建的 RPC,你可以在不寫擴充的情況下,在 PHP 中開啟任何 Go 函式庫的 API。更重要的是,使用 RoadRunner,你可以部署不同於 HTTP 的新伺服器。範例包括在 PHP 中執行 AWS Lambda 處理器,以建立強大的佇列
首頁 後端開發 php教程 為速度而生:PHP 與Golang 的合體 —— RoadRunner

為速度而生:PHP 與Golang 的合體 —— RoadRunner

Sep 23, 2022 pm 07:40 PM
php golang

為速度而生:PHP 與Golang 的合體 —— RoadRunner

在過去的十年中,我們一直在為 財富 500 強公司 以及用戶人數不超過 500 人的企業開發應用程式。一直以來,我們的工程師主要使用 PHP 來開發後端。但兩年前,出現了一些問題不僅嚴重影響了我們的產品效能,還影響了它們的可擴展性 —— 因此我們將 Golang (Go) 引入了我們的技術堆疊。

幾乎同時,我們發現 Go 不僅允許我們創建更大的應用程序,並且能夠將效能提高多達 40 倍。有了它,我們能夠擴展使用 PHP 編寫的現有產品,並透過結合兩種語言的優勢來改進它們。

我們將透過大量的Go 和PHP 經驗告訴你,如何用它來解決實際的開發問題,以及我們如何把它變成一個工具,來消除與 PHP 死亡模型 相關的一些問題。

常規 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 池中。

為速度而生:PHP 與Golang 的合體 —— RoadRunner

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

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

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

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

為速度而生:PHP 與Golang 的合體 —— 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 的支援。

結論

有些人仍然被過時的 PHP 概念所束縛,認為 PHP 是一種緩慢、繁瑣的語言,只適合在 WordPress 下編寫外掛。這些人甚至還說 PHP 有一個限制:當應用程式變得足夠大時,你必須選擇更「成熟」的語言,並重寫多年累積的程式碼庫。

對於這些問題,我的回答是:再想想。我們相信只是你自己為 PHP 設定了一些限制。你可以用一輩子的時間從一種語言遷移到另一種語言,試圖找到與你的需求完美結合的語言,或者你可以將語言視為工具。像 PHP 這樣的語言,它的假想缺陷可能是其成功的真正原因。如果你將它與另一種語言(如 Go)結合,那麼你將創造出比只使用一種語言更強大的產品。

在交替使用 Go 和 PHP 之後,我們可以說我們很喜歡它們。我們不打算犧牲其中一個來換取另一個,相反,我們會想辦法從這個雙重架構中獲得更多利益。

###英文原文網址:https://sudonull.com/post/6470-RoadRunner-PHP-is-not-created-to-die-or-Golang-to-the-rescue## #######翻譯網址:https://learnku.com/php/t/61733#########推薦學習:《###PHP影片教學###》###

以上是為速度而生:PHP 與Golang 的合體 —— RoadRunner的詳細內容。更多資訊請關注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)

PHP和Python:比較兩種流行的編程語言 PHP和Python:比較兩種流行的編程語言 Apr 14, 2025 am 12:13 AM

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP:網絡開發的關鍵語言 PHP:網絡開發的關鍵語言 Apr 13, 2025 am 12:08 AM

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP的未來:改編和創新 PHP的未來:改編和創新 Apr 11, 2025 am 12:01 AM

PHP的未來將通過適應新技術趨勢和引入創新特性來實現:1)適應云計算、容器化和微服務架構,支持Docker和Kubernetes;2)引入JIT編譯器和枚舉類型,提升性能和數據處理效率;3)持續優化性能和推廣最佳實踐。

PHP與Python:了解差異 PHP與Python:了解差異 Apr 11, 2025 am 12:15 AM

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP的目的:構建動態網站 PHP的目的:構建動態網站 Apr 15, 2025 am 12:18 AM

PHP用於構建動態網站,其核心功能包括:1.生成動態內容,通過與數據庫對接實時生成網頁;2.處理用戶交互和表單提交,驗證輸入並響應操作;3.管理會話和用戶認證,提供個性化體驗;4.優化性能和遵循最佳實踐,提升網站效率和安全性。

PHP行動:現實世界中的示例和應用程序 PHP行動:現實世界中的示例和應用程序 Apr 14, 2025 am 12:19 AM

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP的當前狀態:查看網絡開發趨勢 PHP的當前狀態:查看網絡開發趨勢 Apr 13, 2025 am 12:20 AM

PHP在現代Web開發中仍然重要,尤其在內容管理和電子商務平台。 1)PHP擁有豐富的生態系統和強大框架支持,如Laravel和Symfony。 2)性能優化可通過OPcache和Nginx實現。 3)PHP8.0引入JIT編譯器,提升性能。 4)雲原生應用通過Docker和Kubernetes部署,提高靈活性和可擴展性。

您如何防止班級被擴展或方法在PHP中被覆蓋? (最終關鍵字) 您如何防止班級被擴展或方法在PHP中被覆蓋? (最終關鍵字) Apr 08, 2025 am 12:03 AM

在PHP中,final關鍵字用於防止類被繼承和方法被重寫。 1)標記類為final時,該類不能被繼承。 2)標記方法為final時,該方法不能被子類重寫。使用final關鍵字可以確保代碼的穩定性和安全性。

See all articles