Hyperf(企業級協程框架)是一款協程框架,可以幫助用戶配置多種數據請求方式,讓中間件讀取數據更快速,方便在不同的設備上讀取數據,提升數據處理效率,解決異步非阻塞系統的開發問題,幫助平臺擴展數據訪問線程,避免訪問人數過多導致服務器出現阻塞。有需要的用戶快來統一下載體驗吧。
您可以通過這款軟件快速創建新的協程,可以配置協程工作方案,可以構建協程環境,可以配置協程運行控制方案,可以限制 Parallel 最大同時運行的協程數,幫助用戶更好開發數據處理端,快速配置數據讀取線程,結合Hyperf提供的框架組件和其他組件就可以設計新的服務系統!
軟件功能
Hyperf 是基于 Swoole 4.5+ 實現的高性能、高靈活性的 PHP 協程框架,內置協程服務器及大量常用的組件,性能較傳統基于 PHP-FPM 的框架有質的提升,提供超高性能的同時,也保持著極其靈活的可擴展性,標準組件均基于 PSR 標準 實現,基于強大的依賴注入設計,保證了絕大部分組件或類都是可替換與可復用的。
框架組件庫除了常見的協程版的 MySQL客戶端、Redis客戶端,還為您準備了協程版的 Eloquent ORM、WebSocket 服務端及客戶端、JSON RPC 服務端及客戶端、GRPC 服務端及客戶端、Zipkin/Jaeger (OpenTracing) 客戶端、Guzzle HTTP 客戶端、Elasticsearch 客戶端、Consul 客戶端、ETCD 客戶端、AMQP 組件、Apollo 配置中心、阿里云 ACM 應用配置管理、ETCD 配置中心、基于令牌桶算法的限流器、通用連接池、熔斷器、Swagger 文檔生成、Swoole Tracker、視圖引擎、Snowflake 全局 ID 生成器 等組件,省去了自己實現對應協程版本的麻煩。
Hyperf 還提供了 基于 PSR-11 的依賴注入容器、注解、AOP 面向切面編程、基于 PSR-15 的中間件、自定義進程、基于 PSR-14 的事件管理器、Redis/RabbitMQ 消息隊列、自動模型緩存、基于 PSR-16 的緩存、Crontab 秒級定時任務、國際化、Validation 表單驗證器 等非常便捷的功能,滿足豐富的技術場景和業務場景,開箱即用。
軟件特色
Hyperspeed + Flexibility = Hyperf,從名字上我們就將 超高速 和 靈活性 作為 Hyperf 的基因。
對于超高速,我們基于 Swoole 協程并在框架設計上進行大量的優化以確保超高性能的輸出。
對于靈活性,我們基于 Hyperf 強大的依賴注入組件,組件均基于 PSR 標準 的契約和由 Hyperf 定義的契約實現,達到框架內的絕大部分的組件或類都是可替換的。
基于以上的特點,Hyperf 將存在豐富的可能性,如實現 Web 服務,網關服務,分布式中間件,微服務架構,游戲服務器,物聯網(IOT)等。
官方教程
依賴自動注入
依賴自動注入是 Hyperf 提供的一個非常強大的功能,也是保持框架靈活性的根基。
Hyperf 提供了兩種注入方式,一種是大家常見的通過構造函數注入,另一種是通過 @Inject 注解注入,下面我們舉個例子并分別以兩種方式展示注入的實現;
假設我們存在一個 AppServiceUserService 類,類中存在一個 getInfoById(int $id) 方法通過傳遞一個 id 并最終返回一個用戶實體,由于返回值并不是我們這里所需要關注的,所以不做過多闡述,我們要關注的是在任意的類中獲取 UserService 并調用里面的方法,一般的方法是通過 new UserService() 來實例化該服務類,但在 Hyperf 下,我們有更優的解決方法。
通過構造函數注入只需在構造函數的參數內聲明參數的類型,Hyperf 會自動注入對應的對象或值。
通過 @Inject 注解注入
只需對對應的類屬性通過 @var 聲明參數的類型,并使用 @Inject 注解標記屬性 ,Hyperf 會自動注入對應的對象或值。
使用 @Inject 注解時需 use HyperfDiAnnotationInject; 命名空間;
通過上面的示例我們不難發現 $userService 在沒有實例化的情況下, 屬性對應的類對象被自動注入了。
不過這里的案例并未真正體現出依賴自動注入的好處及其強大之處,我們假設一下 UserService 也存在很多的依賴,而這些依賴同時又存在很多其它的依賴時,new 實例化的方式就需要手動實例化很多的對象并調整好對應的參數位,而在 Hyperf 里我們就無須手動管理這些依賴,只需要聲明一下最終使用的類即可。
而當 UserService 需要發生替換等劇烈的內部變化時,比如從一個本地服務替換成了一個 RPC 遠程服務,也只需要通過配置調整依賴中 UserService 這個鍵值對應的類為新的 RPC 服務類即可。
啟動 Hyperf 服務
由于 Hyperf 內置了協程服務器,也就意味著 Hyperf 將以 CLI 的形式去運行,所以在定義好路由及實際的邏輯代碼之后,我們需要在項目根目錄并通過命令行運行 php bin/hyperf.php start 來啟動服務。
當 Console 界面顯示服務啟動后便可通過 cURL 或 瀏覽器對服務正常發起訪問了,默認服務會提供一個首頁 http://127.0.0.1:9501/,對于本章示例引導的情況下,也就是上面的例子所對應的訪問地址為 http://127.0.0.1:9501/index/info?id=1。
重新加載代碼
由于 Hyperf 是持久化的 CLI 應用,也就意味著一旦進程啟動,已解析的 PHP 代碼會持久化在進程中,也就意味著啟動服務后您再修改的 PHP 代碼不會改變已啟動的服務,如您希望服務重新加載您修改后的代碼,您需要通過在啟動的 Console 中鍵入 CTRL + C 終止服務,再重新執行啟動命令 php bin/hyperf.php start 完成啟動和重新加載。
多端口監聽
Hyperf 支持監聽多個端口,但因為 callbacks 中的對象直接從容器中獲取,所以相同的 HyperfHttpServerServer::class 會在容器中被覆蓋。所以我們需要在依賴關系中,重新定義 Server,確保對象隔離。
WebSocket 和 TCP 等 Server 同理。
同時 路由文件,或者 注解 也需要指定對應的 server,如下:
路由文件 config/routes.php
注解
事件
除上述提到的 Event::ON_REQUEST 事件,框架還支持其他事件,所有事件名如下。
常見問題
Inject 或 Value 注解不生效
2.0 使用了構造函數中注入 Inject 和 Value 的功能,以下兩種場景,可能會導致注入失效,請注意使用。
1、原類沒有使用 Inject 或 Value,但父類使用了 Inject 或 Value,且原類寫了構造函數,同時又沒有調用父類構造函數的情況。
這樣就會導致原類不會生成代理類,而實例化的時候又調用了自身的構造函數,故沒辦法執行到父類的構造函數。 所以父類代理類中的方法 __handlePropertyHandler 就不會執行,那么 Inject 或 Value 注解就不會生效。
2、原類沒有使用 Inject 或 Value,但 Trait 中使用了 Inject 或 Value。
這樣就會導致原類不會生成代理類,故沒辦法執行構造函數里的 __handlePropertyHandler,所以 Trait 的 Inject 或 Value 注解就不會生效
基于上述兩種情況,可見 原類 是否生成代理類至關重要,所以,如果使用了帶有 Inject 或 Value 的 Trait 和 父類 時,給原類添加一個 Inject,即可解決上述兩種情況。
異步隊列消息丟失
如果在使用 async-queue 組件時,發現 handle 中的方法沒有執行,請先檢查以下幾種情況:
1、Redis 是否與其他人共用,消息被其他人消費走
2、本地進程是否存在殘余,被其他進程消費掉
以下提供萬無一失的解決辦法:
1、killall php
2、修改 async-queue 配置 channel
使用 AMQP 組件報 SwooleError: API must be called in the coroutine 錯誤
可以在 config/autoload/amqp.php 配置文件中將 params.close_on_destruct 改為 false 即可。
使用 Swoole 4.5 版本和 view 組件時訪問接口出現 404
使用 Swoole 4.5 版本和 view 組件如果出現接口 404 的問題,可以嘗試刪除 config/autoload/server.php 文件中的 static_handler_locations 配置項。
此配置下的路徑都會被認為是靜態文件路由,所以如果配置了/,就會導致所有接口都會被認為是文件路徑,導致接口 404。