# laravel-queue **Repository Path**: grow-project/laravel-queue ## Basic Information - **Project Name**: laravel-queue - **Description**: laravel队列 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-09 - **Last Updated**: 2026-07-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Laravel Queue Lab Laravel 12 队列学习项目,覆盖 Redis 队列、Database 队列对照、重试、失败、手动恢复、超时、backoff、chain、batch、unique job、rate limit、隔离队列、Horizon,以及多种 `supervisorctl` 运维练习。 这个项目的学习方式是:用 CLI 触发队列场景,用 `/queue-lab`、Horizon、Supervisor 日志、Laravel 队列命令和 MySQL 表观察结果。 ## 你会用到的入口 | 入口 | 地址 / 命令 | 用途 | | --- | --- | --- | | 练习台 | http://localhost:8080/queue-lab | 查看场景列表、最近练习、最近事件、失败任务数量和 Database 队列数量。 | | Horizon | http://localhost:8080/horizon | 观察 Redis 队列、pending jobs、recent jobs、failed jobs 和 worker 状态。默认没有启动,需要用 Supervisor 启动。 | | Artisan 命令 | `docker compose exec app php artisan ...` | 触发场景、查看失败任务、清理数据、检查环境。 | | Supervisor | `docker compose exec supervisor supervisorctl ...` | 管理传统 `queue:work` worker 和 Horizon 进程。 | | MySQL | `localhost:33066` | 查看 `queue_exercises`、`queue_events`、`jobs`、`failed_jobs`、`job_batches` 等表。 | | Redis | `localhost:63790` | Redis 队列、缓存锁、rate limiter 和 Horizon 的底层存储。 | ## 快速启动 下面是 Docker 主路径。宿主机直接运行 PHP/MySQL/Redis 的方式见 [docs/local-run.md](docs/local-run.md)。 ```bash cp .env.example .env docker compose run --rm app composer install docker compose run --rm app php artisan key:generate docker compose up -d --build docker compose ps docker compose exec app php artisan queue-lab:ensure-database docker compose exec app php artisan migrate:fresh docker compose exec app php artisan queue-lab:doctor ``` 每条命令的作用: | 命令 | 作用 | 怎么确认有效 | | --- | --- | --- | | `cp .env.example .env` | 创建 Laravel 运行配置。Docker 中的 `DB_HOST=mysql`、`REDIS_HOST=redis` 都来自这个文件。 | 执行 `ls -la .env`,文件存在即可。 | | `docker compose run --rm app composer install` | 启动一次性 `app` 容器安装 PHP 依赖。`--rm` 表示命令结束后删除这个临时容器。 | 项目根目录出现 `vendor/`;后续 `php artisan` 能执行。 | | `docker compose run --rm app php artisan key:generate` | 写入 `APP_KEY`,让 Laravel 加密、session 等功能可用。 | `.env` 中的 `APP_KEY=` 不再为空。 | | `docker compose up -d --build` | 构建 PHP 镜像并后台启动 `app`、`nginx`、`supervisor`、`mysql`、`redis`。 | `docker compose ps` 看到服务在运行;浏览器可打开 `http://localhost:8080`。 | | `docker compose ps` | 查看容器状态、端口映射和健康状态。 | `mysql` 应为 healthy,`nginx` 映射到 `0.0.0.0:8080->80/tcp`。 | | `docker compose exec app php artisan queue-lab:ensure-database` | 在迁移前创建 `DB_DATABASE` 配置的 MySQL 库,并确保 `DB_USERNAME` 用户有权限。 | 输出 `Database [laravel_queue_lab] is ready.`;即使库之前不存在,后续迁移也能连接。 | | `docker compose exec app php artisan migrate:fresh` | 删除并重建数据库表,包括 Laravel 队列表、失败任务表、批次表和练习表。会清空已有数据。 | 命令成功结束;打开 `/queue-lab` 不报表不存在。 | | `docker compose exec app php artisan queue-lab:doctor` | 检查场景数量、默认队列、Horizon 路径、数据库连接、Redis 连接和队列表。 | 看到 `Database: ok`、`Redis: ok`、`Queue tables: ok`。 | 注意:Docker 主路径下,所有 `php artisan ...` 都建议通过 `docker compose exec app php artisan ...` 执行。`.env` 里的 `DB_HOST=mysql`、`REDIS_HOST=redis` 只在 Docker 网络内可用;如果在宿主机直接运行 `php artisan queue-lab:dispatch delayed`,可能会看到 `SQLSTATE[HY000] [2006] MySQL server has gone away (Host: mysql, Port: 3306)`。 ## 第一个场景:成功任务 ```bash docker compose exec app php artisan queue-lab:list docker compose exec app php artisan queue-lab:dispatch success docker compose exec supervisor supervisorctl status docker compose exec supervisor supervisorctl tail queue-default ``` 观察步骤: 1. 打开 http://localhost:8080/queue-lab。 2. 执行 `queue-lab:list`,确认 `success` 场景存在。表格里的 `Key` 就是后续 dispatch 使用的参数。 3. 执行 `queue-lab:dispatch success`。它会创建一条 `queue_exercises` 练习记录,并把 `RecordSuccessJob` 投递到 Redis 的 `default` 队列。 4. 刷新 `/queue-lab`。最近练习中会出现 `success`,状态会从 `已派发` 变成 `运行中` 或 `已成功`。 5. 最近事件中会出现 `开始`、`成功`。如果页面没有变化,执行 `supervisorctl status` 看 `queue-default` 是否在运行。 6. 执行 `supervisorctl tail queue-default` 查看 default worker 的 stdout 日志。 7. 也可以执行 `docker compose exec app php artisan queue-lab:watch --once`,在命令行直接打印当前队列、练习和事件快照。 ## 实时观察队列执行 `/queue-lab` 页面会通过浏览器原生 `EventSource` 连接 `/queue-lab/events`,服务端会持续推送队列快照。你不需要手动刷新页面,就能看到: - `queued`:场景已经派发到哪个 connection / queue。 - `job-processing`:worker 已经取出任务,包含 job class、job id、attempt。 - `started` / `succeeded` / `failed`:job 内部记录的业务生命周期。 - `job-exception`:某次执行抛出异常,通常用于观察 retry/backoff。 - `job-processed`:worker 完成这次任务。 - `job-failed`:任务进入 Laravel 终态失败。 - Redis 队列的 pending / delayed / reserved 数量,以及 Database queue / failed_jobs 数量。 本地运行时推荐开三个终端: ```bash php artisan serve php artisan queue:work redis --queue=high,default,low,api,slow,dead-letter --sleep=1 --tries=3 --timeout=10 php artisan queue-lab:dispatch retry-then-succeed ``` 然后打开 http://127.0.0.1:8000/queue-lab,观察“实时队列执行”和“队列状态”区域。 如果你更想在命令行里观察,可以开一个单独终端持续刷新: ```bash php artisan queue-lab:watch ``` 它会打印三块内容: - `队列状态`:Redis `high/default/low/api/slow/dead-letter` 的 pending、delayed、reserved 数量,以及 Database queue 和 `failed_jobs` 数量。 - `最近练习`:最近派发的 exercise id、场景 key、中文标题、状态、connection / queue、attempt、开始时间和结束时间。 - `最近事件`:worker 取出任务、job 内部开始/成功/失败、异常、终态失败等事件;消息里会带 job class、job id、exception 等细节。 常用参数: ```bash php artisan queue-lab:watch --once php artisan queue-lab:watch --interval=2 php artisan queue-lab:watch --events=20 --exercises=10 php artisan queue-lab:watch --no-clear ``` | 参数 | 作用 | 适合场景 | | --- | --- | --- | | `--once` | 只打印一次快照后退出。 | 快速确认当前状态,或复制输出排查问题。 | | `--interval=2` | 持续观察时每 2 秒刷新一次,默认 1 秒。 | 队列量比较大,不想刷新太快。 | | `--events=20` | 最近事件显示 20 条,默认 12 条。 | 观察重试、backoff、batch、chain 等多事件场景。 | | `--exercises=10` | 最近练习显示 10 条,默认 8 条。 | 一次性 dispatch 多个场景后对照查看。 | | `--no-clear` | 不清屏,持续追加每次快照。 | 想保留历史输出,或者把结果重定向到日志。 | ## `queue-lab:*` 命令 | 命令 | 具体功能 | 主要效果 | 如何查看效果 | | --- | --- | --- | --- | | `docker compose exec app php artisan queue-lab:list` | 列出所有学习场景。 | 输出 `Key`、分类、队列连接、队列名、中文标题。 | 用 `Key` 选择下一条 `queue-lab:dispatch `;也可在 `/queue-lab` 的“练习场景”区域核对。 | | `docker compose exec app php artisan queue-lab:dispatch success` | 按 key 触发单个场景。这里的 `success` 可替换成任意场景 key。 | 创建一条 `queue_exercises`,按场景配置投递一个或多个 job。命令会输出 exercise id、`/queue-lab`、`/horizon`、`queue:failed` 提示。 | `/queue-lab` 看最近练习和事件;Supervisor tail 看 worker 日志;失败类场景用 `queue:failed` 看失败任务。 | | `docker compose exec app php artisan queue-lab:dispatch-all` | 一次性触发全部 14 个场景。 | 会创建多条练习记录,并故意制造失败、重试、延迟、限流、批次等现象。 | `/queue-lab` 会出现大量练习和事件;Horizon 可看 Redis 队列;`queue:failed` 会看到故意失败的任务。练习后建议执行清理命令。 | | `docker compose exec app php artisan queue-lab:watch` | 在命令行持续打印队列实验快照。 | 每秒刷新队列状态、最近练习和最近事件;事件消息包含 job class、job id、attempt、异常等细节。 | 开着这个命令后,在另一个终端执行 `queue-lab:dispatch ` 或 `queue:work`,观察 pending 数、状态和事件变化。 | | `docker compose exec app php artisan queue-lab:ensure-database` | 在 Laravel 迁移前创建目标 MySQL 库。 | 使用 `DB_ADMIN_USERNAME` / `DB_ADMIN_PASSWORD` 连接 MySQL server,执行 `CREATE DATABASE IF NOT EXISTS`,并给 `DB_USERNAME` 授权。 | 看到 `Database [laravel_queue_lab] is ready.` 后再执行 `migrate:fresh`。 | | `docker compose exec app php artisan queue-lab:doctor` | 做运行环境体检。 | 检查数据库、Redis、`jobs` / `failed_jobs` / `job_batches` 表,输出默认队列和 Horizon 路径。 | 所有检查应显示 `ok`。失败时先看 [docs/troubleshooting.md](docs/troubleshooting.md)。 | | `docker compose exec app php artisan queue-lab:reset --force` | 清理本项目的练习数据。 | 删除 `queue_events`、`queue_exercises`、`failed_jobs`、`job_batches`、`jobs` 表数据。不会自动清空 Redis pending 队列。 | 刷新 `/queue-lab`,最近练习和最近事件为空;如 Redis 中还有 pending job,再用 `queue:clear redis --queue=`。 | ## Laravel 队列命令 | 命令 | 具体功能 | 什么时候用 | 如何查看效果 | | --- | --- | --- | --- | | `docker compose exec app php artisan queue:failed` | 列出 Laravel 记录到 `failed_jobs` 的失败任务。 | 跑 `permanent-failure`、`manual-retry`、`dead-letter` 等失败场景后。 | 终端会显示失败任务 UUID;`/queue-lab` 的失败任务数量会增加。 | | `docker compose exec app php artisan queue:retry ` | 把指定 UUID 的失败任务重新投递回原队列。 | 手动恢复某个失败任务。 | `queue:failed` 中该任务可能消失或生成新的失败记录;`/queue-lab` 事件会继续增加。若代码仍故意失败,重试后还会再次失败。 | | `docker compose exec app php artisan queue:retry all` | 重试所有失败任务。 | 批量恢复失败任务。 | `queue:failed` 数量变化;失败场景可能再次进入失败状态。 | | `docker compose exec app php artisan queue:forget ` | 从 `failed_jobs` 删除某个失败任务,不重试。 | 确认某个失败任务不需要恢复时。 | 再执行 `queue:failed`,该 UUID 不再出现。 | | `docker compose exec app php artisan queue:flush` | 清空所有 `failed_jobs`。 | 失败任务太多,想重置失败列表时。 | `queue:failed` 为空;`/queue-lab` 的失败任务数量归零。 | | `docker compose exec app php artisan queue:clear redis --queue=default` | 清空 Redis 某个 queue 中尚未消费的 pending jobs。 | 派发太多 Redis 任务,想清掉某个队列。 | Horizon pending 数减少;Redis 队列长度下降。只影响 pending job,不删除 `failed_jobs` 和练习记录。 | | `docker compose exec app php artisan horizon:status` | 查看 Horizon master 是否运行。 | 切换 Horizon 和传统 worker 时。 | 输出 `Horizon is running` 或 `Horizon is inactive`。 | 常用 Redis 队列名包括 `default`、`high`、`low`、`api`、`slow`、`dead-letter`。例如清空限流场景的 pending jobs: ```bash docker compose exec app php artisan queue:clear redis --queue=api ``` ## Supervisor 命令 Supervisor 在 `supervisor` 容器中管理队列 worker。默认启动传统 worker,不默认启动 Horizon。 | Program | 默认状态 | 处理的队列 | 用途 | | --- | --- | --- | --- | | `queue-default` | 启动 | Redis `default` | 普通 Redis 队列 worker。 | | `queue-priority:*` | 启动 | Redis `high,default,low` | 两个进程,演示优先级队列。 | | `queue-database` | 启动 | Database `database-lab` | 消费 Laravel Database queue。 | | `queue-dead-letter` | 停止 | Redis `dead-letter` | 练习隔离队列,手动启动。 | | `horizon` | 停止 | Redis `high,default,low,api,slow,dead-letter` | 用 Horizon 管理和观察 Redis 队列。 | | `crashy-worker` | 停止 | 无 | 故意退出,用于练习 Supervisor autorestart。 | | 命令 | 具体功能 | 如何查看效果 | | --- | --- | --- | | `docker compose exec supervisor supervisorctl status` | 查看所有 program 的运行状态。 | 看到 `RUNNING`、`STOPPED`、`BACKOFF`、`FATAL` 等状态。 | | `docker compose exec supervisor supervisorctl status queue-default` | 只查看 `queue-default`。 | 确认 default worker 是否正在消费。 | | `docker compose exec supervisor supervisorctl stop queue-default` | 停止 default worker。 | `status queue-default` 变为 `STOPPED`;派发到 `default` 的任务会积压。 | | `docker compose exec supervisor supervisorctl start queue-default` | 启动 default worker。 | 积压的 `default` 任务开始被消费,`/queue-lab` 事件增长。 | | `docker compose exec supervisor supervisorctl restart queue-default` | 重启 default worker。 | 修改 worker 参数后常用;日志中会出现新的 worker 启动记录。 | | `docker compose exec supervisor supervisorctl tail queue-default` | 查看 default worker 最新 stdout 日志。 | 能看到 worker 启动、任务处理输出。 | | `docker compose exec supervisor supervisorctl tail -f queue-default` | 持续跟随日志。 | 适合先开着日志,再在另一个终端 dispatch 场景。按 `Ctrl+C` 只退出 tail,不会停止 worker。 | | `docker compose exec supervisor supervisorctl tail queue-priority:queue-priority_00` | 查看第一个 priority worker 日志。 | priority 有多个进程,使用 `program:process` 形式查看具体进程日志。 | | `docker compose exec supervisor supervisorctl start queue-dead-letter` | 启动 dead-letter 隔离队列 worker。 | `dead-letter` 场景开始被消费并故意失败。 | | `docker compose exec supervisor supervisorctl start horizon` | 启动 Horizon master。 | `horizon:status` 显示 running;浏览器打开 `/horizon` 可看到 worker。 | | `docker compose exec supervisor supervisorctl reread` | 让 Supervisor 重新读取配置文件变更。 | 修改 `docker/supervisor/programs/*.conf` 后使用;会提示 changed/new program。 | | `docker compose exec supervisor supervisorctl update` | 应用 `reread` 发现的 program 配置变化。 | 新增或变更的 program 生效。若只改 command 参数,通常还要 restart。 | | `docker compose exec supervisor supervisorctl signal TERM queue-default` | 向 worker 发送 TERM 信号,练习优雅停止。 | `status` 和日志中能看到进程退出与重启行为。 | ## Horizon 观察模式 如果你想用 Horizon 观察 Redis 队列,建议先停掉传统 Redis worker,避免同一个队列被两套 worker 抢着消费。 ```bash docker compose exec supervisor supervisorctl stop queue-default docker compose exec supervisor supervisorctl stop queue-priority:* docker compose exec supervisor supervisorctl start horizon docker compose exec app php artisan horizon:status ``` 然后打开 http://localhost:8080/horizon,再触发场景: ```bash docker compose exec app php artisan queue-lab:dispatch success docker compose exec app php artisan queue-lab:dispatch retry-then-succeed docker compose exec app php artisan queue-lab:dispatch rate-limited docker compose exec app php artisan queue-lab:dispatch timeout ``` 观察: - Horizon 的 Dashboard 能看到 throughput、runtime、recent jobs。 - Pending Jobs 可观察延迟任务、限流释放后的等待任务。 - Failed Jobs 可观察永久失败、死信式隔离等故意失败任务。 - `/queue-lab` 仍然是项目自己的练习记录视角,可以看到每个场景写入的事件。 恢复传统 worker: ```bash docker compose exec supervisor supervisorctl stop horizon docker compose exec supervisor supervisorctl start queue-default docker compose exec supervisor supervisorctl start queue-priority:* ``` ## 场景说明和观察方式 所有场景都用同一个触发格式: ```bash docker compose exec app php artisan queue-lab:dispatch ``` | 场景 key | 触发命令 | 会发生什么 | 如何查看效果 | | --- | --- | --- | --- | | `success` | `queue-lab:dispatch success` | 投递一个 Redis `default` 任务,记录开始和成功事件。 | `/queue-lab` 看状态变为 `已成功`;`supervisorctl tail queue-default` 看 worker 日志。 | | `delayed` | `queue-lab:dispatch delayed` | 投递一个延迟 30 秒的 Redis `default` 任务。 | 先看 `/queue-lab` 中状态停留在 `已派发`,30 秒后变为成功;Horizon Pending Jobs 可看到等待中的任务。 | | `priority` | `queue-lab:dispatch priority` | 依次投递 `low`、`default`、`high` 三个任务,但 worker 配置按 `high,default,low` 消费。 | `/queue-lab` 最近事件看 `Priority job started on high/default/low`;`tail queue-priority:queue-priority_00` 看 priority worker 日志。 | | `retry-then-succeed` | `queue-lab:dispatch retry-then-succeed` | 前两次 attempt 故意失败,第三次成功;backoff 为 1 秒、3 秒。 | `/queue-lab` 看 attempt 增长和最终成功;`queue:failed` 通常不会留下终态失败。 | | `permanent-failure` | `queue-lab:dispatch permanent-failure` | 每次 attempt 都失败,耗尽 3 次后进入 `failed_jobs`。 | `/queue-lab` 状态变为 `已失败`;`queue:failed` 查看 UUID;`queue:retry ` 可练习重试。 | | `manual-retry` | `queue-lab:dispatch manual-retry` | 和永久失败一样制造失败,重点是手动使用 `queue:retry `。 | 先 `queue:failed` 拿 UUID,再 `queue:retry `,刷新 `/queue-lab` 看新增事件。 | | `timeout` | `queue-lab:dispatch timeout` | 投递到 Redis `slow` 队列;job `$timeout = 2`,内部 `sleep(5)`,用于观察超时。 | 默认传统 worker 不消费 `slow`。建议启动 Horizon 后观察,或临时执行 `docker compose exec app php artisan queue:work redis --queue=slow --tries=1 --timeout=10`。 | | `backoff` | `queue-lab:dispatch backoff` | 前两次失败,按 `[5, 15]` 秒 backoff 后重试,第三次成功。 | `/queue-lab` 看事件时间间隔;Horizon 可看释放后的等待。 | | `chain` | `queue-lab:dispatch chain` | 派发三个链式任务,必须按 1、2、3 顺序执行。 | `/queue-lab` 最近事件看 `Chain step 1/2/3 completed` 顺序。 | | `batch` | `queue-lab:dispatch batch` | 派发三个 batch step,并写入 Laravel `job_batches` 表。 | `/queue-lab` 看 batch step 事件;MySQL 查 `job_batches` 表。 | | `unique` | `queue-lab:dispatch unique` | 连续投递两个相同唯一锁 key 的 job,只允许一个被接受处理。 | `/queue-lab` 看唯一任务事件;Horizon/日志中对比实际处理数量。 | | `rate-limited` | `queue-lab:dispatch rate-limited` | 投递 5 个 Redis `api` 任务;`queue-lab-api` limiter 每分钟只放行 2 个。 | 默认传统 worker 不消费 `api`。建议启动 Horizon 后观察 Pending Jobs 和释放延迟。 | | `dead-letter` | `queue-lab:dispatch dead-letter` | 投递到 Redis `dead-letter` 隔离队列,并故意失败。 | 先 `supervisorctl start queue-dead-letter`,再 dispatch;`queue:failed` 看失败记录;`tail queue-dead-letter` 看隔离 worker 日志。 | | `database` | `queue-lab:dispatch database` | 使用 Laravel Database queue,把 pending job 写入 `jobs` 表,由 `queue-database` 消费。 | 想看 pending,可先 `supervisorctl stop queue-database`,dispatch 后查 `jobs` 表,再 `start queue-database` 消费。 | ## 查看数据库效果 下面命令直接在 MySQL 容器中查询表,适合验证 `/queue-lab` 页面背后的真实记录。 ```bash docker compose exec mysql mysql -ularavel -psecret laravel_queue_lab -e "select id, scenario_key, title, status, attempts_observed, created_at from queue_exercises order by id desc limit 10;" ``` 查看最近事件: ```bash docker compose exec mysql mysql -ularavel -psecret laravel_queue_lab -e "select id, queue_exercise_id, type, message, attempt, created_at from queue_events order by id desc limit 20;" ``` 查看 Database queue pending jobs: ```bash docker compose exec mysql mysql -ularavel -psecret laravel_queue_lab -e "select id, queue, attempts, reserved_at, available_at, created_at from jobs order by id desc limit 10;" ``` 查看失败任务: ```bash docker compose exec mysql mysql -ularavel -psecret laravel_queue_lab -e "select id, uuid, queue, failed_at from failed_jobs order by id desc limit 10;" ``` 查看 batch: ```bash docker compose exec mysql mysql -ularavel -psecret laravel_queue_lab -e "select id, name, total_jobs, pending_jobs, failed_jobs, created_at from job_batches order by created_at desc limit 10;" ``` ## 查看 Redis 队列效果 Laravel Redis queue 的 pending list 常见 key 是 `queues:`: ```bash docker compose exec redis redis-cli llen queues:default docker compose exec redis redis-cli llen queues:api docker compose exec redis redis-cli llen queues:slow ``` 延迟和释放等待中的任务通常在 sorted set 中: ```bash docker compose exec redis redis-cli zcard queues:default:delayed docker compose exec redis redis-cli zcard queues:api:delayed ``` 这些 Redis 命令适合用来确认“任务确实排队了,只是 worker 暂时没有消费”。 ## 清理和重置 常规重置: ```bash docker compose exec app php artisan queue-lab:reset --force docker compose exec app php artisan queue:flush docker compose exec app php artisan queue:clear redis --queue=default docker compose exec app php artisan queue:clear redis --queue=api docker compose exec app php artisan queue:clear redis --queue=slow ``` 每条命令的作用: | 命令 | 清理内容 | 不清理什么 | | --- | --- | --- | | `queue-lab:reset --force` | 清理练习表、事件表、失败任务表、批次表、Database queue 的 `jobs` 表。 | 不清理 Redis pending jobs。 | | `queue:flush` | 清空 `failed_jobs`。 | 不清理练习记录和 Redis pending jobs。 | | `queue:clear redis --queue=` | 清空指定 Redis queue 的 pending jobs。 | 不清理 `failed_jobs`、`queue_exercises`、`queue_events`。 | | `docker compose down` | 停止并删除容器。 | 默认保留 named volume,所以 MySQL 数据还在。 | | `docker compose down -v` | 停止容器并删除 volume。 | 会删除 MySQL 数据,等于彻底重置数据库。谨慎使用。 | ## 服务端口 | Service | URL / Port | 说明 | | --- | --- | --- | | Nginx | http://localhost:8080 | Web 入口,提供 `/queue-lab` 和 `/horizon`。 | | MySQL | localhost:33066 | 宿主机连接 MySQL 的端口;容器内使用 `mysql:3306`。 | | Redis | localhost:63790 | 宿主机连接 Redis 的端口;容器内使用 `redis:6379`。 | | Horizon | http://localhost:8080/horizon | 需要 `supervisorctl start horizon` 后才有 worker 数据。 | ## 学习文档 - [docs/queue-scenarios.md](docs/queue-scenarios.md):按场景拆开的练习说明。 - [docs/supervisorctl-drills.md](docs/supervisorctl-drills.md):Supervisor 操作练习。 - [docs/local-run.md](docs/local-run.md):不使用 Docker 时的本地运行路径。 - [docs/troubleshooting.md](docs/troubleshooting.md):常见问题和恢复命令。 ## 项目结构 - `app/QueueLab`: 场景目录、分发器、事件记录服务。 - `app/Jobs/QueueLab`: 每个队列学习场景的 job。 - `app/Console/Commands`: `queue-lab:*` Artisan 命令。 - `resources/views/queue-lab`: 练习台 Blade 页面。 - `docker/supervisor`: Supervisor 主配置和多个 program 配置。 - `docs/adr`: 已确认的技术取舍。