Swoft 2.0.3 重大更新,發佈優雅的微服務治理

来源:https://www.cnblogs.com/stelin/archive/2019/07/09/11160679.html
-Advertisement-
Play Games

 什麼是 Swoft ? Swoft 是一款基於 Swoole 擴展實現的 PHP 微服務協程框架。Swoft 能像 Go 一樣,內置協程網路伺服器及常用的協程客戶端且常駐記憶體,不依賴傳統的 PHP-FPM。有類似 Go 語言的協程操作方式,有類似 Spring Cloud 框架靈活的註解、強大的 ...


什麼是 Swoft ?

Swoft 是一款基於 Swoole 擴展實現的 PHP 微服務協程框架。Swoft 能像 Go 一樣,內置協程網路伺服器及常用的協程客戶端且常駐記憶體,不依賴傳統的 PHP-FPM。有類似 Go 語言的協程操作方式,有類似 Spring Cloud 框架靈活的註解、強大的全局依賴註入容器、完善的服務治理、靈活強大的 AOP、標準的 PSR 規範實現等等。

Swoft 通過長達三年的積累和方向的探索,把 Swoft 打造成 PHP 界的 Spring Cloud, 它是 PHP 高性能框架和微服務治理的最佳選擇。

優雅的服務治理

Swoft 官方建議開發者使用 Service mesh 模式,比如 Istio/Envoy 框架,把業務和服務治理分開,但是 Swoft 也為中小型企業快速構建微服務提供了一套微服務組件。

服務註冊與發現

服務註冊與發現,需要用到 Swoft 官方提供的 swoft-consul 組件,如果其它第三方也類似。

註冊與取消服務

監聽 SwooleEvent::START 事件,註冊服務

/**
 * Class RegisterServiceListener
 *
 * @since 2.0
 *
 * @Listener(event=SwooleEvent::START)
 */
class RegisterServiceListener implements EventHandlerInterface
{
    /**
     * @Inject()
     *
     * @var Agent
     */
    private $agent;

    /**
     * @param EventInterface $event
     */
    public function handle(EventInterface $event): void
    {
        /* @var HttpServer $httpServer */
        $httpServer = $event->getTarget();

        $service = [
            // ....
        ];

        $scheduler = Swoole\Coroutine\Scheduler();
        $scheduler->add(function () use ($service) {
            // Register
            $this->agent->registerService($service);
            CLog::info('Swoft http register service success by consul!');
        });
        $scheduler->start();
    }
}

監聽 SwooleEvent::SHUTDOWN 事件,取消服務

/**
 * Class DeregisterServiceListener
 *
 * @since 2.0
 *
 * @Listener(SwooleEvent::SHUTDOWN)
 */
class DeregisterServiceListener implements EventHandlerInterface
{
    /**
     * @Inject()
     *
     * @var Agent
     */
    private $agent;

    /**
     * @param EventInterface $event
     */
    public function handle(EventInterface $event): void
    {
        /* @var HttpServer $httpServer */
        $httpServer = $event->getTarget();

        $scheduler = Swoole\Coroutine\Scheduler();
        $scheduler->add(function () use ($httpServer) {
            $this->agent->deregisterService('swoft');
        });
        $scheduler->start();
    }
}    

服務發現

定義服務提供者

/**
 * Class RpcProvider
 *
 * @since 2.0
 *        
 * @Bean()
 */
class RpcProvider implements ProviderInterface
{
    /**
     * @Inject()
     *
     * @var Agent
     */
    private $agent;

    /**
     * @param Client $client
     *
     * @return array
     * @example
     * [
     *     'host:port'
     * ]
     */
    public function getList(Client $client): array
    {
        // Get health service from consul
        $services = $this->agent->services();

        $services = [

        ];

        return $services;
    }
}

配置服務提供者

return [
    'user'           => [
      'class'   => ServiceClient::class,
      'provider' => bean(RpcProvider::class)
      // ...
    ]
];

服務熔斷

Swoft 使用 @Breaker 註解實現熔斷,可以在任何方法上面進行熔斷操作。 

/**
 * Class BreakerLogic
 *
 * @since 2.0
 *
 * @Bean()
 */
class BreakerLogic
{
    /**
     * @Breaker(fallback="funcFallback")
     *
     * @return string
     * @throws Exception
     */
    public function func(): string
    {
        // Do something

        throw new Exception('Breaker exception');
    }
    
    /**
     * @return string
     */
    public function funcFallback(): string
    {
        return 'funcFallback';
    }
}

服務限流

Swoft 中使用 @RateLimiter 註解實現服務限流,可以在任何方法上面限流,不僅僅是控制器,且 KEY 還支持 symfony/expression-language 表達式。

/**
 * Class LimiterController
 *
 * @since 2.0
 *
 * @Controller(prefix="limiter")
 */
class LimiterController
{
    /**
     * @RequestMapping()
     * @RateLimiter(key="request.getUriPath()", fallback="limiterFallback")
     *
     * @param Request $request
     *
     * @return array
     */
    public function requestLimiter(Request $request): array
    {
        $uri = $request->getUriPath();
        return ['requestLimiter', $uri];
    }

    /**
     * @param Request $request
     *
     * @return array
     */
    public function limiterFallback(Request $request): array
    {
        $uri = $request->getUriPath();
        return ['limiterFallback', $uri];
    }
}

配置中心

配置中心,需要用到 Swoft 官方提供的 Swoft-apollo 組件,如果其它第三方也類似。

聲明Agent

/**
 * Class AgentCommand
 *
 * @since 2.0
 *
 * @Command("agent")
 */
class AgentCommand
{
    /**
     * @Inject()
     *
     * @var Config
     */
    private $config;

    /**
     * @CommandMapping(name="index")
     */
    public function index(): void
    {
        $namespaces = [
            'application'
        ];

        while (true) {
            try {
                $this->config->listen($namespaces, [$this, 'updateConfigFile']);
            } catch (Throwable $e) {
                CLog::error('Config agent fail(%s %s %d)!', $e->getMessage(), $e->getFile(), $e->getLine());
            }
        }
    }

    /**
     * @param array $data
     *
     * @throws ContainerException
     * @throws ReflectionException
     */
    public function updateConfigFile(array $data): void
    {
        foreach ($data as $namespace => $namespaceData) {
            $configFile = sprintf('@config/%s.php', $namespace);

            $configKVs = $namespaceData['configurations'] ?? '';
            $content   = '<?php return ' . var_export($configKVs, true) . ';';
            Co::writeFile(alias($configFile), $content, FILE_NO_DEFAULT_CONTEXT);

            CLog::info('Apollo update success!');

            /** @var HttpServer $server */
            $server = bean('httpServer');
            $server->restart();
        }
    }
}

啟動Agent

Agent 只需要在服務(Http/RPC/Websocket)啟動前,運行即可。

php bin/swoft agent:index

更新內容

移除(Remove)

  • 移除 request->json() 方法(c9e8f04)

新增(Enhancement):

  • 新增介面依賴註入(6169f84)
  • 新增 getFile 方法獲取文件上傳保存之後的信息(fe7e3a6)
  • 新增 restart() 服務新增重啟方法(2ffec37)
  • 新增調用 1.x RPC 服務支持(30d73c3)
  • 新增 AOP 類名匹配支持正則表達式(bc5e479)
  • 新增 RPC Server /Http Server 中間件命名空間 use 錯誤提示(b1cec04)
  • 新增 驗證器排除屬性欄位 unfields(b1bf44f)
  • 新增 自動寫入時間戳(dc58011)
  • 新增 模型動作事件(dc58011)
  • 新增 資料庫遷移(26bb464)
  • 新增 實體自動與 json 和數組互轉(dc58011)
  • 新增 模型批量更新方法batchUpdateByIds(dc58011)

修複(Fixed):

  • 修複 cookies 設置時的一些問題,增加一些 withCookie 相關方法(b05afbb01)
  • 修複 在console使用協程方式運行命令時,沒有捕獲處理錯誤(8a5418bf)
  • 修複 websocket server 重啟命令沒有先停止舊server問題(db2d935)
  • 修複任務返回值為 null 問題(a69347c) 
  • 修複 RPC Server 只有類中間件無法使用問題()204bc7f
  • 修複 RPC Server 返回值為 null 問題(4d091be)
  • 修複 Logger 和 CLog 日誌等級無法覆蓋和無效問題(8eb8aba)
  • 修複 模型裡面的屬性不支持自定義表達式(dc58011)

更新(Update):

  • 驗證器優化,支持自定義驗證規則(d959a4f)
  • 重命名錯誤處理管理類 ErrorHanlders 為 ErrorManager (f3a8f04b)
  • console組件的異常處理改為由error組件提供的統一處理風格 (4f47204)
  • console組件允許設置禁用命令組(c5a0269)
  • 在預設的錯誤處理中,允許設置錯誤捕獲級別。預設級別是 E_ALL | E_STRICT (afff9029)
  • 優化 啟動ws server時同時啟用了http處理功能,信息面板添加提示(83a81170)
  • 優化 啟動ws server 並同時添加rpc server啟動,信息面板沒有顯示 rpc server信息(3d1d0d848)

擴展(Extra):

  • 文檔添加支持通過google進行搜索
  • 新增 apollo 組件
  • 新增 consul 組件
  • 新增 breaker 組件
  • 新增 limter 組件

資源


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 上一篇文章 "MAT入門到精通(一)" 介紹了MAT的使用場景和基本概念,這篇文章開始介紹MAT的基本功能,後面還有兩篇,一篇是MAT的高級功能,另一篇是MAT實戰案例分析。 三、歡迎頁 使用MAT打開一個heap dump文件,解析完成後,預設會進入歡迎頁,歡迎頁里包含了一些常見的分析:最大記憶體占 ...
  • 如果這個: "leadcode的Hot100系列 62. 不同路徑 簡單的動態規劃" 看懂的話,那這題基本上是一樣的, 不同點在於: 1、這裡每條路徑相當於多了一個權值 2、結論不再固定,而是要比較不同走法哪個權值更小 針對第一點,需要把第一行和第一列的權值做一個累加: 假設這裡的權值都是1,則 | ...
  • 10-6 加法運算:提示用戶輸入提供數值輸入,常出現的一個問題是,用戶提供的是文本而不是數字。這種情況下,當你嘗試將輸入轉換為整數時,將 引發TypeError異常。編寫一個程式,提示用戶輸入兩個數字,再將它們相加並列印結果。在用戶輸入的任何一個值不是數字時都捕獲TypeError異常,並列印一條友 ...
  • 文件下載 1.寫action類 2.配置struts.xml 查看源碼發現要以流的方式返回給客戶端需要配置3個參數 上面那張圖流寫is根本調用不了getInputStream的方法要把is變數名更改為inputStream才可以。 下載完成 struts的OGNL OGNL是Object Graph ...
  • 題目比較清晰,簡單來說就是: | A | B | C | D | | | | | | | E | F | G | H | | I | J | K | L | 只能往右或者往下,從A到L,能有幾種走法。 這裡使用動態規劃的方法來做一下。 動態規劃最重要的就是動態方程,這裡簡單說下這個動態方程怎麼做出來 ...
  • 組合模式:將對象組合成樹形結構以表示“部分-整體”的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。· 意思就是用樹狀結構來表示部分和整體,使他們具有一致性,一致性的意思就是都實現了相同的介面,舉個例子,一個公司可能有研發部門和銷售部門,然後這個公司又有子公司,子公司也有研發和銷售部 ...
  • 一、安裝和簡介 ElasticSearch是一個基於Lucene的搜索伺服器。它提供了一個分散式多用戶能力的全文搜索引擎,基於RESTful web介面。Elasticsearch是用Java開發的,並作為Apache許可條款下的開放源碼發佈,是當前流行的企業級搜索引擎。 搭建運行環境 "Linux ...
  • 一、Reids介紹 redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字元串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...