Hyperf框架:服务注册之consul组件
前言
-
在Hyperf里,目前仅支持Consul和Nacos为服务中心的组件。
-
同一个服务既可以是服务者也可以是消费者,为了简单清楚的演示,本文中使用docker 启动hyperf服务提供者服务、消费者服务、consul服务。
-
依赖的组件:
- hyperf/json-rpc
- hyperf/rpc
- hyperf/rpc-client
- hyperf/rpc-server
- hyperf/service-governance
- hyperf/service-governance-consul
服务提供者
启动服务提供者容器
docker run --name hyperf-provider -p 9501:9501 -v /work/hyperf:/opt/hyperf -itd hyperf/hyperf
安装的时候选择JSON-RPC
cd /opt
composer create-project hyperf/hyperf-skeleton hyperf
cd hyperf
composer require hyperf/service-governance
composer require hyperf/service-consul
定义服务提供者
进入到config/autoload/server.php。添加下面配置
[
'name' => 'jsonrpc-http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9504,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
Event::ON_REQUEST => [Hyperf\JsonRpc\HttpServer::class, 'onRequest'],
],
],
如下图所示:
定义服务接口类
创建接口类:App\JsonRpc\TestServiceInterface
interface TestServiceInterface
{
public function sum(int $a, int $b): int;
public function diff(int $a, int $b): int;
}
定义接口实现类
创建实现类: App\JsonRpc\TestService
/**
* @RpcService(name="CalculatorService", protocol="jsonrpc-http", server="jsonrpc-http", publishTo="consul")
* Class CalculatorService
* @package App\JsonRpc
*/
class CalculatorService implements CalculatorServiceInterface
{
public function sum(int $a, int $b): int
{
return $a + $b;
}
public function diff(int $a, int $b): int
{
return $a - $b;
}
}
@RpcService 共有 4 个参数:
-
name 属性为定义该服务的名称,这里定义一个全局唯一的名字即可,Hyperf 会根据该属性生成对应的 ID 注册到服务中心去;
-
protocol 属性为定义该服务暴露的协议,目前仅支持 jsonrpc 和 jsonrpc-http,分别对应于 TCP 协议和 HTTP 协议下的两种协议,默认值为 jsonrpc-http,这里的值对应在 Hyperf\Rpc\ProtocolManager 里面注册的协议的 key,这两个本质上都是 JSON RPC 协议,区别在于数据格式化、数据打包、数据传输器等不同。
-
server 属性为绑定该服务类发布所要承载的 Server,默认值为 jsonrpc-http,该属性对应 config/autoload/server.php 文件内 servers 下所对应的 name,这里也就意味着我们需要定义一个对应的 Server;
-
publishTo 属性为定义该服务所要发布的服务中心,目前仅支持 consul、nacos 或为空,为空时代表不发布该服务到服务中心去,但也就意味着您需要手动处理服务发现的问题,要使用此功能需安装 hyperf/service-governance 组件及对应的驱动依赖;
配置服务驱动
此地址为服务中心的地址,在启动服务时,Hyperf 会自动地将 @RpcService 定义了 publishTo 属性为 consul 的服务注册到服务中心去。
config/autoload/services.php
// 服务驱动相关配置
'drivers' => [
'consul' => [
'uri' => 'http://172.17.0.7:8500', //此地址为后面docker启动consul服务的容器ip地址
'token' => '',
'check' => [
'deregister_critical_service_after' => '90m',
'interval' => '1s',
],
],
]
消费者
启动消费者服务
docker run --name hyperf-customer -p 9500:9500 -v /work/hyperf-customer:/opt/hyperf -itd hyperf/hyperf
安装的时候选择JSON-RPC
cd /opt
composer create-project hyperf/hyperf-skeleton hyperf
cd hyperf
composer require hyperf/service-governance
composer require hyperf/service-consul
定义服务消费者
进入到config/autoload/server.php。添加下面配置
[
'name' => 'http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9500,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
Event::ON_REQUEST => [Hyperf\HttpServer::class, 'onRequest'],
],
],
如下图所示:
配置服务提供者地址
config/autoload/services.php
// 服务消费者相关配置
'consumers' => [
[
// The service name, this name should as same as with the name of service provider.
'name' => 'test',
'service' => \App\JsonRpc\TestInterface::class,
'protocol' => 'jsonrpc-http',
// The service registry, if `nodes` is missing below, then you should provide this configs.
'registry' => [
'protocol' => 'consul',
'address' => 'http://172.17.0.7:8500',
],
// If `registry` is missing, then you should provide the nodes configs.
'nodes' => [
// Provide the host and port of the service provider.
// ['host' => '172.17.0.7', 'port' => 9504]
],
],
],
定义和服务端相同的接口类
app/JsonRpc/TestServiceInterface.php
namespace App\JsonRpc;
interface TestInterface
{
public function sum(int $a, int $b): int;
public function diff(int $a, int $b): int;
}
在控制器中调用
通过注解注入的方式
/**
* @Inject
* @var TestInterface
*/
private $test;
/**
* @RequestMapping(path="index", methods="get")
*/
public function index()
{
$user = $this->request->input('user', 'Hyperf');
$method = $this->request->getMethod();
$diff = $this->test->diff(12, 3);
return [
'method' => $method,
'message' => "Hello {$user}.",
'diff' => $diff
];
}
通过容器调用
/**
* @RequestMapping(path="index", methods="get")
*/
public function index()
{
$user = $this->request->input('user', 'Hyperf');
$method = $this->request->getMethod();
$container = ApplicationContext::getContainer()->get(TestServiceInterface:class);
$diff = $container->diff(12, 3);
return [
'method' => $method,
'message' => "Hello {$user}.",
'diff' => $diff
];
}
安装、启动consul服务
docker pull consul
docker run --name consul -p 8500:8500 -itd consul
启动服务
启动服务提供者
cd opt/hyperf
php bin/hyperf.php start
如下图所示,服务会注册到consul中。
启动消费者服务
cd opt/hyperf
php bin/hyperf.php start
返回结果:
{
method: "GET",
message: "Hello Hyperf.",
diff: 9
}
共同学习,写下你的评论
评论加载中...
作者其他优质文章