一、簡單來講,RPC沒有那麼多HTTP的Request 和Response Body 字段,好比:content-type、user-agent、accept-language、content-encoding、expires等字段。每每這些字段就佔了報文的70%內容,若是請求次數過於頻繁,可想而知對於性能和網絡開銷有多大。php
二、而在內部服務器間相互通信,咱們徹底能夠減小握手次數linux
基於以上,微服務間使用HTTPv1.1的服務器間通信並非最好的方案,這就是爲何不少PHP框架基於PHP-FPM不適合作微服務的緣由,由於PHP-FPM每一個請求都會產生一個新的Woker進程,若是每一個Worker都跑去與微服務創建HTTP1.1鏈接,那其實沒有意義web
consul是什麼?爲何須要服務發現?看圖就知道了json
我在Server1部署了一套HTTP服務(服務消費者)對外提供接口,可是它同時也依賴Server2的服務(服務提供者),Server1不須要知道Server2的地址,只須要知道Consul這個服務者中心就好了,它會幫我註冊全部的服務api
這在現實中舉個例子就是,一個大公司的Team A在作HTTP業務核心功能,Team B作了不少服務輪子,那Team A總不能每次開發都跑去Team B問:「大家的地址是多少啊?端口是多少啊? 服務名叫什麼啊?告訴我好調用啊」。那若是要調用100個服務,豈不是Team A的人每次都要爲了配置IP和端口忙死?數組
一、下載consul for linux,解壓後就是一個可執行文件,直接mv到/usr/bin/consul瀏覽器
二、新建一個consul文件夾,在裏面新建一個data文件夾和etc文件夾,data文件夾用於存放consul的數據文件,etc用於存放配置文件服務器
三、切換到etc文件夾,新建一個web.json文件,內容以下:網絡
{ "service": { //這裏寫服務的ID,必須惟一 "id": "CalculatorService", //這裏寫服務名稱,通常也是ID名,非惟一 "name": "CalculatorService", //註冊服務,服務在哪臺服務器上,就填寫那臺服務器IP,這裏我填寫server2的ip,由於是server2提供服務給server1調用 "address": "server2.ip.server2.ip", //隨便寫 "tags": [ "webapi" ], //同上,服務也有端口,就填寫那臺服務器提供的端口,這裏填寫server2的端口 "port": 9502 } }
四、回到consul目錄,啓動consul,其中-config-dir指定剛剛的配置目錄,-data-dir指定存放數據的目錄app
consul agent -dev -ui -config-dir=./etc -data-dir=./data -client=0.0.0.0
client=0.0.0.0這裏須要注意下,網上通常的都是127.0.0.1,若是寫成127.0.0.1一樣能夠運行,可是沒辦法在外網訪問consul的UI界面,因此這裏改爲0.0.0.0
五、在瀏覽器輸入IP:8500,就能夠看到consul安裝成功
一、在app目錄下新建RPC文件夾,先新建一個CalculatorServiceInterface接口文件,文件名CalculatorServiceInterface.php
<?php namespace App\Rpc; interface CalculatorServiceInterface { public function add(int $a, int $b): int; }
二、基於這個Interface,在該目錄下添加一個實現方式的CalculatorService,文件名:CalculatorService.php
<?php namespace App\Rpc; use Hyperf\RpcServer\Annotation\RpcService; /** * 注意,如但願經過服務中心來管理服務,需在註解內增長 publishTo 屬性 * @RpcService(name="CalculatorService", protocol="jsonrpc-http", server="jsonrpc-http" ,publishTo="consul") */ class CalculatorService implements CalculatorServiceInterface { public function add(int $a, int $b) : int { return $a +$b; } }
在這裏使用了註解方式提供服務,name是服務名稱,protocol指定使用了jsonrpc-http協議,這裏加了publishTo選項,指定一個服務註冊中心,由於以前已經搭建好了consul
三、打開config/autoload/server.php,在servers數組下,添加一個數組:
[ 'name' => 'jsonrpc-http', 'type' => Server::SERVER_HTTP, 'host' => '0.0.0.0', 'port' => 9502, 'sock_type' => SWOOLE_SOCK_TCP, 'callbacks' => [ SwooleEvent::ON_REQUEST => [\Hyperf\JsonRpc\HttpServer::class, 'onRequest'], ], ],
這樣hyperf就會把代碼裏的服務,以9502端口發佈出去並運行,這裏的端口,其實就與上面的consul配置文件web.json文件對應起來,從而使到consul能發現9502這個服務
一、我這裏新建一個項目來表示消費者consumer服務模,一樣在app目錄下新建RPC文件夾,先新建一個CalculatorServiceInterface接口文件,文件名CalculatorServiceInterface.php
<?php namespace App\Rpc; interface CalculatorServiceInterface { public function add(int $a, int $b): int; }
二、打開app/Controllers/IndexController.php
<?php namespace App\Controller; use App\Rpc\CalculatorServiceInterface; use Hyperf\Di\Annotation\Inject; use Hyperf\HttpServer\Annotation\AutoController; /** * Class IndexController * @package App\Controller * @AutoController() */ class IndexController extends AbstractController { /** * //在這裏咱們注入了一個接口類,並直接調用接口的add方法,但在本項目並無add 方法的實現,真正的add方法在服務提供者裏已經實現了,hyperf會幫咱們找到相應服務並使用 * @Inject() * @var CalculatorServiceInterface */ private $calculatorService; public function index() { return $this->calculatorService->add(1,2); } }
二、在config/autoload下新建services.php
<?php return [ 'consumers' => [ [ // name 需與服務提供者的 name 屬性相同 'name' => 'CalculatorService', // 服務接口名,可選,默認值等於 name 配置的值,若是 name 直接定義爲接口類則可忽略此行配置,如 name 爲字符串則須要配置 service 對應到接口類 'service' => \App\Rpc\CalculatorServiceInterface::class, // 這個消費者要從哪一個服務中心獲取節點信息,如不配置則不會從服務中心獲取節點信息 'registry' => [ 'protocol' => 'consul', //這裏的address,表示consul搭建在那臺服務器上,就填寫哪臺服務器的IP 'address' => 'http://127.0.0.1:8500', ], ] ], ];
這樣當請求進來的時候,IndexController就會注入Service,hyperf就會告知這個service應該要去services.php去找到這個服務(也就是consul)
三、把config/autoload/server.php裏的port改爲9503,待會經過9503訪問index控制器,這裏只是演示,現實中你能夠隨意更改爲你想訪問的端口
'servers' => [ [ 'name' => 'http', 'type' => Server::SERVER_HTTP, 'host' => '0.0.0.0', 'port' => 9503, 'sock_type' => SWOOLE_SOCK_TCP, 'callbacks' => [ SwooleEvent::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'], ], ], ],
4、跑起來
一、從新啓動consul,若是以前啓動過,先kill -9 consul的PID
consul agent -dev -ui -config-dir=./etc -data-dir=./data -client=0.0.0.0
二、切換到Server2的hyperf-provider,啓動
php bin/hyperf.php start
三、切換到Server1的hyperf-consumer,啓動
php bin/hyperf.php start
四、在瀏覽器打開Server1的HTTP 8500端口,查看consul界面,能夠看到能夠找到Server2下的hyperf的provider
五、在瀏覽訪問一下Servier1的服務
能夠看到Server1下的9503服務是正常的,它會訪問Server1下的consul-8500中心,而後consul-8500中心會去訪問Server2下的9502服務,再交還給Server1的9503
那這裏就把整個簡單的微服務體系完成了,寫得很差大佬們見諒哈~