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

圖片描述

什麼是 Swoft ?

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

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

優雅的服務治理

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

服務註冊與發現

服務註冊與發現,須要用到 Swoft 官方提供的 swoft-consul 組件,若是其它第三方也相似。github

註冊與取消服務

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

/**
 * 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;
    }
}

配置服務提供者express

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

服務熔斷

Swoft 使用 @Breaker 註解實現熔斷,能夠在任何方法上面進行熔斷操做。json

/**
 * 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)
  • 重命名錯誤處理管理類 ErrorHanldersErrorManager (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 組件

資源

相關文章
相關標籤/搜索