在laravel中实现分布式horizon

关于horizon的基本操作这里不赘述,虽然有点复杂,但总体上看文档还是能跑起来的(https://learnku.com/docs/laravel/11.x/horizonmd/16721#configuration

这里简单说一下我的本地开发调试的方式,在vs中打开多个终端,一个终端运行php artisan serve,负责debug,一个终端运行php artisan schedule:work,负责启动计划任务,一个终端运行php artisan horizon,来运行监控面板。

放到服务器部署的话,我用的是dnmp方案,提供php+nginx或者php+caddy来运行站点。

另外在laravel项目中创建了一个docker-compose.yml:

services:

  redis:
    image: redis:7-alpine
    container_name: laravel_redis
    profiles: [independence]
    restart: unless-stopped
    volumes:
      - ./docker/data/redis:/data
    networks:
      - laravel-network
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5


  nginx:
    image: nginx:alpine
    container_name: laravel_nginx
    profiles: [independence]
    restart: unless-stopped
    ports:
      - "${HORIZON_PORT:-8000}:80"
    volumes:
      - .:/var/www
      - ./docker/nginx/conf.d:/etc/nginx/conf.d
      - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
    networks:
      - laravel-network
    depends_on:
      - php

  php:
    image: registry.cn-beijing.aliyuncs.com/futuremeng/php:8.4.11-fpm
    container_name: laravel_php
    profiles: [independence]
    working_dir: /var/www
    volumes:
      - .:/var/www
    networks:
      - laravel-network
    environment:
      - APP_ENV=production
      - QUEUE_CONNECTION=redis


  laravel_horizon:
    image: registry.cn-beijing.aliyuncs.com/futuremeng/php:8.4.11-fpm
    # build:
    #   context: .
    #   dockerfile: Dockerfile
    container_name: laravel_horizon
    working_dir: /var/www  # 设置工作目录
    command: php artisan horizon
    restart: unless-stopped
    volumes:
      - .:/var/www
    environment:
      - APP_ENV=production
      - QUEUE_CONNECTION=redis
    networks:
      - laravel-network


  laravel_scheduler:
    image: registry.cn-beijing.aliyuncs.com/futuremeng/php:8.4.11-fpm
    # build:
    #   context: .
    #   dockerfile: Dockerfile
    container_name: laravel_scheduler
    working_dir: /var/www  # 设置工作目录
    command: php artisan schedule:work
    restart: unless-stopped
    volumes:
      - .:/var/www
    environment:
      - APP_ENV=production
    depends_on:
      - laravel_horizon
    networks:
      - laravel-network

networks:
  laravel-network:
    driver: bridge
    # name: laravel-network
    ipam:
      driver: default
      # 解除下面的注释可以设置网段,用于nginx等容器固定容器IP
      config:
       - subnet: 10.10.0.0/24

在服务器1上用正常方式启动nginx+php+mysql+redis,在服务器2上用这个来运行队列任务,当执行:

docker compose up -d

时,.env中的mysql和redis都链接到服务器1的实例,然后在服务器1的IP:PORT/horizon中就可以看到了任务执行情况了,这个时候假定的是服务器1不执行job,而服务器2只负责执行job,当然,也可以合并到服务器1来运行,也可以启动服务器3来按服务器2一样的配置来运行。这里的关键点就是redis的配置要完全一样,比如使用同一个DB。

另外一种方式是:

docker compose --profile independence up -d

这时候在服务器2上会启动额外的redis,而服务器2的laravel中配置为连接服务器1的mysql来拉取任务,而队列管理放在服务器2自己的redis上。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理