Hyperf框架 - 基于Json-Rpc与Consul的微服务搭建
依赖的组件hyperf/json-rpchyperf/rpc-clienthyperf/rpc-serverhyperf/service-governancehyperf/consul以 HTTP协议 为例json-rpc 即为基于json的rpc调用,原理就是 A 和 B 拥有同一套 interface I 的定义,A 就像调用自己的方法一样调用B的方法F,当然F必须是 insterface I
依赖的组件
hyperf/json-rpc
hyperf/rpc-client
hyperf/rpc-server
hyperf/service-governance
hyperf/consul
以 HTTP协议 为例
json-rpc 即为基于json的rpc调用,原理就是 A 和 B 拥有同一套 interface I 的定义,A 就像调用自己的方法一样调用B的方法F,当然F必须是 insterface I 中的方法。
保存镜像
docker commit -p hyperf raoxiaoya/hyperf:v1
一、服务端
1.1、启动服务提供者容器
docker run --name hyperf-db -p 9503:9503 --network host -v /data/www/hyperf-db:/hyperf-db -it --entrypoint /bin/sh raoxiaoya/hyperf:v1
cd /
composer create-project hyperf/hyperf-skeleton hyperf-db
安装的时候选择 JSON-RPC
cd /hyperf-db
composer require hyperf/consul
服务治理组件,不然 publishTo 不会生效
composer require hyperf/service-governance
发布consul组件的配置到app
php bin/hyperf.php vendor:publish hyperf/consul
1.2、定义服务提供者
config/autoload/server.php
'servers' => [
[
'name' => 'jsonrpc-http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9503,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
SwooleEvent::ON_REQUEST => [\Hyperf\JsonRpc\HttpServer::class, 'onRequest'],
],
],
],
1.3、定义接口
app/JsonRpc/CalculatorServiceInterface.php
<?php
namespace App\JsonRpc;
interface CalculatorServiceInterface
{
public function add(int $a, int $b): int;
}
1.4、定义实现类
app/JsonRpc/CalculatorService.php
<?php
namespace App\JsonRpc;
use Hyperf\RpcServer\Annotation\RpcService;
/**
* @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;
}
}
1.5、发布到服务中心
此地址为服务中心的地址,在启动服务时,Hyperf 会自动地将 @RpcService 定义了 publishTo 属性为 consul 的服务注册到服务中心去。
config/autoload/consul.php
return [
'uri' => 'http://127.0.0.1:8500',
];
二、客户端
2.1、启动服务消费者容器
docker run --name hyperf-api -p 9502:9502 --network host -v /data/www/hyperf-api:/hyperf-api -it --entrypoint /bin/sh raoxiaoya/hyperf:v1
cd /
composer create-project hyperf/hyperf-skeleton hyperf-api
安装的时候选择 JSON-RPC
cd /hyperf-api
composer require hyperf/consul
2.2、定义服务消费者
config/autoload/server.php
'servers' => [
[
'name' => 'http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9502,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
SwooleEvent::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'],
],
],
],
2.3、设置服务提供方地址,注册中心的地址
config/autoload/services.php
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://doc.hyperf.io
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
return [
'consumers' => [
[
// name 需与服务提供者的 name 属性相同
'name' => 'CalculatorService',
// 服务接口名,可选,默认值等于 name 配置的值,如果 name 直接定义为接口类则可忽略此行配置,如 name 为字符串则需要配置 service 对应到接口类
'service' => \App\JsonRpc\CalculatorServiceInterface::class,
// 对应容器对象 ID,可选,默认值等于 service 配置的值,用来定义依赖注入的 key
'id' => \App\JsonRpc\CalculatorServiceInterface::class,
// 服务提供者的服务协议,可选,默认值为 jsonrpc-http
// 可选 jsonrpc-http jsonrpc jsonrpc-tcp-length-check
'protocol' => 'jsonrpc-http',
// 负载均衡算法,可选,默认值为 random
'load_balancer' => 'random',
// 这个消费者要从哪个服务中心获取节点信息,如不配置则不会从服务中心获取节点信息
'registry' => [
'protocol' => 'consul',
'address' => 'http://127.0.0.1:8500',
],
// 如果没有指定上面的 registry 配置,即为直接对指定的节点进行消费,通过下面的 nodes 参数来配置服务提供者的节点信息
'nodes' => [
['host' => '127.0.0.1', 'port' => 9503],
],
// 配置项,会影响到 Packer 和 Transporter
'options' => [
'connect_timeout' => 5.0,
'recv_timeout' => 5.0,
'settings' => [
// 根据协议不同,区分配置
'open_eof_split' => true,
'package_eof' => "\r\n",
// 'open_length_check' => true,
// 'package_length_type' => 'N',
// 'package_length_offset' => 0,
// 'package_body_offset' => 4,
],
// 当使用 JsonRpcPoolTransporter 时会用到以下配置
'pool' => [
'min_connections' => 1,
'max_connections' => 32,
'connect_timeout' => 10.0,
'wait_timeout' => 3.0,
'heartbeat' => -1,
'max_idle_time' => 60.0,
],
],
],
],
];
2.4、定义接口,同服务端保持一致
app/JsonRpc/CalculatorServiceInterface.php
<?php
namespace App\JsonRpc;
interface CalculatorServiceInterface
{
public function add(int $a, int $b): int;
}
指的注意的是,app/JsonRpc/CalculatorServiceInterface 接口应该发布到composer包,被多个服务所依赖。
2.5、定义路由
Router::addRoute(['GET'], '/testRpc', 'App\Controller\IndexController@testRpc');
2.7、控制器中调用
public function testRpc()
{
$client = ApplicationContext::getContainer()->get(CalculatorServiceInterface::class);
$res = $client->add(1, 2);
return [
'result' => $res,
];
}
三、安装consul服务
然而文档中并没有说明如何安装 Consul 服务,以下对 Consul 做一个简单的安装。
docker pull consul
docker run --name=consul -p 8500:8500 -e CONSUL_BIND_INTERFACE=eth0 -d consul
访问页面
http://192.168.2.200:8500/
四、启动服务器
进入hyperf-db容器启动服务提供者
cd /hyperf-db
php bin/hyperf.php start
发现consul页面已经出来了一个services
进入hyperf-api容器启动服务消费者
cd /hyperf-api
php bin/hyperf.php start
访问接口
http://192.168.2.200:9502/testRpc
返回信息
{
"result": 3
}
说明我们的服务已经搭建成功了。
优化的点
1、关于接口的管理
上面的示例中接口文件 app/JsonRpc/CalculatorServiceInterface.php 我是手动创建的,在实际应用中,或有很多个接口文件,且被不同的人管理,那么在这rpc架构中,这些接口又被多个服务所依赖,一旦接口被改动,都需要同步到其他依赖的服务,这是一件很抓狂的事情,所以我们应该将所有的接口整合到一个composer包,然后其他服务直接引入这个包,如果接口有改动,其他服务重新拉取即可。
创建composer包:https://blog.csdn.net/raoxiaoya/article/details/107759887
在 client 和 server 中都执行 composer require phprao/composer-test=v1.0.1 下载接口。然后删掉原先的接口文件
app/JsonRpc/CalculatorServiceInterface.php 然后把引用的 namespace 改一下就可以使用了。
更多推荐
所有评论(0)