Hyperf 2.2 版釋出!| 企業級的漸進式 PHP 協程框架

huangzhhui 發表於 2021-07-21
框架 PHP

前言

首先感謝所有 Hyperf 的支持者,從釋出至今兩年的時間裡,我們堅持每週釋出一個小版本,截止至今已經發布了超過 106 個版本,這是 Hyperf 團隊傳達對使用者堅持和負責任精神最直接的一種方式,我們用行動來說明一切,往後我們仍將一如既往地繼續保持 Hyperf 的迭代與維護。

同時我們也很榮幸看到越來越多的公司選擇了 Hyperf 作為公司專案的框架來使用,並反哺了很多的 Pull Request 和 Bugfixs 給 Hyperf,當前 Hyperf 的 Contributors 已超 200 人,感謝大家一起共造了生態的繁榮,我們必定不負眾望!

Thanks ALL

Thanks All Contributors

在持續迭代的過程中,我們又產生了一些新的思路。我們對這些思路進行迭代、驗證,並最終沉澱到了 2.2 版本中,很榮幸向大家公佈,Hyperf 2.2 版本釋出!

主要功能迭代

DI 底層實現重構

在 2.0-2.1 版本時,為了實現 AOP 作用於非 DI 管理的物件(如 new 關鍵詞例項化的物件時),底層實現採用了BetterReflection 元件來實現相關功能,帶來新的程式設計體驗的同時,也還是存在一些此前未攻克的問題,如下:

  • 無掃描快取時專案啟動很慢
  • 特殊場景下 Inject 和 Value 不生效
  • BetterReflection尚未支援 PHP 8 (截止發版時)

在新的版本里,我們棄用了 BetterReflection 的應用,採用了 子程式掃描的方式 來解決此前的問題,以上這些痛點,我們全部解決了~

用正向的角度來描述這個功能的變更:

  • 無快取下,啟動時間縮減一個數量級,以筆者所在公司的某個巨型專案為例,原啟動時間長達 5分鐘,新版本只需 10秒!
  • 豐富了 Inject 註解注入的適用場景,但可惜仍有一種情況下無效(父類 private 屬性注入時失效,與此前版本表現一致),我們會繼續努力攻克該場景的實現
  • 支援 PHP 8Attributes 原生註解特性

簡而言之,DI 元件作為 Hyperf 的核心元件之一,現在已經達到了一個全新的階段,創新與實用值滿格~

支援 PHP 8

Hyperf 2.2 各元件已經適配 PHP 8,註解亦相容 PHP 8Attributes 原生註解特性。

<?php
namespace App\Controller;

#[Controller]
class IndexController
{
    #[GetMapping("/test")]
    public function index()
    {
        ...
    }
}

需要注意的是,同一區域同時使用 註解(Annotations)原生註解(Attributes),底層將 忽略註解(Annotations) (即使註解不同)

<?php
namespace App\Controller;

/**
 * @Controller
 * 同一區域同時使用,註解(Annotations) 無效
 */
#[Middleware(TestMiddleware::class)]
class IndexController
{
    // 單獨使用,可以支援
    #[Inject]
    protected StdoutLoggerInterface $logger;

    /**
     * 單獨使用,可以支援
     * @GetMapping("/test")
     */
    public function index()
    {
        ...
    }
}

需要注意的是,框架雖然已經支援 PHP8,但是升級時仍需要自行確認業務程式碼和依賴的第三方元件是否滿足 PHP 8 不相容變更

可重複註解

在之前版本中,同一區域相同Annotation 無法重複使用:

/**
 * @AutoController()
 * @Middleware(FooMiddleware::class)
 * @Middleware(BarMiddleware::class)
 * 重複 @Middleware 只有一個生效!
 */
class IndexController
{

}

此前,重複使用相同註解只能通過註解巢狀方式實現:

/**
 * @AutoController()
 * @Middlewares({
 *     @Middleware(FooMiddleware::class)
 *     @Middleware(BarMiddleware::class)
 * })
 * 非常繁瑣,增加額外心智負擔
 */
class IndexController
{

}

在 2.2 中,我們實現了可重複註解:

<?php
namespace App\Controller;

#[AutoController]
#[Middleware(FooMiddleware::class)]
#[Middleware(BarMiddleware::class)]
class IndexController
{

}

當使用者自定義的註解需要可重複時,將註解的父類更改為 Hyperf\Di\Annotation\AbstractMultipleAnnotation 即可,具體可參考框架 Middleware 註解的實現。

配置中心完全重構

在此前的版本,配置中心的實現是由各個零散的元件自行實現的,各元件的實現參差不一,都有一些細節實現的區別,各元件間的程式碼重合度也是非常高的,在 2.2 版本,我們 完全重構 了相關元件,增加了 hyperf/config-center 元件,該元件將作為配置中心的統一接入層和抽象層,通過結合其他配置中心的 Driver 元件來實現相關儲存引擎的能力驅動,如 hyperf/config-center + hyperf/config-apollo 元件結合使用的方式來實現對 Apollo 配置中心的使用,其他驅動只需更換對應的驅動即可。這樣的改造使我們極大的減少了驅動的程式碼量,現在簡單幾行程式碼幾個類就能完成一個新的驅動的接入了。

在升級使用時,注意相關配置檔案的變更,新版本將由 config/autoload/config_center.php 配置檔案來管控所有相關資訊,初次建立該檔案可通過執行 php bin/hyperf.php vendor:publish hyperf/config-center 命令生成。

服務治理元件重構

在此前的版本,hyperf/service-governance 元件跟配置中心所面臨的問題也是一致的,我們在此版本也做了與配置中心類似的改變,比如通過 hyperf/service-governance + hyperf/service-governance-nacos 元件來實現 nacos 作為服務中心的使用。

在升級使用時,注意相關配置檔案的變更,新版本將由 config/autoload/services.php 配置檔案來管控所有相關資訊,內部結構有一定的改變,初次建立該檔案可通過執行 php bin/hyperf.php vendor:publish hyperf/service-governance 命令生成。

Nacos 元件完全重構

重要:一定要重讀該元件文件!!!

我們對 Nacos 元件做了 完全的重構,使該元件的程式碼實現、結構分層和 API 更加的合理,並對原來整合在一個元件內的配置中心邏輯、服務中心邏輯和客戶端程式碼進行了拆分,如上面兩個主要迭代功能介紹所示。

具體使用到 Nacos 元件的一定要重新閱讀新的文件,並根據新的文件指示來使用。

AMQP 元件連線機制重構

我們發現使用 AMQP 元件的使用者非常的多,而作為一個訊息佇列元件,其效能速度對系統的削峰效果和訊息投遞/消費速度影響是非常大的,我們通過 協程通道(Channel) 實現了一個多路複用的機制,使該元件的訊息投遞效能提升了將近一倍!在效能提升的同時,還使得客戶端與服務端間的連線穩定性得到了提升。

該元件升級後會直接切換為新的連線機制,無需做任何調整。

以下是抽取壓測對比中的關鍵資訊:

非 Confirm 模式投遞

2.1 版本

連線池內最大數量設定為 10

$ ab -c 32 -n 10000 http://127.0.0.1:9501/
Requests per second:    5340.80 [#/sec] (mean)
Time per request:       5.992 [ms] (mean)
Time per request:       0.187 [ms] (mean, across all concurrent requests)
Transfer rate:          928.38 [Kbytes/sec] received

2.2 版本

設定 2 個多路複用的連線

$ ab -c 32 -n 10000 -k http://127.0.0.1:9501/
Requests per second:    9101.44 [#/sec] (mean)
Time per request:       3.516 [ms] (mean)
Time per request:       0.110 [ms] (mean, across all concurrent requests)
Transfer rate:          1626.53 [Kbytes/sec] received

Confirm 模式投遞

2.1 版本

連線池內最大數量設定為 10

$ ab -c 32 -n 5000 -k http://127.0.0.1:9501/ 
Requests per second:    797.73 [#/sec] (mean)
Time per request:       40.114 [ms] (mean)
Time per request:       1.254 [ms] (mean, across all concurrent requests)
Transfer rate:          142.56 [Kbytes/sec] received

2.2 版本

設定 2 個多路複用的連線

$ ab -c 32 -n 5000 -k http://127.0.0.1:9501/Requests per second:    1595.94 [#/sec] (mean)Time per request:       20.051 [ms] (mean)Time per request:       0.627 [ms] (mean, across all concurrent requests)Transfer rate:          285.21 [Kbytes/sec] received

3 個 Incubator 元件畢業進入主庫

自從採用 Incubator 機制來孵化元件後,產生了大量的新元件,很榮幸在 2.2 版本時,有 3 個 Incubator 元件畢業進入主庫,這也意味著這些元件進入了生產可用階段~

以下為各個畢業的元件及其簡介

hyperf/dag

該元件是一個輕量級有向無環圖 (Directed Acyclic Graph) 任務編排庫,通過該元件可以很輕鬆的完成任務的編排和執行。

hyperf/rpc-multiplex

該元件是一個實現多路複用的 RPC 協議連線元件,通過使用該庫可以得到效能更高和連線更穩定的 RPC 功能;

hyperf/rpn

該元件是一個 逆波蘭表示法 的實現元件,RPN 是一種是由波蘭數學家揚·武卡謝維奇1920年引入的數學表示式方式,在逆波蘭記法中,所有操作符置於運算元的後面,因此也被稱為字尾表示法。逆波蘭記法不需要括號來標識操作符的優先順序。通過該元件可以完成 逆波蘭表示式 的解析。

依賴升級

  • 升級friendsofphp/php-cs-fixer^3.0;
  • 升級psr/container^1.0|^2.0;
  • 升級egulias/email-validator^3.0;
  • 升級markrogoyski/math-php^2.0;
  • 升級league/flysystem^1.0|^2.0;
依賴項已更改
  • #3577 domnikl/statsd廢棄,不再維護。作者建議改用slickdeals/statsd包;

即將棄用 API

  • #3636 Hyperf\Utils\Resource將在 v2.3 中被棄用,請改用Hyperf\Utils\ResourceGenerator

變更明細

  • #3334LengthAwarePaginator::toArray()的返回值更改為與Paginator::toArray()的一致;
  • #3550kafka刪除了brokerbootstrap_server請使用brokersbootstrap_servers代替;
  • #3580 將切面的預設優先順序更改為 0;
  • #3582AMQP 的消費者標籤更改為空字串;
  • #3634 使用 Fork Process 策略替換 BetterReflection策略;
    • #3649hyperf/database使用gen:model時移除了roave/better-reflection
    • #3651LazyLoader 中移除了roave/better-reflection
    • #3654 在其他元件中移除了roave/better-reflection
  • #3676使用promphp/prometheus_client_php代替endclothing/prometheus_client_php
  • #3694更改Hyperf\CircuitBreaker\CircuitBreakerInterface為支援 PHP8
    • CircuitBreaker::inc*Counter()CircuitBreaker::incr*Counter()
    • 更改了 AbstractHandler::switch()方法的型別提示;
  • #3706PHP8 中將@Middlewares({@Middleware(FooMiddleware::class)})的書寫風格更改為#[Middlewares(FooMiddleware::class)]
  • #3715 重構nacos元件,一定要重讀文件;
  • #3722 刪除了 config_apollo.php配置,請改用config_center.php
  • #3725 刪除了 config_etcd.php配置,請改用config_center.php
  • #3730kafka中刪除了brokersupdate_brokers配置;
  • #3733 刪除了 zookeeper.php配置,請改用config_center.php
  • #3734 #3772 分割了nacosconfig-nacosservice-governance-nacos
  • #3734 重新命名nacos-sdk 元件名為 nacos
  • #3737 重構配置中心和配置驅動程式
    • 新增AbstractDriver並將重複的程式碼併合到抽象類中
    • 新增PipeMessageInterface以統一配置獲取程式的訊息結構
  • #3817 #3818 從 service-governance 元件中分離出 service-governance-consul 元件;
更多

升級指南

我們提供了詳盡的升級指南,請查閱官方文件 - 2.2 升級指南

Github 👈👈👈👈👈 點 Star 支援我們
Gitee 碼雲 👈👈👈👈👈 點 Star 支援我們
Hyperf 官網
Hyperf 文件
Hyperf 交流群: 862099724(已滿)
Hyperf 交流 2 群: 811414891(已滿)
Hyperf 交流 3 群: 589051831
釘釘群 一群: 34538367(已滿)
釘釘群 二群: 34488757

本作品採用《CC 協議》,轉載必須註明作者和本文連結