Swoft与Consul(二) - 商品服务注册与注销
理解swoft框架的服务注册与发现
微服务治理过程中,经常会涉及注册启动的服务到第三方集群,比如 consul / etcd 等等,
本章以 Swoft 框架中使用 swoft-consul 组件,实现服务注册与发现为例。
在官方的手册中有描述关于服务注册与发现的案例:
https://www.swoft.org/documents/v2/microservice/register-find/
swoft服务注册
无论是 http / rpc / ws 服务,启动时只监听 SwooleEvent::START 事件,即可把启动的服务注册到第三方集群。
swoft配置consul连接
/mnt/hgfs/goods/app/server/swoft/app/bean.php
<?php
return [
// ...
'consul' => [
'host' => '192.168.3.98',
'port' => '8550'
]
];
?>
注意这里我们选择的是部署在服务器192.168.3.98上的docker consul的client,对应端口8550,
参照 Consul理解与使用(一) - 高可用集群架构
swoft配置服务注册
/mnt/hgfs/goods/app/server/swoft/app/Listener/RegisterServiceListener.php
<?php
namespace App\Listener;
use Swoft\Consul\Agent;
use Swoft\Event\EventHandlerInterface;
use Swoft\Event\EventInterface;
use Swoft\Server\SwooleEvent;
/**
* Class RegisterServiceListener
*
* @since 2.0
*
* @Listener(event=SwooleEvent::START)
*/
class RegisterServiceListener implements EventHandlerInterface
{
/**
* @Inject()
*
* @var Agent
*/
private $agent;
// private agent agent;
/**
* @param EventInterface $event
*/
public function handle(EventInterface $event): void
{
$httpServer = $event->getTarget();
$service = [
'ID' => 'swoft_goods_server_172_110',
'Name' => 'swoft_goods_server',
'Tags' => [
'http'
],
'Address' => '192.168.3.66',
'Port' => $httpServer->getPort(),
'Meta' => [
'version' => '1.0'
],
'EnableTagOverride' => false,
'Weights' => [
'Passing' => 10,
'Warning' => 1
]
];
// Register
$this->agent->registerService($service);
echo 'Swoft http register service success by consul!'."\n";
// CLog::info('Swoft http register service success by consul!');
}
}
?>
定义swoft商品服务
在服务器192.168.3.66上部署docker swoft商品服务容器
docker-compose.yml:
# 定义容器
version: "3.3" # 确定docker-composer文件的版本
services: # 代表就是一组服务 - 简单来说一组容器
swoft_goods_server_172_110: # 这个表示服务的名称,可自定义; 注意不是容器名称
image: swoft # 指定容器的镜像文件
container_name: swoft_goods_server_172_110 # 这是容器的名称
networks: ## 引入外部预先定义的网段
app_swoft:
ipv4_address: 172.200.7.110 #设置ip地址
privileged: true # 执行特殊权限的命令
volumes: # 配置数据挂载
- /mnt/share/goods/app/server/swoft:/var/www/swoft
working_dir: /var/www/swoft #工作目录
#command: php bin/swoft http:start
# 设置网络模块
networks:
# 自定义网络
app_swoft:
driver: bridge
ipam: #定义网段
config:
- subnet: "172.200.7.0/24"
运行 docker-compose up -d,然后进入容器执行命令:
docker exec -it swoft_goods_server_172_110 sh
php bin/swoft http:start
浏览器查看http://192.168.3.98:8550/ui/dc1/services
swoft服务注销
/mnt/hgfs/goods/app/server/swoft/app/Listener/DeregisterServiceListener.php
/**
* Class DeregisterServiceListener
*
* @since 2.0
*
* @Listener(SwooleEvent::SHUTDOWN)
*/
class DeregisterServiceListener implements EventHandlerInterface
{
/**
* @Inject()
*
* @var Agent
*/
private $agent;
/**
* @param EventInterface $event
*/
public function handle(EventInterface $event): void
{
$httpServer = $event->getTarget();
$this->agent->deregisterService('swoft_goods_server_172_110');
echo 'Swoft http register service deregisterService'."\n";
}
}
在swoft容器内执行命令:php bin/swoft http:stop,再刷新浏览器,可以看到swoft_goods_server没有了。
swoft-consul服务注册注销实现思路
利用在对象上增加的 @Listener(SwooleEvent::START)监听,
通过 Swoft\Consul\Agent 调用对应接口实现服务在Consul上的注册,
@Listener(SwooleEvent::SHUTDOWN) 注销服务;
分析这个之后,我们在其他的框架程序中可以自己编写服务注册注销功能,
只需要封装对应的接口,比如可以使用curl请求调用'/v1/agent/service/register'注册服务;
回顾swoole声明周期:
通过new 创建服务
-》进入start事件初始化
-》manager Start
-》worker/task Start
-》监听事件(request,message,receive)等
-》worker/task Stop
-》manager Stop
-》结束swoole进程 Shutdown
swoft的事件监听就是在这些节点增加的事件监听方法;通过 SHUTDOWN确定执行节点;
关于方法的封装主要是在 app\server\swoft\vendor\swoft\consul\src\Consul.php 与 app\server\swoft\vendor\swoft\consul\src\Agent.php
其中注释:@Bean() 当一个对象中标有这个注解代表在启动的时候会注册到容器中,
然后使用的时候我们无需手动的new 只需要在属性上运用@Inject()注解可以创建实例;
注意:@Inject()注解是需要配合@var一起运用否则报错;
在 app\server\swoft\vendor\swoft\consul\src\Consul.php 发送数据实际底层是运用了协程客户端处理
swoft代码同步热加载,生产环境不要使用
php swoftcli.phar run -c http:start