微服務的概念由 Martin Fowler 於2014年3月提出:php
微服務架構是一種架構模式,它提倡將單一應用程序劃分紅一組小的服務,服務之間相互協調、互相配合,爲用戶提供最終價值。每一個服務運行在其獨立的進程中,服務和服務之間採用輕量級的通訊機制相互溝通。每一個服務都圍繞着具體的業務進行構建,而且可以被獨立的部署到生產環境、類生產環境等。另外,應儘可能避免統一的、集中的服務管理機制,對具體的一個服務而言,應根據業務上下文,選擇合適的語言、工具對其進行構建。
下圖是一個電商系統的微服務架構圖:前端
微服務架構與單體應用相比,具備如下優勢:java
沒有銀彈,微服務架構在帶來諸多優勢的同時,也會有以下缺點:node
能夠說,正是傳統應用架構的系統變得日益臃腫,面臨難以維護、擴展的問題,同時容器化技術(Docker)的蓬勃發展和 DevOps 思想的日漸成熟,催生了新的架構設計風格 – 微服務架構的出現。git
微服務架構中的各個服務一般不在同一個機器上,甚至不會在同一個網絡環境裏,所以微服務之間如何調用是一個亟待解決的問題,咱們一般使用 RPC 協議來解決:程序員
RPC(Remote Procedure Call),即遠程過程調用,是一個計算機通訊協議。該協議容許運行於一臺計算機的程序調用另外一臺計算機的子程序,而程序員無需額外地爲這個交互做用編程。——維基百科
實現了 RPC 協議的框架,可讓服務方和調用方屏蔽各類底層細節,讓調用方像調用本地函數同樣調用遠端的函數(服務)。RPC 框架通常爲服務端和客戶端提供了序列化、反序列化、鏈接池管理、負載均衡、故障轉移、隊列管理、超時管理、異步管理等職能。在網上找到一個說明 RPC 框架工做原理圖:github
目前,根據序列化數據時採用的技術的不一樣,可分爲 JSON-RPC
和 gRPC
兩種:web
JSON-RPC
優勢是易於使用和閱讀。gRPC
具備低延遲、高效率、高擴展性、支持分佈式等優勢。如今有了 RPC 框架,咱們就能夠只考慮服務與服務之間的業務調用而不用考慮底層傳輸細節。此時,若是服務 A 想調用服務 B 時,咱們能夠在服務 A 中配置服務 B 的 IP 地址和端口,而後剩下的傳輸細節就交給 RPC 框架。這在微服務規模很小的狀況下是沒有問題的,可是在服務規模很大、並且每一個服務不止部署一個實例的狀況下會面臨巨大挑戰。好比,服務 B 部署了三個實例,這時候服務 A 想調用服務 B 該請求哪一個實例的 IP ?假如服務 B 部署的三個實例有兩個都掛掉了,服務 A 可能會依舊去請求掛掉的實例,服務將不可用。將 IP 地址和端口寫成配置文件顯得很不靈活,微服務架構每每要保證高可用及動態伸縮。spring
所以,咱們須要一個服務註冊與服務發現的工具,可以動態地變動服務信息,而且找到可用的服務的 IP 地址和端口。目前市面上服務發現的工具備不少,如 Consul、ZooKeeper 、Etcd、Doozerd 等,本文主要以 Consul 軟件爲例。docker
Consul 是一個支持多數據中心、分佈式高可用的服務發現和配置共享的服務軟件,由 HashiCorp 公司用 Go 語言開發, 基於 Mozilla Public License 2.0 的協議進行開源。 Consul 支持健康檢查,並容許 HTTP 、gRPC 和 DNS 協議調用 API 存儲鍵值對。
下面是引入服務註冊與服務發現工具後的架構圖:
在這個架構中:
可見, Consul 軟件除了服務註冊和服務發現的功能以外,還提供了健康檢查和狀態變動通知的功能。
對於 Java 開發者來講,有技術至關成熟的 Dubbo 和 Spring Cloud 微服務框架可供選擇。做爲一名 PHPer,我用 Google 查了一下「PHP + 微服務」,發現有用的相關內容少之又少 ,沒有什麼實質性的參考價值,無限惆悵。。。幸虧,有大神在基於 Swoole 擴展的基礎上,實現了高性能、高靈活性的 PHP 協程框架 Hyperf ,並提供了微服務架構的相關組件。
Hyperf 是基於Swoole 4.3+
實現的高性能、高靈活性的 PHP 協程框架,內置協程服務器及大量經常使用的組件,性能較傳統基於PHP-FPM
的框架有質的提高,提供超高性能的同時,也保持着極其靈活的可擴展性,標準組件均基於 PSR 標準 實現,基於強大的依賴注入設計,保證了絕大部分組件或類都是可替換
與可複用
的。
因而,我在學習了微服務架構相關的基礎知識以後,使用 Hyperf 框架構建了一個基於 PHP 的微服務集羣,這是項目源碼地址:github.com/Jochen-z/p.…。該項目使用 Dokcer 搭建,docker-compose.yml
代碼以下:
version: "3"
services:
consul-server-leader:
image: consul:latest
container_name: consul-server-leader
command: "agent -server -bootstrap -ui -node=consul-server-leader -client=0.0.0.0"
environment:
- CONSUL_BIND_INTERFACE=eth0
ports:
- "8500:8500"
networks:
- microservice
microservice-1:
build:
context: .
container_name: "microservice-1"
command: "php bin/hyperf.php start"
depends_on:
- "consul-server-leader"
volumes:
- ./www/microservice-1:/var/www
networks:
- microservice
tty: true
microservice-2:
build:
context: .
container_name: "microservice-2"
command: "php bin/hyperf.php start"
depends_on:
- "consul-server-leader"
volumes:
- ./www/microservice-2:/var/www
networks:
- microservice
tty: true
app:
build:
context: .
container_name: "app"
command: "php bin/hyperf.php start"
depends_on:
- "microservice-1"
volumes:
- ./www/web:/var/www
ports:
- "9501:9501"
networks:
- microservice
tty: true
networks:
microservice:
driver: bridge
volumes:
microservice:
driver: local複製代碼
這裏啓動了一個 Consul 容器 consul-server-leader
做爲服務註冊和服務發現的組件,容器 microservice-1
和 microservice-2
分別提供了加法運算和除法運算的服務。容器 app
做爲服務調用方,配置了 consul-server-leader
容器的 URL,經過訪問 consul-server-leader
獲取 microservice-1
和 microservice-2
服務的 IP 地址和端口,而後 app
經過 RPC 協議調用加法運算和除法運算的服務獲取結果並返回給用戶。
app
容器爲 Web 應用,部署了一個 Hyperf 項目並對外提供 HTTP 服務。例如,在 App\Controller\IndexController
控制器裏有 add
方法:
public function add(AdditionService $addition)
{
$a = (int)$this->request->input('a', 1); # 接受前端用戶參數
$b = (int)$this->request->input('b', 2);
return [
'a' => $a,
'b' => $b,
'add' => $addition->add($a, $b) # RPC調用
];
}複製代碼
在 App\JsonRpc\AdditionService
中 add
的實現:
class AdditionService extends AbstractServiceClient
{
/**
* 定義對應服務提供者的服務名稱
* @var string
*/
protected $serviceName = 'AdditionService';
/**
* 定義對應服務提供者的服務協議
* @var string
*/
protected $protocol = 'jsonrpc-http';
public function add(int $a, int $b): int
{
return $this->__request(__FUNCTION__, compact('a', 'b'));
}
}複製代碼
繼承了 AbstractServiceClient
便可建立一個微服務客戶端請求類,Hyperf 在底層幫咱們實現了與 Consul 和服務提供者交互的細節,咱們只要 AdditionService
類裏的 add
方法便可遠程調用 microservice-1
和 microservice-2
提供的服務。
至此,PHP 微服務集羣搭建就完成了!
歡迎你們關注個人公衆號【java小瓜哥的分享平臺】,文章都會在裏面更新,整理的資料也會放在裏面