本篇文章為大家展示了Swoole4.4中怎么實(shí)現(xiàn)協(xié)程搶占式調(diào)度器,內(nèi)容簡明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序制作、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了叢臺(tái)免費(fèi)建站歡迎大家使用!協(xié)程調(diào)度
去年Swoole
推出了4.0
版本后,完整的支持PHP
協(xié)程,我們可以基于協(xié)程實(shí)現(xiàn)CSP
編程,身邊的開發(fā)者驚呼,原來PHP代碼還可以這樣寫。Swoole
的協(xié)程默認(rèn)是基于IO調(diào)度,程序中有阻塞會(huì)自動(dòng)讓出當(dāng)前協(xié)程,協(xié)程的各種優(yōu)勢(shì)我們不在這里展開討論。如果是IO
密集型的場(chǎng)景,可以表現(xiàn)得很不錯(cuò)。但是對(duì)于CPU
密集型的場(chǎng)景,會(huì)導(dǎo)致一些協(xié)程因?yàn)榈貌坏?code>CPU時(shí)間片被餓死。
搶占式調(diào)度
我們?cè)诮衲昴瓿蹙陀?jì)劃實(shí)現(xiàn)Swoole
的搶占式調(diào)度,以滿足實(shí)現(xiàn)有些場(chǎng)景下的不均衡調(diào)度帶來的問題。我們中間經(jīng)歷了幾個(gè)版本,在這里和大家分享一下開發(fā)過程中的動(dòng)機(jī)和解決辦法。
我們目的是為了均衡調(diào)度每個(gè)協(xié)程的CPU
時(shí)間,比如協(xié)程3需要比較長的執(zhí)行時(shí)間,我們必須把協(xié)程3的CPU
時(shí)間主動(dòng)中斷,而不依賴IO
事件,使得每個(gè)協(xié)程得到平均的執(zhí)行時(shí)間。
起初,我們的想法是可以從PHP
的循環(huán)中自動(dòng)檢測(cè)執(zhí)行實(shí)踐,若達(dá)到限制,可以自動(dòng)讓出當(dāng)前協(xié)程。因?yàn)楫吘购苌儆腥艘获R平川的寫出占用很多CPU
的代碼,大都通過循環(huán)條件來控制。我們hook
循環(huán)指令,每次執(zhí)行循環(huán)指令的時(shí)候,都來檢查協(xié)程的執(zhí)行時(shí)間,我們很欣喜的得到了最初的版本。但是這樣做比較hack,而且opcode
經(jīng)過opcache
優(yōu)化后,情況會(huì)變得有些復(fù)雜。
后來我們使用PHP
的ticks
機(jī)制,也就是在PHP
代碼編譯期間,注入ticks
指令,可以執(zhí)行相應(yīng)的函數(shù),我們可以在這些函數(shù)中檢測(cè)處理協(xié)程的時(shí)間,達(dá)到搶占式的效果,但是這里有一個(gè)問題,PHP
的declare(ticks=N)
語法,只對(duì)當(dāng)前腳本范圍有效,也就是說項(xiàng)目稍微大點(diǎn),require
或者include
進(jìn)來的腳本,并不會(huì)自動(dòng)注入ticks
指令,這樣Swoole
開發(fā)者幾乎是無法接受的。我們也試圖給PHP
官方提一個(gè)PR,可以在擴(kuò)展層設(shè)置一個(gè)全局默認(rèn)的ticks
,但是官方不愿意采納我們的提交,因?yàn)楣俜接X得這個(gè)功能對(duì)性能損耗比較大,而且有可能在PHP8
移除這個(gè)功能。其實(shí)經(jīng)過實(shí)測(cè)這個(gè)性能損耗并不大,而且我們已經(jīng)在生產(chǎn)環(huán)境驗(yàn)證,并取得了顯著的效果,即可以讓出某些CPU
密集的邏輯部分,使得服務(wù)整個(gè)相應(yīng)時(shí)間更加均衡。
下圖是我們生產(chǎn)環(huán)境一個(gè)RPC接口的調(diào)用端統(tǒng)計(jì)數(shù)據(jù)對(duì)比,客戶端等待超時(shí)時(shí)間為2s,超時(shí)則統(tǒng)計(jì)為錯(cuò)誤。
左邊一側(cè)是沒有搶占式調(diào)度,右側(cè)是開了搶占式調(diào)度,可以發(fā)現(xiàn),左側(cè)總是會(huì)有偶爾超時(shí)情況,而經(jīng)過優(yōu)化之后,沒有一個(gè)超時(shí)的請(qǐng)求,請(qǐng)求響應(yīng)時(shí)間非常平滑,提升了服務(wù)的穩(wěn)定性。
可以從上圖看出,由于搶占式調(diào)度的加入,去除了請(qǐng)求耗時(shí)高的毛刺,使得平均請(qǐng)求時(shí)間變得更加平滑,穩(wěn)定。
想要做搶占式調(diào)度,對(duì)于PHP
來說,有兩個(gè)途徑
單線程的PHP
的執(zhí)行流,通過執(zhí)行指令做文章,可以在PHP
執(zhí)行流程中注入邏輯,以檢查執(zhí)行時(shí)間,再加上Swoole
的協(xié)程能力,可以在不同的協(xié)程中切換,以達(dá)到搶占CPU
的目的。
考慮開線程,負(fù)責(zé)檢查當(dāng)前執(zhí)行協(xié)程執(zhí)行時(shí)間。
經(jīng)過以上辦法的嘗試,注入指令的路數(shù)基本是無法得到官方的支持,我們只能另謀出路,多開一個(gè)線程,只負(fù)責(zé)檢查當(dāng)前協(xié)程。具體的做法是,利用PHP-7.1.0
引入的VM interrupt
機(jī)制,默認(rèn)每隔5ms檢查一下當(dāng)前協(xié)程是否達(dá)到較大執(zhí)行時(shí)間,默認(rèn)為10ms,如果超過,則讓出當(dāng)前協(xié)程,達(dá)到被其他協(xié)程搶占的目的。
示例代碼
需要Swoole 4.4
或更高版本
<?php Co::set(['enable_preemptive_scheduler' => 1]); $start = microtime(1); echo "start\n"; $flag = 1; go(function () use (&$flag) { echo "coro 1 start to loop\n"; $i = 0; for (;;) { if (!$flag) { break; } $i++; } echo "coro 1 can exit\n"; }); $end = microtime(1); $msec = ($end - $start) * 1000; echo "use time $msec\n"; go(function () use (&$flag) { echo "coro 2 set flag = false\n"; $flag = false; }); echo "end\n";
執(zhí)行結(jié)果
start coro 1 start to loop use time 11.121988296509 coro 2 set flag = false end coro 1 can exit
可以發(fā)現(xiàn),代碼邏輯可以從第一個(gè)協(xié)程的死循環(huán)中自動(dòng)yield
出來,執(zhí)行第二個(gè)協(xié)程,如果沒有這個(gè)特性,第二個(gè)協(xié)程永遠(yuǎn)不會(huì)被執(zhí)行,導(dǎo)致被餓死。而這樣做,第二個(gè)協(xié)程可以順利被執(zhí)行,最后執(zhí)行結(jié)束后,第一個(gè)協(xié)程也會(huì)接著繼續(xù)往下執(zhí)行。達(dá)到我們的第二個(gè)協(xié)程主動(dòng)搶占第一個(gè)協(xié)程CPU
的效果。
這個(gè)特性在生產(chǎn)環(huán)境非常有用,尤其是對(duì)于實(shí)時(shí)系統(tǒng)或者響應(yīng)時(shí)間比較敏感的場(chǎng)景。
上述內(nèi)容就是Swoole4.4中怎么實(shí)現(xiàn)協(xié)程搶占式調(diào)度器,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
名稱欄目:Swoole4.4中怎么實(shí)現(xiàn)協(xié)程搶占式調(diào)度器-創(chuàng)新互聯(lián)
文章轉(zhuǎn)載:http://jinyejixie.com/article38/diojsp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機(jī)網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、網(wǎng)站維護(hù)、網(wǎng)站排名、微信公眾號(hào)、App開發(fā)
聲明:本網(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í)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容