Skip to content

十一、本项目中的 BRPOP 使用全景 ​

三个队列的 BRPOP 消费 ​

                        LPUSH              BRPOP
                        ←─────             ─────→
task:queue        [8, 7, 6]                     → Worker 取出 6
                                                  (FIFO 先进先出)

                        LPUSH              BRPOP
                        ←─────             ─────→
task:queue:vip    [102, 101]                    → Worker 优先取 VIP
task:queue:normal [202, 201]                    → VIP 空了才取普通
                        LPUSH              BRPOP [vip, normal]
                        ←─────             ─────→
                                                  → 先查 VIP,后查 normal

                        LPUSH              BRPOP
                        ←─────             ─────→
review:queue      [6, 5]                       → 管理员 API LPOP 取出 6
                                                  (审核面板展示)

Worker 消费循环完整代码 ​

python
def process_queue() -> None:
    logger.info("编排 Worker 启动,等待任务...")
    while True:
        try:
            # 优先消费 VIP 队列,其次普通队列
            # timeout=5 确保能响应 Ctrl+C 优雅退出
            result = redis_client.brpop(
                ["task:queue:vip", "task:queue:normal"],
                timeout=5
            )
            if result:
                queue_name, task_id = result
                task_id = int(task_id)
                logger.info(
                    "从 %s 取到任务 %s,开始生成",
                    queue_name, task_id
                )
                run_task(task_id)
        except KeyboardInterrupt:
            logger.info("Worker 收到退出信号,停止")
            break
        except Exception as e:
            logger.exception("Worker 处理异常: %s", e)
            time.sleep(1)

关键设计决策:

决策选择原因
阻塞 vs 轮询BRPOP零 CPU 等待
timeout5 秒平衡退出响应性和循环开销
多队列VIP + 普通优先VIP 用户优先体验
队列模式LPUSH + BRPOPFIFO 公平排队
异常处理catch + sleep(1)防止异常风暴,Worker 不崩溃