<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          swPromisePHP純異步非阻塞框架

          聯(lián)合創(chuàng)作 · 2023-09-29 12:36

          swPromise,基于swoole的PHP promise框架

          一個(gè)業(yè)務(wù)請求可能會串行的請求多個(gè)接口A-> B-> C,此時(shí)如果接口B的響應(yīng)時(shí)間較慢(關(guān)鍵性業(yè)務(wù),需要有預(yù)先準(zhǔn)備好的超時(shí)等待時(shí)間),并導(dǎo)致請求整體的時(shí)間過長,嚴(yán)重降低系統(tǒng)的響應(yīng)能力??紤]到這個(gè)業(yè)務(wù)場景下,進(jìn)展的主要時(shí)間用在等待網(wǎng)絡(luò)io返回。的方式,逐漸極大的提升服務(wù)的爆炸(NodeJS的優(yōu)勢)。

          如果某接口響應(yīng)時(shí)間超過往常,會導(dǎo)致php-fpm過程數(shù)急劇上升,從而導(dǎo)致大量cpu資源浪費(fèi)在進(jìn)程調(diào)度上面,甚至導(dǎo)致服務(wù)崩潰。swPromise框架是為了解決該問題而開發(fā)的。

          傳統(tǒng)上,為進(jìn)行初始化調(diào)用,會在代碼中實(shí)現(xiàn)大量的替換函數(shù),導(dǎo)致代碼發(fā)生性與可維護(hù)性的急劇下降。為了解決這個(gè)問題,主流方案有以下幾種:

          • 自定義事件式方案

          • 承諾/推遲

          • 高階函數(shù)修正改局部函數(shù)

          • 協(xié)程(發(fā)電機(jī))

          Swoole是PHP語言的高級網(wǎng)絡(luò)通信框架,提供了PHP語言的異步多線程服務(wù)器。swoole采用自定義事件樣式方案,為我們提供網(wǎng)絡(luò)層基本封裝?;趕woole,可以擴(kuò)展出業(yè)務(wù)層的模擬開發(fā)框架。

          tsf(騰訊服務(wù)器框架)是騰訊公司推出的PHP協(xié)程方案,基于Swoole + PHP Generator實(shí)現(xiàn)的協(xié)程。該框架使用協(xié)程模式,基于swoole與swoole框架開發(fā)。實(shí)現(xiàn)了真正的異步非多重開發(fā)模式,同時(shí)具有極高的性能。其核心代碼來源于該文章協(xié)同多任務(wù)處理使用協(xié)同程序(在PHP中?。?/a>。TSF使用了較為復(fù)雜的用戶態(tài)任務(wù)調(diào)度邏輯,在騰訊的OpenAPI中使用。另外由于使用了swoole框架,略顯重量級。

          該類實(shí)現(xiàn)了基本的然后的方法,并通過對Promise流程的延遲計(jì)算,保證了流程的動(dòng)態(tài)控制能力。該框架是一個(gè)非?;A(chǔ)的Web框架。 ,目前僅實(shí)現(xiàn)通用Future(通用延遲計(jì)算),HttpClientFuture,ResponseFuture三個(gè)連續(xù)計(jì)算類。

          該框架需要配合Swoole master版本使用,編譯參數(shù)。/configure--enable-async-httpclient,開啟初始化http client。

          演示代碼

          class Handler_Index extends \Core\Handler{
              public function run($request, $response){
                  Promise::create ( Model::getUserInfo ( 'user1', 'haha' ) )
                      ->then (function(&$promise){
                          $user1 = $promise->get('user1');
                          if($user1){
                              return Model::getUserInfo ( 'user2', 'haha2' )
                                      ->then(function(&$promise){
                                          $user2 = $promise->get('user2');
                                          $promise->accept(['user3'=>$user2['body']]);
                                      });
                          }
                          else $promise->accept();
                      })
                      ->then ( Model::getUserInfo ( 'user4', 'haha4' ) )
                      ->then ( Model::getUserInfo ( 'user5', 'haha5' ) )
                      ->then ( new ResponseFuture ($response) )
                      ->start ( new PromiseContext () );
              }
          }

          這段流程表明了,先獲取haha這個(gè)用戶的信息,寫入上下文的user1字段中。 如果獲取到了數(shù)據(jù),再獲取haha2這個(gè)用戶的信息,寫入上下文user2字段中。 并將user2的body字段放入user3字段中。然后獲取haha4和haha5的信息。 最后將所有數(shù)據(jù)輸出到網(wǎng)頁。

          可以看到,在第一個(gè)then中,通過if條件返回promise對象,實(shí)現(xiàn)了對異步流程的動(dòng)態(tài)控制。 同樣的,整個(gè)流程通過then串聯(lián)起來,已經(jīng)較為接近同步代碼的書寫了。 而使用回調(diào)的方式,代碼會變得極為恐怖。

          并行請求

          class Handler_Index extends \Core\Handler{
              public function run($request, $response){
                  Promise::create([
                      Model::getUserInfo ( 'user1', 'haha' ),
                      Model::getUserInfo ( 'user2', 'haha2' ),
                  ])->then(
                      new ResponseFuture ($response)
                  )->start(new PromiseContext ());
              }
          }

          這個(gè)請求并行獲得haha與hah2兩個(gè)用戶的數(shù)據(jù),分布放到user1和user2兩個(gè)字段中。

          存在問題

          其中Handler_Sync實(shí)現(xiàn)的就是該框架同步的使用方式。 另外,目前reject方法以及異常處理流程均沒有實(shí)現(xiàn),有興趣的朋友可以自行擴(kuò)展。

          目前有一個(gè)比較嚴(yán)重的bug,如果大量http request沒有完成就自行中斷的話,會導(dǎo)致swoole http server發(fā)生錯(cuò)誤,從而退出。在swoole前面放一個(gè)nginx就可以解決問題。

          測試方法

          啟動(dòng)

          php run.php

          測試:

          ab -n 10000 -c 100 "http://localhost:9502/async"
          ab -n 10000 -c 100 "http://localhost:9502/sync"

          經(jīng)過測試,在后端接口響應(yīng)性能有問題的情況下,swPromise 可以同時(shí)處理大量連接,用很低的 cpu 負(fù)載等待接口數(shù)據(jù)返回。

          瀏覽 20
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          編輯 分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          編輯 分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产99视频精品免视看10 | 奇米影视77777 | 思思热视频在线观看 | 免费看无码一级A片放24小时 | 啪啪视频在线观看 |