一、简单来讲,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
那这里就把整个简单的微服务体系完成了,写得很差大佬们见谅哈~