面试知识库

跨层并发治理总览#

涉及: Layer 1 (API 接入) · Layer 2 (队列缓冲) · Layer 3 (编排调度)

并发治理不是某一层的事。V3 把”接收请求、排队任务、执行诊断”拆成三件不同的事,每一层用不同手段削峰限流,避免所有压力都挤到 Agent 执行阶段。

压力来源拆解#

AIOps 系统里的”压力”不是一种压力,而是多条链路同时受压。V3 把它们分开处理:

压力来源典型场景风险治理层级处理方式
用户请求压力多人同时点击诊断API 线程被长任务占住Layer 1同步/异步分流,高并发走后台提交
告警洪峰压力Alertmanager 批量推送 firing告警入口阻塞,任务重复Layer 1Webhook 只做校验、归一、去重、入库、入队
队列堆积压力短时间提交多于消费能力任务越积越多Layer 2队列保存 backlog,前端展示位置/深度/lag/DLQ
Worker 执行压力多 Worker 同时跑 AgentLLM/RAG/MCP 被并发打满Layer 3所有 Worker 共享全局执行上限
LLM 成本/配额压力多任务同时规划、执行、生成报告token 成本失控,RPM/TPM 打满Layer 3+4prompt 收敛、模型分层、步骤上限、token 统计
RAG/向量库压力多诊断同时检索、rerank延迟升高Layer 3后台执行限额间接保护检索链路
MCP 工具压力多诊断同时查系统/网络/Docker外部依赖抖动Layer 4+6Skill 工具白名单、并行上限、失败降级
数据库写入压力大量任务/证据同时落库连接池耗尽Layer 7任务状态分阶段写入,Redis 只保存运行态
前端长连接压力多个 SSE 同时流式输出连接占用时间长Layer 1同步 SSE 适合少量即时诊断,批量走后台

六层治理体系#

每一层解决一个不同的问题,自上而下逐级收敛:

关键点:并发请求数量、排队任务数量、真实诊断执行数量是三件不同的事。V3 允许短时间接收更多请求,但把昂贵的诊断执行收敛到一个可控上限内。

各层治理详解#

层级解决的问题做法详见
接入层削峰请求和告警不能直接压到 AgentAPI 只做校验、落库、入队,立即返回 task_id01-api-layer.md §1.1-1.2
队列缓冲短时间大量任务需要排队四级优先级队列,高优告警先被 Worker 领取02-queue-layer.md §2.1-2.2
执行层限额Worker 可扩展,但 LLM/RAG/MCP 有配额所有 Worker 共享全局执行上限 (Redis ZSET + Lua)03-orchestration-layer.md §3.2
接口限流防止单用户/IP/告警源刷爆系统固定窗口计数器,超限返回 42901-api-layer.md §1.3
失败恢复Worker 崩溃或任务超时不能丢任务XAUTOCLAIM 回收 + 重试 + DLQ02-queue-layer.md §2.4
可观测闭环并发治理必须能被看见队列深度/pending/lag/DLQ/Worker 存活/执行槽占用02-queue-layer.md §2.6

与压测报告的关系#

本文描述设计意图,实测数据见 PRESSURE_TEST_REPORT.md。压测验证了:

  • 读接口 3000 请求 / 200 并发,100% 成功
  • 后台诊断提交 200 请求 / 100 并发,100% 入队
  • Webhook 500 请求 / 100 并发,告警全部接收、归一、落库
  • 全局执行槽始终不超过 2/2,真实诊断并发可控

模拟面试问答#

🔥 热点拷问#

面试官:你这个并发设计,本地跑 3 个 Worker、2 个执行槽,跟生产环境差距大不大?你怎么证明这套东西上了生产能用?

差距肯定有。本地压测验证的是机制正确性——队列削峰、执行槽限制、优先级抢占、DLQ 这些逻辑在并发下是否按预期工作。生产环境的变量更多:网络延迟、Redis/Postgres 集群化、LLM API 的 RPM 波动。当前配置(3 Worker / 2 槽)是本地开发环境的经验值,上生产需要根据 LLM 配额和基础设施能力重新调参。但核心架构——请求接入和诊断执行分离、全局执行槽跨进程共享——这个拓扑不需要改,改的是参数。

追问:那执行槽用 Redis ZSET + Lua 做,Redis 本身是单线程的,如果争抢很频繁,Redis 会不会成为瓶颈?

当前场景不会。Lua 脚本只做 ZREMRANGEBYSCORE + ZCARD + ZADD 三个操作,执行时间在微秒级。执行槽的争抢频率取决于诊断任务的提交速率,不是请求速率——请求到执行之间有队列缓冲。即使 100 个 Worker 争抢 10 个槽位,每次 Lua 调用也就几微秒。真正的 Redis 瓶颈更可能出现在限流器的 INCR 高频调用上,但那也是简单的单键操作。


面试官:为什么不用 Kafka?你说 Redis Streams 够用,但 Kafka 不是更成熟吗?

两个原因。一是项目已经依赖 Redis(限流、执行槽、心跳),引入 Kafka 增加一个独立的有状态服务,运维成本上升但当前规模下收益不大。二是瓶颈不在队列吞吐——一个诊断任务跑 30-60 秒 LLM 调用,队列每分钟处理几十个任务就够了,Redis Streams 绰绰有余。Kafka 的优势在海量吞吐、跨数据中心复制和流式计算集成,这些当前用不上。如果告警量到了每秒几千条,或者需要多机房部署,那时候换 Kafka 才有实际收益。

常规问题#

面试官:如果全局执行槽设置为 1 或 10 分别会怎样?

设 1:所有诊断串行,告警堆积时延迟极高,但 LLM/RAG 压力最小。设 10:高并发但 LLM RPM/TPM 可能被打满,Postgres(向量/BM25 检索)和 MCP 工具延迟上升。当前默认 2 是在本地开发环境下的经验值——足够验证并发机制,又不会打爆依赖。生产环境应根据 LLM 配额和基础设施能力调整。

反思与改进#

面试官:这套并发设计的投入产出比怎么样?

队列 + Worker + 执行槽 + 心跳 + DLQ 大概花了两周。如果只做 demo,直接在 API 进程里跑 Agent 就够了。但如果要回答”高并发怎么办、任务丢了怎么办”这些面试问题,就必须有真实的队列和 Worker。从面试角度,这是项目里最能体现系统设计能力的部分,投入产出比很高。