av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

享受PHP與Go的強(qiáng)大合體【RoadRunner】的樂趣!

網(wǎng)站設(shè)計制作、網(wǎng)站設(shè)計中從網(wǎng)站色彩、結(jié)構(gòu)布局、欄目設(shè)置、關(guān)鍵詞群組等細(xì)微處著手,突出企業(yè)的產(chǎn)品/服務(wù)/品牌,幫助企業(yè)鎖定精準(zhǔn)用戶,提高在線咨詢和轉(zhuǎn)化,使成都網(wǎng)站營銷成為有效果、有回報的無錫營銷推廣。創(chuàng)新互聯(lián)專業(yè)成都網(wǎng)站建設(shè)10多年了,客戶滿意度97.8%,歡迎成都創(chuàng)新互聯(lián)客戶聯(lián)系。

享受它的樂趣吧!

在過去的十年中,我們一直在為 財富 500 強(qiáng)公司 以及用戶人數(shù)不超過 500 人的企業(yè)開發(fā)應(yīng)用程序。 一直以來,我們的工程師主要使用 php 來開發(fā)后端。 但是兩年前,出現(xiàn)了一些問題不僅嚴(yán)重影響了我們的產(chǎn)品性能,還影響了它們的可擴(kuò)展性——因此我們將 Golang (Go) 引入了我們的技術(shù)棧。

幾乎同時,我們發(fā)現(xiàn) Go 不僅允許我們創(chuàng)建更大的應(yīng)用程序,并且能夠?qū)⑿阅芴岣叨噙_(dá) 40 倍。 有了它,我們能夠擴(kuò)展使用 PHP 編寫的現(xiàn)有產(chǎn)品,并通過結(jié)合兩種語言的優(yōu)勢來改進(jìn)它們。

我們將通過大量的 Go 和 PHP 經(jīng)驗告訴你,如何用它解決實際的開發(fā)問題,以及我們?nèi)绾伟阉兂梢粋€工具,來消除與 PHP 死亡模型 相關(guān)的一些問題。

推薦學(xué)習(xí):《PHP視頻教程》

常規(guī) PHP 開發(fā)環(huán)境

在講述 Go 如何改善 PHP 死亡模型前,先了解一下常規(guī) PHP 開發(fā)環(huán)境。

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

看看 PHP-FPM 是如何執(zhí)行代碼的。當(dāng)收到請求,PHP-FPM 初始化 PHP 子進(jìn)程,并將請求的詳細(xì)信息轉(zhuǎn)發(fā)給它,作為其狀態(tài)的一部分(_GET, _POST, _SERVER 等)。

在 PHP 腳本執(zhí)行期間,狀態(tài)將無法更改,因此只能通過一種方式獲取一組新的輸入數(shù)據(jù):清除進(jìn)程內(nèi)存并再次初始化它。

這種性能模型有許多優(yōu)點(diǎn)。你不需要太擔(dān)心內(nèi)存消耗,所有進(jìn)程都是完全隔離的,如果其中一個進(jìn)程「死亡」,它將自動重新創(chuàng)建,并且不會影響其他進(jìn)程。但是,當(dāng)你嘗試擴(kuò)展應(yīng)用程序時,這種方式會有缺點(diǎn)產(chǎn)生。

典型 PHP 環(huán)境的缺點(diǎn)和低效性

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

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

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

一個PHP進(jìn)程能處理多個請求嗎?

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

但是開發(fā)長時間運(yùn)行的腳本并不是那么容易。任何錯誤都會殺死進(jìn)程,內(nèi)存溢出會導(dǎo)致崩潰,而且不能用F5來調(diào)試程序了。

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

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

要解決這個問題,首先需要實現(xiàn)一個服務(wù)器應(yīng)用程序,該應(yīng)用程序可以接收 HTTP 請求并將它們逐個重定向到 PHP worker,而不是每次都?xì)⑺浪?/p>

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

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

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

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

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

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

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

在 PHP 端,我們使用了 pack 函數(shù) ,在 Go 端,使用了 編碼 / 二進(jìn)制 庫。

有一個協(xié)議對我們來說有點(diǎn)過時,我們添加了直接 從 PHP 調(diào)用 net / rpc Go 服務(wù) 的功能。 這個功能在后面的開發(fā)中對我們有很大的幫助,因為我們可以輕松地將 Go 庫集成到 PHP 應(yīng)用程序中。這項工作的結(jié)果可以在我們的另一個開源產(chǎn)品 Goridge 中看到。

在多個 PHP Worker 之間分配任務(wù)

在交互機(jī)制實現(xiàn)之后,我們開始思考如何更好地將任務(wù)轉(zhuǎn)移到 PHP 進(jìn)程中。當(dāng)任務(wù)到達(dá)時,應(yīng)用服務(wù)器必須選擇一個空閑的 worker 來執(zhí)行它。 如果 worker 進(jìn)程因錯誤而終止或「死亡」,我們將清除它并創(chuàng)建一個新的。 如果 worker 進(jìn)程成功執(zhí)行,我們會將它返回到可用于執(zhí)行任務(wù)的 worker 池中。

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

最終,我們得到了一個可以運(yùn)行的 PHP 服務(wù)器,它能夠處理任何以二進(jìn)制形式呈現(xiàn)的請求。

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

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

RoadRunner - 高 - 性能 PHP 應(yīng)用服務(wù)器

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

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

在年中的時候,我們改進(jìn)了我們的方案,在 MIT 許可下將其發(fā)布在 GitHub 上,并命名為 RoadRunner, 從而強(qiáng)調(diào)了它驚人的速度和效率。

RoadRunner 是如何改進(jìn)你的開發(fā)堆棧的

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

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

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

結(jié)論

有些人仍然被過時的 PHP 概念所束縛,認(rèn)為 PHP 是一種緩慢、繁瑣的語言,只適合在 WordPress 下編寫插件。這些人甚至還說 PHP 有這樣一個限制:當(dāng)應(yīng)用程序變得足夠大時,你必須選擇一種更「成熟」的語言,并重寫多年積累的代碼庫。

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

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


當(dāng)前名稱:享受PHP與Go的強(qiáng)大合體【RoadRunner】的樂趣!
文章出自:http://uogjgqi.cn/article/cdsiggj.html
掃二維碼與項目經(jīng)理溝通

我們在微信上24小時期待你的聲音

解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流