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
QQ截图20220825160956.png

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

标签: none

添加新评论