nginx+consul+swoft 集群高可用与服务注册、发现

整体架构图

nginx+consul+swoft 集群高可用与服务注册、发现_第1张图片

构建consul集群

服务端1主2从,客户端2台,共5台组成集群
nginx+consul+swoft 集群高可用与服务注册、发现_第2张图片

docker hub 搜索合适的consul版本,拉起镜像到本地
docker pull consul:1.10.4 # 拉取镜像
编写consul.yaml文件

# consul.yaml
version: "3.7" # 确定docker-composer文件的版本
services: # 代表就是一组服务 - 简单来说一组容器
  # server
  consul_master_server_173_10: # 这个表示服务的名称,课自定义; 注意不是容器名称
    image: consul:1.10.4 # 指定容器的镜像文件
    ports: # 配置容器与宿主机的端口
      - "8510:8500"
    networks: ## 引入外部预先定义的网段
      consul:
        ipv4_address: 173.22.1.10 #设置ip地址
    container_name: consul_master_server_173_10 # 这是容器的名称 -bootstrap-expect:3节点数  -node节点名称
    command: consul agent -server -bootstrap-expect 3 -data-dir /tmp/consul -node=consul_master_server_173_10 -bind=173.22.1.10 -ui -client=0.0.0.0

  consul_slaves_server_173_11: # 这个表示服务的名称,课自定义; 注意不是容器名称
    image: consul:1.10.4 # 指定容器的镜像文件
    ports: # 配置容器与宿主机的端口
      - "8511:8500"
    networks: ## 引入外部预先定义的网段
      consul:
        ipv4_address: 173.22.1.11 #设置ip地址
    container_name: consul_slaves_server_173_11 # 这是容器的名称
    command: consul agent -server -data-dir /tmp/consul -node=consul_slaves_server_173_11 -bind=173.22.1.11 -ui -client=0.0.0.0 -join 173.22.1.10
  consul_slaves_server_173_12: # 这个表示服务的名称,课自定义; 注意不是容器名称
    image: consul:1.10.4 # 指定容器的镜像文件
    ports: # 配置容器与宿主机的端口
      - "8512:8500"
    networks: ## 引入外部预先定义的网段
      consul:
        ipv4_address: 173.22.1.12 #设置ip地址
    container_name: consul_slaves_server_173_12 # 这是容器的名称
    command: consul agent -server -data-dir /tmp/consul -node=consul_slaves_server_173_12 -bind=173.22.1.12 -ui -client=0.0.0.0 -join 173.22.1.10

  # client
  consul_client_173_21: # 这个表示服务的名称,课自定义; 注意不是容器名称
    image: consul:1.10.4 # 指定容器的镜像文件
    ports: # 配置容器与宿主机的端口
      - "8521:8500"
    networks: ## 引入外部预先定义的网段
      consul:
        ipv4_address: 173.22.1.21 #设置ip地址
    container_name: consul_client_173_21 # 这是容器的名称
    command: consul agent -data-dir /tmp/consul -node=consul_client_173_21 -bind=173.22.1.21 -ui -client=0.0.0.0 -join 173.22.1.10
  consul_client_173_22: # 这个表示服务的名称,课自定义; 注意不是容器名称
    image: consul:1.10.4 # 指定容器的镜像文件
    ports: # 配置容器与宿主机的端口
      - "8522:8500"
    networks: ## 引入外部预先定义的网段
      consul:
        ipv4_address: 173.22.1.22 #设置ip地址
    container_name: consul_client_173_22 # 这是容器的名称
    command: consul agent -data-dir /tmp/consul -node=consul_client_173_22 -bind=173.22.1.22 -ui -client=0.0.0.0 -join 173.22.1.10
# 设置网络模块
networks:
  # 自定义网络
  consul:
    driver: bridge
    ipam: #定义网段
      config:
        - subnet: "173.22.1.0/24"

docker-compose -f consul.yaml up -d # 构建consul集群
docker-compose -f consul.yaml down # 停止并删除consul集群 nginx+consul+swoft 集群高可用与服务注册、发现_第3张图片
访问consul:http://127.0.0.1:8510/
nginx+consul+swoft 集群高可用与服务注册、发现_第4张图片
nginx+consul+swoft 集群高可用与服务注册、发现_第5张图片
nginx+consul+swoft 集群高可用与服务注册、发现_第6张图片

构建nginx容器

docker pull nginx:1.17
docker run -itd -v /www/biny/nginx:/nginx -p 80:80 --name nginx1.17 nginx1.17nginx+consul+swoft 集群高可用与服务注册、发现_第7张图片

构建2台swoft客户端服务容器

在这里插入图片描述

swoft镜像已提前构建好,swoft是一套swoole框架
编写swoft-client.yml

# 编排php,redis,nginx容器
version: "3.6" # 确定docker-composer文件的版本
services:
  # 代表就是一组服务 - 简单来说一组容器
  swoft_client_174_10:
    # 这个表示服务的名称,课自定义; 注意不是容器名称
    image: swoft # 指定容器的镜像文件
    container_name: swoft_client_174_10 # 这是容器的名称
    ports:
      - "18310:18306"
    networks:
      ## 引入外部预先定义的网段
      swoft:
        ipv4_address: 174.22.1.10 #设置ip地址
    volumes:
      # 配置数据挂载
      - /www/biny/client/swoft:/var/www/swoft
    working_dir: /var/www/swoft #工作目录
    command: php bin/swoft http:start

  swoft_client_174_11:
    # 这个表示服务的名称,课自定义; 注意不是容器名称
    image: swoft # 指定容器的镜像文件
    container_name: swoft_client_174_11 # 这是容器的名称
    ports:
      - "18311:18306"
    networks:
      ## 引入外部预先定义的网段
      swoft:
        ipv4_address: 174.22.1.11 #设置ip地址
    volumes:
      # 配置数据挂载
      - /www/biny/client/swoft:/var/www/swoft
    working_dir: /var/www/swoft #工作目录
    command: php bin/swoft http:start

# 设置网络模块
networks:
  # 自定义网络
  swoft:
    driver: bridge
    ipam:
      #定义网段
      config:
        - subnet: "174.22.1.0/24"

docker-compose -f swoft-client.yaml up -d # 构建consul集群
docker-compose -f swoft-client.yaml down # 停止并删除consul集群
分别访问http://127.0.0.1:18310/ 和 http://127.0.0.1:18310/

nginx+consul+swoft 集群高可用与服务注册、发现_第8张图片
nginx+consul+swoft 集群高可用与服务注册、发现_第9张图片

nginx+consul+swoft实现动态负载均匀

手动将swoft客户端服务容器注册到consul中
curl -X PUT -d ‘{“max_fails”:2,“fail_timeout”:10}’ http://127.0.0.1:8510/v1/kv/upstream/swoft_server/192.168.31.22:18310
curl -X PUT -d ‘{“max_fails”:2,“fail_timeout”:10}’ http://127.0.0.1:8510/v1/kv/upstream/swoft_server/192.168.31.22:18311
nginx+consul+swoft 集群高可用与服务注册、发现_第10张图片

修改nginx.conf

worker_processes  4;
worker_cpu_affinity auto;  #自动绑定cpu跟进程的关系
events {
    worker_connections  100000; #设置单个worker连接数
}
error_log /nginx/logs/error.log;

http {
    default_type  application/octet-stream;
    sendfile        on;
    upstream swoft_server {
        server 192.168.31.22:18310 max_fails=2 fail_timeout=30s;  
        upsync 192.168.31.22:8510/v1/kv/upstream/swoft_server upsync_timeout=1m upsync_interval=1m upsync_type=consul strong_dependency=on;
        upsync_dump_path /nginx/conf/swoft_server.conf;
        include /nginx/conf/swoft_server.conf;
    }
    server {
        listen       80;
        server_name  localhost;
        location / {
            proxy_pass http://swoft_server;
        }
    }
}

访问http://127.0.0.1/swoft_index/test,重复刷新页面,看到2个服务均得到反馈,负载成功。

nginx+consul+swoft 集群高可用与服务注册、发现_第11张图片nginx+consul+swoft 集群高可用与服务注册、发现_第12张图片

swoft自动注册与销毁consul

启动swoft服务时,自动执行监听注册事件,完成consul注册与提交健康检查监听

#swoft/app/bean.php
#部分代码
return [
	#....
    'consul' => [
        // consul ip地址
        'host' => '192.168.31.22',
        'port' => 8510
    ]
];
#swoft/app/Listener/RegisterServiceListener.php
public function handle(EventInterface $event): void
    {
        $rpcServer = $event->getTarget();

        $service = [
            'ID'                => getConsulServerId($this->serverName),
            'Name'              => $this->serverName,
            'Tags'              => [
                'rpc'
            ],
            'Address'           => env("HOST"),
            'Port'              => $rpcServer->getPort(),
            'Meta'              => [
                'version' => '1.0'
            ],
            'EnableTagOverride' => false,
            'Weights'           => [
                'Passing' => 10,
                'Warning' => 1
            ],
            // 上面部分是像consul提交服务注册
            // 下面部分是提交健康检查,都可以修改成env配置参数
            "Check" => [
                "name"     => "swoft.goods.server",
                // 192.168.31.22 这是 swoft 的服务宿主机地址
                "tcp"      => "192.168.31.22:".env("CONSUL_CHECK_PORT"), //服务器ip地址
                "interval" => '10s', //检查时间间隔
                "timeout"  => '2s'  //检查超时时间
            ],
        ];
        $this->agent->registerService($service);
    }

swoft客户端与rpc服务通信

http客户端代码:

#swoft/app/bean.php
	// 部分代码
    // ------- goods server -------
    'goods'               => [
        'class'   => ServiceClient::class,
        'host'    => '127.0.0.1',
        'port'    => 18307,
        'setting' => [
            'timeout'         => 0.5,
            'connect_timeout' => 1.0,
            'write_timeout'   => 10.0,
            'read_timeout'    => 0.5,
        ],
        'packet'  => bean('rpcClientPacket'),
        'provider' => bean(RpcProvider::class)
    ],
    'goods.pool'          => [
        'class'  => ServicePool::class,
        'client' => bean('goods'),
    ],

#swoft/app/Http/Controller/GoodsController.php
/**
 * Class GoodsController
 *
 * @since 2.0
 *
 * @Controller(prefix="/goods")
 */
class GoodsController
{
    /**
     * @Reference(pool="goods.pool")
     *
     * @var GoodsInterface
     */
    private $goodsService;


    /**
     * @RequestMapping("getList")
     *
     * @return array
     */
    public function getList(): array
    {
        $result  = $this->goodsService->getList(12, 'type');


        return [$result];
    }
}

rpc服务端代码

#swoft/app/Rpc/Service/GoodsService.php
/**
 * Class GoodsService
 *
 * @since 2.0
 *
 * @Service()
 */
class GoodsService implements GoodsInterface
{
    /**
     * @param int   $id
     * @param mixed $type
     * @param int   $count
     *
     * @return array
     */
    public function getList(int $id, $type, int $count = 10): array
    {
        return ['desc' => ['rpc服务端返回数据']];
    }


}

你可能感兴趣的:(php,docker,nginx,consul,docker,php)