您好,登錄后才能下訂單哦!
這篇文章主要介紹“ PHP 實現微服務的方法是什么”,在日常操作中,相信很多人在 PHP 實現微服務的方法是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答” PHP 實現微服務的方法是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
隨著互聯網瀏覽越來越大. 傳統的 MVC 單一架構隨著應用規模的不斷擴大,應用模塊不斷增加,整個應用也顯得越來越臃腫,維護起來也更加困難.
我們必須采取措施,按應用拆分,就是把原來的應用按照業務特點拆分成多個應用。比如一個大型電商系統可能包含用戶系統、商品系統、訂單系統、評價系統等等,我們可以把他們獨立出來形成一個個單獨的應用。多應用架構的特點是應用之間各自獨立 ,不相互調用。
多應用雖然解決了應用臃腫問題,但應用之間相互獨立,有些共同的業務或代碼無法復用。
對于一個大型的互聯網系統,一般會包含多個應用,而且應用之間往往還存在共同的業務,并且應用之間還存在調用關系。除此之外 ,對于大型的互聯網系統還有一些其它的挑戰,比如如何應對急劇增長的用戶,如何管理好研發團隊快速迭代產品研發,如何保持產品升級更加穩定等等 。
因此,為了使業務得到很好的復用,模塊更加容易拓展和維護,我們希望業務與應用分離,某個業務不再屬于一個應用,而是作為一個獨立的服務單獨進行維護。應用本身不再是一個臃腫的模塊堆積,而是由一個個模塊化的服務組件組合而成。
那么采用服務化
給有那些亮點的特色呢 ?
應用按業務拆分成服務
各個服務均可獨立部署
服務可被多個應用共享
服務之間可以通信
架構上系統更加清晰
核心模塊穩定,以服務組件為單位進行升級,避免了頻繁發布帶來的風險
開發管理方便
單獨團隊維護、工作分明,職責清晰
業務復用、代碼復用
非常容易拓展
系統服務化之后, 增加了依賴關系復雜, 也會增加服務與服務之間交互的次數. 在 fpm
的開發模式下. 因為無法常駐內存給我們帶來了, 每一次請求都要從零開始加載到退出進程, 增加了很多無用的開銷, 數據庫連接無法復用也得不到保護, 由于fpm
是以進程為單位的fpm
的進程數也決定了并發數, 這也是是fpm
開發簡單給我們帶來的問題. 所以說為什么現在互聯網平臺Java
比較流行了,.NET
和PHP
在這方面都不行。PHP非內存常駐
的就不用說了。除此之外,還有很多其他問題需要解決。
服務越來越多,配置管理復雜
服務間依賴關系復雜
服務之間的負載均衡
服務的拓展
服務監控
服務降級
服務鑒權
服務上線與下線
服務文檔 ......
你可以想象一下常駐內存給我們帶來的好處 比如
只啟動框架初始化 如果常駐內存我們只是在啟動的時候處理化框架初始化在內存中,專心處理請求
連接復用,有些工程師并不能特別理解,如果不用連接池,來一個請求就發一個連接怎么樣?這樣就會導致后端資源連接過多。對一些基礎服務來說,比如 Redis,數據庫,連接是個昂貴的消耗。
那么有沒有好的方案呢?答案是有的,而且很多人都在用這個框架,它就是-Swoft
。Swoft
就是一個帶有服務治理
功能的RPC框架。Swoft
是首個 PHP常駐內存協程全棧框架, 基于 Spring Boot
提出的約定大于配置的核心理念
Swoft
提供了類似 Dubbo
更為優雅的方式使用 RPC
服務, Swoft
性能是非常棒的有著類似Golang
性能, 下面是我的PC
對Swoft
性能的壓測情況.
ab
壓力測試處理速度十分驚人, 在 i78代
CPU, 16GB
內存下
100000萬個請求只用了
5s時間在
fpm開發模式下基本不可能達到. 這也足以證明
Swoft` 的高性能和穩定性,
微服務治理過程中,經常會涉及注冊啟動的服務到第三方集群,比如 consul / etcd 等等,本章以 Swoft 框架中使用 swoft-consul 組件,實現服務注冊與發現為例。
實現邏輯
<?php declare(strict_types=1);namespace App\Common;use ReflectionException;use Swoft\Bean\Annotation\Mapping\Bean;use Swoft\Bean\Annotation\Mapping\Inject;use Swoft\Bean\Exception\ContainerException;use Swoft\Consul\Agent;use Swoft\Consul\Exception\ClientException;use Swoft\Consul\Exception\ServerException;use Swoft\Rpc\Client\Client;use Swoft\Rpc\Client\Contract\ProviderInterface;/** * Class RpcProvider * * @since 2.0 * * @Bean() */class RpcProvider implements ProviderInterface{ /** * @Inject() * * @var Agent */ private $agent; /** * @param Client $client * * @return array * @throws ReflectionException * @throws ContainerException * @throws ClientException * @throws ServerException * @example * [ * 'host:port', * 'host:port', * 'host:port', * ] */ public function getList(Client $client): array { // Get health service from consul $services = $this->agent->services(); $services = [ ]; return $services; } }
在分布式環境下,特別是微服務結構的分布式系統中, 一個軟件系統調用另外一個遠程系統是非常普遍的。這種遠程調用的被調用方可能是另外一個進程,或者是跨網路的另外一臺主機, 這種遠程的調用和進程的內部調用最大的區別是,遠程調用可能會失敗,或者掛起而沒有任何回應,直到超時。更壞的情況是, 如果有多個調用者對同一個掛起的服務進行調用,那么就很有可能的是一個服務的超時等待迅速蔓延到整個分布式系統,引起連鎖反應, 從而消耗掉整個分布式系統大量資源。最終可能導致系統癱瘓。
斷路器(Circuit Breaker)模式就是為了防止在分布式系統中出現這種瀑布似的連鎖反應導致的災難。
基本的斷路器模式下,保證了斷路器在open狀態時,保護supplier不會被調用, 但我們還需要額外的措施可以在supplier恢復服務后,可以重置斷路器。一種可行的辦法是斷路器定期探測supplier的服務是否恢復, 一但恢復, 就將狀態設置成close。斷路器進行重試時的狀態為半開(half-open)狀態。
熔斷器的使用想到簡單且功能強大,使用一個 @Breaker
注解即可,Swoft
的熔斷器可以用于任何場景, 例如 服務調用的時候使用, 請求第三方的時候都可以對它進行熔斷降級
<?php declare(strict_types=1);namespace App\Model\Logic;use Exception;use Swoft\Bean\Annotation\Mapping\Bean;use Swoft\Breaker\Annotation\Mapping\Breaker;/** * Class BreakerLogic * * @since 2.0 * * @Bean() */class BreakerLogic{ /** * @Breaker(fallback="loopFallback") * * @return string * @throws Exception */ public function loop(): string { // Do something throw new Exception('Breaker exception'); } /** * @return string * @throws Exception */ public function loopFallback(): string { // Do something } }
限流、熔斷、降級這個強調多少遍都不過分,因為確實很重要。服務不行的時候一定要熔斷。限流是一個保護自己最大的利器,如果沒有自我保護機制,不管有多少連接都會接收,如果后端處理不過來,前端流量又很大的時候肯定就掛了。
限流是對稀缺資源訪問時,比如秒殺,搶購的商品時,來限制并發和請求的數量,從而有效的進行削峰并使得流量曲線平滑。限流的目的是對并發訪問和并發請求進行限速,或者一個時間窗口內請求進行限速從而來保護系統,一旦達到或超過限制速率就可以拒絕服務,或者進行排隊等待等。
Swoft
限流器底層采用的是令牌桶算法,底層依賴于 Redis
實現分布式限流。
Swoft 限速器不僅可以限流控制器,也可以限制任何 bean 里面的方法,可以控制方法的訪問速率。這里以下面使用示例詳解
<?php declare(strict_types=1);namespace App\Model\Logic;use Swoft\Bean\Annotation\Mapping\Bean;use Swoft\Limiter\Annotation\Mapping\RateLimiter;/** * Class LimiterLogic * * @since 2.0 * * @Bean() */class LimiterLogic{ /** * @RequestMapping() * @RateLimiter(rate=20, fallback="limiterFallback") * * @param Request $request * * @return array */ public function requestLimiter2(Request $request): array { $uri = $request->getUriPath(); return ['requestLimiter2', $uri]; } /** * @param Request $request * * @return array */ public function limiterFallback(Request $request): array { $uri = $request->getUriPath(); return ['limiterFallback', $uri]; } }
key 這里支持 symfony/expression-language
表達式, 如果被限速會調用 fallback
中定義的limiterFallback
方法
說起配置中心前我們先說說配置文件,我們并不陌生,它提供我們可以動態修改程序運行能力。引用別人的一句話就是:
系統運行時(runtime)飛行姿態的動態調整!
我可以把我們的工作稱之為在快速飛行的飛機上修理零件。我們人類總是無法掌控和預知一切。對于我們系統來說,我們總是需要預留一些控制線條,以便在我們需要的時候做出調整,控制系統方向(如灰度控制、限流調整),這對于擁抱變化的互聯網行業尤為重要。
對于單機版,我們稱之為配置(文件);對于分布式集群系統,我們稱之為配置中心(系統);
隨著業務的發展、微服務架構的升級,服務的數量、程序的配置日益增多(各種微服務、各種服務器地址、各種參數),傳統的配置文件方式和數據庫的方式已無法滿足開發人員對配置管理的要求:
安全性:配置跟隨源代碼保存在代碼庫中,容易造成配置泄漏;
時效性:修改配置,需要重啟服務才能生效;
局限性:無法支持動態調整:例如日志開關、功能開關;
因此,我們需要配置中心來統一管理配置!把業務開發者從復雜以及繁瑣的配置中解脫出來,只需專注于業務代碼本身,從而能夠顯著提升開發以及運維效率。同時將配置和發布包解藕也進一步提升發布的成功率,并為運維的細力度管控、應急處理等提供強有力的支持。
關于分布式配置中心,網上已經有很多開源的解決方案,例如:
Apollo是攜程框架部門研發的分布式配置中心,能夠集中化管理應用不同環境、不同集群的配置,配置修改后能夠實時推送到應用端,并且具備規范的權限、流程治理等特性,適用于微服務配置管理場景。
本章以Apollo
為例,從遠端配置中心拉取配置以及安全重啟服務。如果對 Apollo
不熟悉,可以先看Swoft
擴展 Apollo
組件以及閱讀 Apollo
官方文檔。
本章以 Swoft
中使用 Apollo
為例,當 Apollo
配置變更后,重啟服務(http-server / rpc-server/ ws-server)。如下是一個 agent 例子:
<?php declare(strict_types=1);namespace App\Model\Logic;use Swoft\Apollo\Config;use Swoft\Apollo\Exception\ApolloException;use Swoft\Bean\Annotation\Mapping\Bean;use Swoft\Bean\Annotation\Mapping\Inject;/** * Class ApolloLogic * * @since 2.0 * * @Bean() */class ApolloLogic{ /** * @Inject() * * @var Config */ private $config; /** * @throws ApolloException */ public function pull(): void { $data = $this->config->pull('application'); // Print data var_dump($data); } }
以上就是一個簡單的 Apollo 配置拉取,Swoft-Apollo
除此方法外,還提供了更多的使用方法。
到此,關于“ PHP 實現微服務的方法是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。