本篇內(nèi)容介紹了“PHP與Go的合體有什么優(yōu)勢(shì)”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
成都創(chuàng)新互聯(lián)公司于2013年開(kāi)始,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元巴東做網(wǎng)站,已為上家服務(wù),為巴東各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:028-86922220
常規(guī) PHP 開(kāi)發(fā)環(huán)境
在講述 Go 如何改善 PHP 死亡模型前,先了解一下常規(guī) PHP 開(kāi)發(fā)環(huán)境。
通常,應(yīng)用運(yùn)行于 nginx 和 PHP-FPM 上。nginx 處理靜態(tài)請(qǐng)求,而動(dòng)態(tài)請(qǐng)求則被重定向給 PHP-FPM,并由其執(zhí)行 PHP 代碼。也許你用的是 Apache 和 mod_php,但是他們?cè)硐嗤\(yùn)行起來(lái)只有細(xì)微的差別。
看看 PHP-FPM 是如何執(zhí)行代碼的。當(dāng)收到請(qǐng)求,PHP-FPM 初始化 PHP 子進(jìn)程,并將請(qǐng)求的詳細(xì)信息轉(zhuǎn)發(fā)給它,作為其狀態(tài)的一部分(_GET, _POST, _SERVER 等)。
在 PHP 腳本執(zhí)行期間,狀態(tài)將無(wú)法更改,因此只能通過(guò)一種方式獲取一組新的輸入數(shù)據(jù):清除進(jìn)程內(nèi)存并再次初始化它。
這種性能模型有許多優(yōu)點(diǎn)。你不需要太擔(dān)心內(nèi)存消耗,所有進(jìn)程都是完全隔離的,如果其中一個(gè)進(jìn)程「死亡」,它將自動(dòng)重新創(chuàng)建,并且不會(huì)影響其他進(jìn)程。但是,當(dāng)你嘗試擴(kuò)展應(yīng)用程序時(shí),這種方式會(huì)有缺點(diǎn)產(chǎn)生。
典型 PHP 環(huán)境的缺點(diǎn)和低效性
如果你從事 PHP 的專業(yè)開(kāi)發(fā),那么你就知道從哪兒開(kāi)始創(chuàng)建一個(gè)新項(xiàng)目——選擇框架。它是一個(gè)用于依賴注入、ORM、轉(zhuǎn)化和模板方法的庫(kù)。當(dāng)然,所有用戶輸入的數(shù)據(jù)都可以方便地放在一個(gè)對(duì)象中(Symfony / HttpFoundation 或者 PSR-7)。這些框架很棒!
但一切都有它的代價(jià)。在任何企業(yè)框架中,為了處理一個(gè)簡(jiǎn)單的用戶請(qǐng)求或訪問(wèn)數(shù)據(jù)庫(kù),您必須加載至少幾十個(gè)文件,創(chuàng)建許多類,并解析多個(gè)配置。但最糟糕的是,在每個(gè)任務(wù)完成后,您需要重置所有內(nèi)容并重新啟動(dòng):您剛剛啟動(dòng)的所有代碼都將變得無(wú)用,在它的幫助下,您將無(wú)法處理另一個(gè)請(qǐng)求。把這件事告訴任何用其他語(yǔ)言編寫(xiě)的程序員——你會(huì)看到他臉上的困惑。
多年來(lái),PHP工程師一直在尋找解決此問(wèn)題的方法,他們使用了延遲加載技術(shù)、微幀、優(yōu)化庫(kù)、緩存等。但最終,您仍然必須放棄整個(gè)應(yīng)用程序,重新開(kāi)始*(譯者注:隨著PHP7.4中預(yù)加載的出現(xiàn),這個(gè)問(wèn)題將得到部分解決)
一個(gè)PHP進(jìn)程能處理多個(gè)請(qǐng)求嗎?
您可以編寫(xiě)持續(xù)時(shí)間超過(guò)幾分鐘的PHP腳本(最多幾小時(shí)或幾天):例如Cron任務(wù)、CSV解析器、隊(duì)列處理程序。所有這些工作遵循一個(gè)模式:他們獲取一條任務(wù),處理完它,然后獲取下一個(gè)任務(wù)。代碼常駐在內(nèi)存中,因此避免了額外的操作來(lái)加載框架和應(yīng)用程序,節(jié)約了寶貴時(shí)間。
但是開(kāi)發(fā)長(zhǎng)時(shí)間運(yùn)行的腳本并不是那么容易。任何錯(cuò)誤都會(huì)殺死進(jìn)程,內(nèi)存溢出會(huì)導(dǎo)致崩潰,而且不能用F5來(lái)調(diào)試程序了。
自PHP 7后情況有所改善:可靠的垃圾收集器出現(xiàn)了,它變得更容易處理錯(cuò)誤,內(nèi)核的擴(kuò)展可以避免內(nèi)存泄漏。是的,工程師仍然需要仔細(xì)處理內(nèi)存并記住代碼中的狀態(tài)的問(wèn)題(有哪一種語(yǔ)言能讓你可以不關(guān)注這些事情呢?)當(dāng)然,在PHP 7中,驚喜并不多。
是否可以采用一種 常駐 PHP 腳本的模型,將其用于處理 HTTP 請(qǐng)求等更瑣碎的任務(wù),從而消除對(duì)每個(gè)請(qǐng)求都從頭開(kāi)始下載所有內(nèi)容的需要?
要解決這個(gè)問(wèn)題,首先需要實(shí)現(xiàn)一個(gè)服務(wù)器應(yīng)用程序,該應(yīng)用程序可以接收 HTTP 請(qǐng)求并將它們逐個(gè)重定向到 PHP worker,而不是每次都?xì)⑺浪?/p>
我們知道我們可以用純 PHP(PHP-PM)或 C 擴(kuò)展(Swoole)編寫(xiě) web 服務(wù)器。盡管每種方法都有其優(yōu)點(diǎn),但這兩種選擇都不適合我們 —— 我想要更多的東西。我們需要的不僅僅是一個(gè) web 服務(wù)器 —— 我們希望得到一個(gè)解決方案,可以使我們避免與 PHP 中的「重啟動(dòng)」相關(guān)的問(wèn)題,同時(shí)可以輕松地為特定的應(yīng)用程序進(jìn)行調(diào)整和擴(kuò)展。也就是說(shuō),我們需要一個(gè)應(yīng)用服務(wù)器。
Go 可以幫助解決這個(gè)問(wèn)題嗎?我們知道它可以,因?yàn)檫@種語(yǔ)言將應(yīng)用程序編譯成單個(gè)的二進(jìn)制文件; 它是跨平臺(tái)的; 使用自己的并行處理模型(并發(fā))和用于處理 HTTP 的庫(kù); 最后,我們可以把更多的開(kāi)源庫(kù)集成到我們的程序中。
合并兩種編程語(yǔ)言遇到的困難
首先,有必要確定兩個(gè)或多個(gè)應(yīng)用程序之間如何相互通信。
例如,使用 Alex Palaestras 的 go-php 庫(kù), 可以實(shí)現(xiàn) PHP 和 Go 進(jìn)程 (如 Apache 中的 mod_php) 之間的內(nèi)存共享。但是這個(gè)庫(kù)的功能限制了我們使用它解決問(wèn)題。
我們決定使用另一種更常見(jiàn)的方法:通過(guò)使用 sockets / pipelines 來(lái)構(gòu)建進(jìn)程之間的交互。 這種方法在過(guò)去十年中已經(jīng)證明了其可靠性,并且在操作系統(tǒng)級(jí)別得到了很好的優(yōu)化。
首先,我們創(chuàng)建了一個(gè)簡(jiǎn)單的二進(jìn)制協(xié)議,用于在進(jìn)程之間交換數(shù)據(jù)和處理傳輸錯(cuò)誤。在其最簡(jiǎn)單的形式中, 這種類型的協(xié)議類似于 一個(gè)具有固定大小的 packet 頭 (在我們的示例中為 17 個(gè)字節(jié)) 的 netstring ,其中包含的信息有 packet 的類型,其大小和二進(jìn)制掩碼的信息,用來(lái)檢查數(shù)據(jù)的完整性。
在 PHP 端,我們使用了 pack 函數(shù) ,在 Go 端,使用了 編碼 / 二進(jìn)制 庫(kù)。
有一個(gè)協(xié)議對(duì)我們來(lái)說(shuō)有點(diǎn)過(guò)時(shí),我們添加了直接 從 PHP 調(diào)用 net / rpc Go 服務(wù) 的功能。 這個(gè)功能在后面的開(kāi)發(fā)中對(duì)我們有很大的幫助,因?yàn)槲覀兛梢暂p松地將 Go 庫(kù)集成到 PHP 應(yīng)用程序中。這項(xiàng)工作的結(jié)果可以在我們的另一個(gè)開(kāi)源產(chǎn)品 Goridge 中看到。
在多個(gè) PHP Worker 之間分配任務(wù)
在交互機(jī)制實(shí)現(xiàn)之后,我們開(kāi)始思考如何更好地將任務(wù)轉(zhuǎn)移到 PHP 進(jìn)程中。當(dāng)任務(wù)到達(dá)時(shí),應(yīng)用服務(wù)器必須選擇一個(gè)空閑的 worker 來(lái)執(zhí)行它。 如果 worker 進(jìn)程因錯(cuò)誤而終止或「死亡」,我們將清除它并創(chuàng)建一個(gè)新的。 如果 worker 進(jìn)程成功執(zhí)行,我們會(huì)將它返回到可用于執(zhí)行任務(wù)的 worker 池中。
為了存儲(chǔ)活躍的 worker 進(jìn)程池,我們使用了一個(gè) 緩沖通道 , 為了從池中清除意外「死亡」的工作進(jìn)程,我們添加了一種跟蹤錯(cuò)誤和 worker 進(jìn)程狀態(tài)的機(jī)制。
最終,我們得到了一個(gè)可以運(yùn)行的 PHP 服務(wù)器,它能夠處理任何以二進(jìn)制形式呈現(xiàn)的請(qǐng)求。
為了讓我們的應(yīng)用程序作為 web 服務(wù)器開(kāi)始工作,我們必須選擇一個(gè)可靠的 PHP 標(biāo)準(zhǔn)來(lái)處理任何傳入的 HTTP 請(qǐng)求。在我們的例子中,我們只需將簡(jiǎn)單的 net / http 請(qǐng)求從 Go 轉(zhuǎn)換 為 PSR-7 格式,這樣它就可以與目前大多數(shù)可用的 PHP 框架兼容。
由于 PSR-7 被認(rèn)為是不可變的(有人會(huì)說(shuō)在技術(shù)上不是),開(kāi)發(fā)人員必須編寫(xiě)那些在原則上不將請(qǐng)求視為全局實(shí)體的應(yīng)用程序。這完全符合 PHP 常駐進(jìn)程的概念。我們的最終實(shí)現(xiàn)(尚未收到名稱)如下所示:
RoadRunner - 高 - 性能 PHP 應(yīng)用服務(wù)器
我們的第一個(gè)測(cè)試任務(wù)是一個(gè) API 后端,在該后端上,會(huì)周期性地出現(xiàn)不可預(yù)測(cè)的突發(fā)請(qǐng)求(比平時(shí)更頻繁)。雖然在大多數(shù)情況下 nginx capabilities 是足夠的,但是我們經(jīng)常因?yàn)闊o(wú)法在預(yù)期的負(fù)載增加下快速平衡系統(tǒng)而遇到 502 錯(cuò)誤。
為解決此問(wèn)題,我們?cè)?2018 年初部署了第一臺(tái) PHP / Go 應(yīng)用服務(wù)器。并立即取得了驚人的效果!我們不僅完全消除了 502 錯(cuò)誤,并且還將服務(wù)器的數(shù)量減少了三分之二,節(jié)省了大量資金并解決了令工程師和產(chǎn)品經(jīng)理頭痛的問(wèn)題。
在年中的時(shí)候,我們改進(jìn)了我們的方案,在 MIT 許可下將其發(fā)布在 GitHub 上,并命名為 RoadRunner, 從而強(qiáng)調(diào)了它驚人的速度和效率。
RoadRunner 是如何改進(jìn)你的開(kāi)發(fā)堆棧的
RoadRunner 的使用允許我們?cè)?Go 端使用中間件 net/http ,甚至在請(qǐng)求進(jìn)入 PHP 之前進(jìn)行 JWT 驗(yàn)證,以及在 Prometheus 中處理 WebSocket 和全局聚合狀態(tài)。
由于內(nèi)置的 RPC,你可以在不編寫(xiě)擴(kuò)展包的情況下,在 PHP 中打開(kāi)任何 Go 庫(kù)的 API。更重要的是,使用 RoadRunner,你可以部署不同于 HTTP 的新服務(wù)器。示例包括在 PHP 中運(yùn)行 AWS Lambda 處理器 , 創(chuàng)建強(qiáng)大的隊(duì)列 選擇器, 甚至將 gRPC 添加到我們的應(yīng)用程序中。
同時(shí)使用 PHP 和 Go ,對(duì)解決方案有了穩(wěn)定的提升,在一些測(cè)試中將應(yīng)用程序性能提高了 40 倍,改進(jìn)了調(diào)試工具,實(shí)現(xiàn)了與 Symfony 框架的集成,并添加了對(duì) HTTPS、HTTP/2、插件和 PSR-17 的支持。
“PHP與Go的合體有什么優(yōu)勢(shì)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
文章標(biāo)題:PHP與Go的合體有什么優(yōu)勢(shì)
網(wǎng)站網(wǎng)址:http://jinyejixie.com/article18/gpgdgp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、云服務(wù)器、網(wǎng)站收錄、網(wǎng)站維護(hù)、全網(wǎng)營(yíng)銷(xiāo)推廣、自適應(yīng)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
營(yíng)銷(xiāo)型網(wǎng)站建設(shè)知識(shí)