
大模型推理队列是承载用户各类生成请求的缓冲调度载体。不同于普通Web接口,大模型单次推理消耗大量GPU显存与算力,无法瞬时并发处理海量请求。
队列的核心作用是把突发涌入的请求进行暂存、排队、有序分发,成为接入层与推理引擎之间的中间缓冲层。无论是对话问答、文案创作、代码生成、知识库问答,所有线上大模型接口请求,都必须经过推理队列流转调度。队列既可以基于单机内存实现,也可借助Redis、消息中间件搭建分布式全局推理队列,适配集群多节点场景。

队列积压本质是请求入队速率持续超过模型推理出队处理速率。业务流量突发暴涨、长耗时请求占用资源、GPU算力瓶颈、无合理调度策略,都会引发积压。一旦形成积压,最直观表现就是用户侧响应延迟飙升、接口超时报错。严重情况下会造成推理进程负载过高、内存持续占用溢出、GPU利用率异常抖动。更会向上游链路传导压力,引发服务雪崩、接口级连锁故障,直接影响整体业务可用性。
一旦队列中等待请求持续堆积,最终导致:
请求排队治理是一套覆盖请求接入、排队、调度、执行、容错的全链路管控体系,针对队列积压的全流程优化手段。
核心涵盖推理队列限流、多级别优先级调度、长短请求拆分、阻塞队列溢出防护、大模型集群负载均衡五大核心模块。
治理的核心目标:


生产环境大模型服务普遍采用线程安全阻塞队列作为底层结构。阻塞队列具备两大核心特性:
天然适配多线程并发消费场景,无需手动加锁即可保证请求读写安全。分布式场景下会基于Redis List、RabbitMQ、Kafka实现分布式阻塞队列,实现多节点共享排队任务。
简而言之,大模型服务主流使用阻塞队列,支持:
每一个环节都承担独立管控作用,接入层做前置过滤,队列做缓冲排队,调度器做资源分配,推理引擎做计算执行。

重要过程说明:
整个流程闭环运行,保证请求有序流转,不会出现乱序、重复执行、资源抢占等问题。
限流是在请求接入队列之前,对单位时间内允许进入系统的请求总量做硬性管控。属于队列积压治理的第一道防线,从入口拦截超额流量,从根源避免队列被无限撑满。不是单纯拒绝请求,而是通过可控的流量整形,让进入队列的请求量匹配后端推理集群的处理能力。
1.2.1 令牌桶算法
1.2.2 漏桶算法
1.2.3 固定窗口/滑动窗口限流
基于令牌桶算法实现大模型API限流,通过容量控制突发流量、速率控制持续压力,演示突发请求拦截、令牌恢复、稳定流量三种场景下的限流效果与通过率统计。
import time
import threading
class TokenBucket:
def __init__(self, capacity: int, rate: float):
self.capacity = capacity # 令牌桶容量(最大并发)
self.rate = rate # 每秒生成令牌数
self.tokens = capacity # 当前令牌数
self.last_time = time.time()
self.lock = threading.Lock()
self.total_requests = 0 # 总请求数
self.passed_requests = 0 # 通过请求数
self.rejected_requests = 0 # 拒绝请求数
def acquire(self, tokens=1) -> bool:
"""获取令牌,成功返回True,失败返回False"""
with self.lock:
now = time.time()
# 计算时间差,生成新令牌
delta = now - self.last_time
new_tokens = delta * self.rate
self.tokens += new_tokens
self.tokens = min(self.tokens, self.capacity)
self.last_time = now
self.total_requests += 1
if self.tokens >= tokens:
self.tokens -= tokens
self.passed_requests += 1
return True
else:
self.rejected_requests += 1
return False
def get_stats(self):
"""获取限流统计信息"""
return {
"current_tokens": round(self.tokens, 2),
"total_requests": self.total_requests,
"passed": self.passed_requests,
"rejected": self.rejected_requests,
"pass_rate": f"{self.passed_requests / max(self.total_requests, 1) * 100:.1f}%"
}
# 大模型队列限流实例:每秒生成2个令牌,桶容量5(模拟GPU显存限制)
llm_rate_limiter = TokenBucket(capacity=5, rate=2)
def handle_llm_request(request_id: str, prompt: str = "", simulate_process: bool = True):
"""处理大模型请求"""
timestamp = time.strftime("%H:%M:%S", time.localtime())
# 请求先获取令牌
if llm_rate_limiter.acquire():
print(f"[{timestamp}] 请求{request_id}:✓ 获取令牌成功 | 当前令牌: {llm_rate_limiter.tokens:.1f} | 进入推理队列")
# 模拟推理耗时(可选,用于演示令牌消耗)
if simulate_process:
time.sleep(0.05) # 缩短处理时间,让限流效果更明显
return True
else:
print(f"[{timestamp}] 请求{request_id}:✗ 限流触发 | 当前令牌: {llm_rate_limiter.tokens:.1f} | 排队等待或拒绝")
return False
def burst_test_concurrent():
"""并发突发测试:多线程同时请求"""
import concurrent.futures
print("=" * 60)
print("【场景1】并发突发流量测试:20个请求同时到达")
print("=" * 60)
print(f"配置:令牌桶容量={llm_rate_limiter.capacity}, 生成速率={llm_rate_limiter.rate}/秒")
print("-" * 60)
results = {"passed": 0, "rejected": 0}
def worker(i):
return handle_llm_request(f"concurrent_{i}", simulate_process=False)
# 使用线程池并发执行20个请求
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
futures = [executor.submit(worker, i) for i in range(20)]
for future in concurrent.futures.as_completed(futures):
if future.result():
results["passed"] += 1
else:
results["rejected"] += 1
print("-" * 60)
stats = llm_rate_limiter.get_stats()
print(f"统计:总请求={stats['total_requests']}, 通过={stats['passed']}, 拒绝={stats['rejected']}, 通过率={stats['pass_rate']}")
print(f"说明:并发请求中仅前{llm_rate_limiter.capacity}个获取令牌,其余被拒绝")
# ===================== 测试场景 =====================
# 场景1:并发突发测试
burst_test_concurrent()
print("\n" + "=" * 60)
print("【场景2】令牌恢复测试:等待3秒后再次请求")
print("=" * 60)
# 先清空令牌
llm_rate_limiter.tokens = 0
print(f"当前令牌数已清空: {llm_rate_limiter.tokens:.1f}")
time.sleep(3) # 等待令牌恢复
print(f"等待3秒后,当前令牌数: {llm_rate_limiter.tokens:.1f} (应恢复约{min(3 * llm_rate_limiter.rate, llm_rate_limiter.capacity)}个)")
for i in range(8):
handle_llm_request(f"recover_{i}")
time.sleep(0.05)
print("\n" + "=" * 60)
print("【场景3】持续流量测试:请求速率 > 令牌生成速率")
print("=" * 60)
# 重置计数器
llm_rate_limiter.total_requests = 0
llm_rate_limiter.passed_requests = 0
llm_rate_limiter.rejected_requests = 0
llm_rate_limiter.tokens = llm_rate_limiter.capacity # 重置令牌
print(f"配置:令牌生成速率={llm_rate_limiter.rate}/秒,请求间隔=0.3秒(即约3.3请求/秒)")
print("-" * 60)
# 模拟20个请求,间隔0.3秒(请求速率 > 令牌生成速率)
for i in range(20):
handle_llm_request(f"steady_{i}")
time.sleep(0.3)
print("-" * 60)
stats = llm_rate_limiter.get_stats()
print(f"最终统计:总请求={stats['total_requests']}, 通过={stats['passed']}, 拒绝={stats['rejected']}, 通过率={stats['pass_rate']}")
print(f"说明:当请求速率({1/0.3:.1f}/秒) > 令牌生成速率({llm_rate_limiter.rate}/秒)时,部分请求被拒绝")
print("=" * 60)输出结果:
============================================================ 【场景1】并发突发流量测试:20个请求同时到达 ============================================================ 配置:令牌桶容量=5, 生成速率=2/秒 ------------------------------------------------------------ [22:09:03] 请求concurrent_0:✓ 获取令牌成功 | 当前令牌: 4.0 | 进入推理队列 [22:09:03] 请求concurrent_1:✓ 获取令牌成功 | 当前令牌: 3.0 | 进入推理队列 [22:09:03] 请求concurrent_3:✓ 获取令牌成功 | 当前令牌: 1.0 | 进入推理队列 [22:09:03] 请求concurrent_2:✓ 获取令牌成功 | 当前令牌: 2.0 | 进入推理队列 [22:09:03] 请求concurrent_5:✗ 限流触发 | 当前令牌: 0.0 | 排队等待或拒绝 [22:09:03] 请求concurrent_6:✗ 限流触发 | 当前令牌: 0.0 | 排队等待或拒绝 [22:09:03] 请求concurrent_4:✓ 获取令牌成功 | 当前令牌: 0.0 | 进入推理队列 [22:09:03] 请求concurrent_9:✗ 限流触发 | 当前令牌: 0.0 | 排队等待或拒绝 [22:09:03] 请求concurrent_8:✗ 限流触发 | 当前令牌: 0.0 | 排队等待或拒绝 [22:09:03] 请求concurrent_11:✗ 限流触发 | 当前令牌: 0.0 | 排队等待或拒绝 [22:09:03] 请求concurrent_7:✗ 限流触发 | 当前令牌: 0.0 | 排队等待或拒绝 [22:09:03] 请求concurrent_13:✗ 限流触发 | 当前令牌: 0.0 | 排队等待或拒绝 [22:09:03] 请求concurrent_15:✗ 限流触发 | 当前令牌: 0.0 | 排队等待或拒绝 [22:09:03] 请求concurrent_16:✗ 限流触发 | 当前令牌: 0.0 | 排队等待或拒绝 [22:09:03] 请求concurrent_10:✗ 限流触发 | 当前令牌: 0.0 | 排队等待或拒绝 [22:09:03] 请求concurrent_19:✗ 限流触发 | 当前令牌: 0.0 | 排队等待或拒绝 [22:09:03] 请求concurrent_12:✗ 限流触发 | 当前令牌: 0.0 | 排队等待或拒绝 [22:09:03] 请求concurrent_18:✗ 限流触发 | 当前令牌: 0.0 | 排队等待或拒绝 [22:09:03] 请求concurrent_17:✗ 限流触发 | 当前令牌: 0.0 | 排队等待或拒绝 [22:09:03] 请求concurrent_14:✗ 限流触发 | 当前令牌: 0.0 | 排队等待或拒绝 ------------------------------------------------------------ 统计:总请求=20, 通过=5, 拒绝=15, 通过率=25.0% 说明:并发请求中仅前5个获取令牌,其余被拒绝 ============================================================ 【场景2】令牌恢复测试:等待3秒后再次请求 ============================================================ 当前令牌数已清空: 0.0 等待3秒后,当前令牌数: 0.0 (应恢复约5个) [22:09:06] 请求recover_0:✓ 获取令牌成功 | 当前令牌: 4.0 | 进入推理队列 [22:09:06] 请求recover_1:✓ 获取令牌成功 | 当前令牌: 3.2 | 进入推理队列 [22:09:06] 请求recover_2:✓ 获取令牌成功 | 当前令牌: 2.4 | 进入推理队列 [22:09:06] 请求recover_3:✓ 获取令牌成功 | 当前令牌: 1.6 | 进入推理队列 [22:09:07] 请求recover_4:✓ 获取令牌成功 | 当前令牌: 0.8 | 进入推理队列 [22:09:07] 请求recover_5:✓ 获取令牌成功 | 当前令牌: 0.1 | 进入推理队列 [22:09:07] 请求recover_6:✗ 限流触发 | 当前令牌: 0.3 | 排队等待或拒绝 [22:09:07] 请求recover_7:✗ 限流触发 | 当前令牌: 0.4 | 排队等待或拒绝 ============================================================ 【场景3】持续流量测试:请求速率 > 令牌生成速率 ============================================================ 配置:令牌生成速率=2/秒,请求间隔=0.3秒(即约3.3请求/秒) ------------------------------------------------------------ [22:09:07] 请求steady_0:✓ 获取令牌成功 | 当前令牌: 4.0 | 进入推理队列 [22:09:07] 请求steady_1:✓ 获取令牌成功 | 当前令牌: 3.7 | 进入推理队列 [22:09:08] 请求steady_2:✓ 获取令牌成功 | 当前令牌: 3.4 | 进入推理队列 [22:09:08] 请求steady_3:✓ 获取令牌成功 | 当前令牌: 3.1 | 进入推理队列 [22:09:08] 请求steady_4:✓ 获取令牌成功 | 当前令牌: 2.8 | 进入推理队列 [22:09:09] 请求steady_5:✓ 获取令牌成功 | 当前令牌: 2.5 | 进入推理队列 [22:09:09] 请求steady_6:✓ 获取令牌成功 | 当前令牌: 2.2 | 进入推理队列 [22:09:09] 请求steady_7:✓ 获取令牌成功 | 当前令牌: 1.9 | 进入推理队列 [22:09:10] 请求steady_8:✓ 获取令牌成功 | 当前令牌: 1.6 | 进入推理队列 [22:09:10] 请求steady_9:✓ 获取令牌成功 | 当前令牌: 1.3 | 进入推理队列 [22:09:10] 请求steady_10:✓ 获取令牌成功 | 当前令牌: 1.0 | 进入推理队列 [22:09:11] 请求steady_11:✓ 获取令牌成功 | 当前令牌: 0.7 | 进入推理队列 [22:09:11] 请求steady_12:✓ 获取令牌成功 | 当前令牌: 0.4 | 进入推理队列 [22:09:11] 请求steady_13:✓ 获取令牌成功 | 当前令牌: 0.2 | 进入推理队列 [22:09:12] 请求steady_14:✗ 限流触发 | 当前令牌: 0.9 | 排队等待或拒绝 [22:09:12] 请求steady_15:✓ 获取令牌成功 | 当前令牌: 0.5 | 进入推理队列 [22:09:12] 请求steady_16:✓ 获取令牌成功 | 当前令牌: 0.2 | 进入推理队列 [22:09:13] 请求steady_17:✗ 限流触发 | 当前令牌: 0.9 | 排队等待或拒绝 [22:09:13] 请求steady_18:✓ 获取令牌成功 | 当前令牌: 0.5 | 进入推理队列 [22:09:13] 请求steady_19:✓ 获取令牌成功 | 当前令牌: 0.2 | 进入推理队列 ------------------------------------------------------------ 最终统计:总请求=20, 通过=18, 拒绝=2, 通过率=90.0% 说明:当请求速率(3.3/秒) > 令牌生成速率(2/秒)时,部分请求被拒绝 ============================================================
摒弃传统FIFO先进先出的单一规则,为不同业务、不同用户类型的请求设置等级权重。调度器优先从高优先级队列取任务执行,保障高价值业务优先占用算力资源。解决普通请求挤占核心业务、低价值批量任务阻塞实时对话请求的痛点。
可根据业务实际场景扩展更多优先级等级,适配复杂业务分层架构。

基于多级队列实现大模型请求优先级调度,VIP用户请求优先于普通用户和普通用户优先于免费用户处理,确保高价值用户在突发流量下仍能获得及时响应。
import queue
import time
import threading
from enum import Enum
class PriorityLevel(Enum):
"""优先级等级"""
VIP = 0 # 最高优先级:VIP用户/付费用户
NORMAL = 1 # 普通优先级:普通用户
FREE = 2 # 最低优先级:免费试用用户
class PriorityLLMQueue:
def __init__(self, maxsize: int = 100):
"""
多级优先级队列
maxsize: 每级队列最大容量
"""
# 多级队列:0=VIP, 1=普通, 2=免费
self.queues = {
PriorityLevel.VIP: queue.Queue(maxsize=maxsize),
PriorityLevel.NORMAL: queue.Queue(maxsize=maxsize),
PriorityLevel.FREE: queue.Queue(maxsize=maxsize)
}
self.stats = {
PriorityLevel.VIP: {"enqueued": 0, "dequeued": 0},
PriorityLevel.NORMAL: {"enqueued": 0, "dequeued": 0},
PriorityLevel.FREE: {"enqueued": 0, "dequeued": 0}
}
self.lock = threading.Lock()
def enqueue(self, request: dict, priority: PriorityLevel) -> bool:
"""
请求入队
priority: PriorityLevel.VIP/NORMAL/FREE
"""
try:
self.queues[priority].put_nowait(request)
with self.lock:
self.stats[priority]["enqueued"] += 1
return True
except queue.Full:
print(f"[警告] 优先级{priority.name}队列已满,请求{request['id']}被拒绝")
return False
def dequeue(self) -> tuple:
"""
优先调度高优先级请求
返回: (request, priority) 或 (None, None)
"""
for priority in [PriorityLevel.VIP, PriorityLevel.NORMAL, PriorityLevel.FREE]:
try:
request = self.queues[priority].get_nowait()
with self.lock:
self.stats[priority]["dequeued"] += 1
return request, priority
except queue.Empty:
continue
return None, None
def get_queue_sizes(self) -> dict:
"""获取各级队列当前大小"""
return {
priority.name: self.queues[priority].qsize()
for priority in PriorityLevel
}
def get_stats(self) -> dict:
"""获取统计信息"""
return {
priority.name: {
"队列长度": self.queues[priority].qsize(),
"已入队": self.stats[priority]["enqueued"],
"已处理": self.stats[priority]["dequeued"]
}
for priority in PriorityLevel
}
# ===================== 测试场景 =====================
def test_basic_priority():
"""基础优先级调度测试"""
print("=" * 60)
print("【场景1】基础优先级调度测试")
print("=" * 60)
print("说明:VIP用户优先于普通用户,普通用户优先于免费用户")
print("-" * 60)
llm_queue = PriorityLLMQueue()
# 模拟混合请求入队(按乱序入队)
requests = [
{"id": "free_user_1", "prompt": "你好"},
{"id": "vip_user_1", "prompt": "紧急问题"},
{"id": "normal_user_1", "prompt": "普通咨询"},
{"id": "free_user_2", "prompt": "谢谢"},
{"id": "vip_user_2", "prompt": "重要业务"},
{"id": "normal_user_2", "prompt": "一般问题"},
]
priorities = [
PriorityLevel.FREE,
PriorityLevel.VIP,
PriorityLevel.NORMAL,
PriorityLevel.FREE,
PriorityLevel.VIP,
PriorityLevel.NORMAL
]
print("【入队阶段】")
for req, prio in zip(requests, priorities):
llm_queue.enqueue(req, prio)
print(f"\n当前队列状态: {llm_queue.get_queue_sizes()}")
print("\n【调度执行阶段】")
processed = []
while True:
req, prio = llm_queue.dequeue()
if not req:
break
print(f"[处理] {req['id']} (优先级: {prio.name}) - 提示: {req['prompt']}")
processed.append((req['id'], prio.name))
time.sleep(0.2)
print(f"\n处理顺序: {' -> '.join([p[0] for p in processed])}")
print(f"优先级顺序: {' -> '.join([p[1] for p in processed])}")
print("-" * 60)
def test_burst_priority():
"""突发流量下的优先级保障测试"""
print("\n" + "=" * 60)
print("【场景2】突发流量下的优先级保障")
print("=" * 60)
print("说明:大量免费用户请求涌入时,VIP用户请求仍能被优先处理")
print("-" * 60)
llm_queue = PriorityLLMQueue()
# 模拟突发:10个免费用户 + 2个VIP用户
print("【突发入队】10个免费用户请求 + 2个VIP用户请求")
for i in range(10):
llm_queue.enqueue({"id": f"free_user_{i}", "prompt": f"免费问题{i}"}, PriorityLevel.FREE)
# VIP用户稍后到达
time.sleep(0.1)
llm_queue.enqueue({"id": "vip_user_urgent", "prompt": "紧急业务"}, PriorityLevel.VIP)
llm_queue.enqueue({"id": "vip_user_important", "prompt": "重要咨询"}, PriorityLevel.VIP)
print(f"\n当前队列状态: {llm_queue.get_queue_sizes()}")
print("\n【调度执行】")
processed = []
for i in range(12):
req, prio = llm_queue.dequeue()
if req:
print(f"[{i+1:2d}] {req['id']:20s} | 优先级: {prio.name:6s}")
processed.append(prio.name)
# 统计
vip_count = processed.count("VIP")
free_count = processed.count("FREE")
print(f"\n统计:VIP请求处理{vip_count}个(占比{vip_count/len(processed)*100:.1f}%)")
print(f" 免费请求处理{free_count}个(占比{free_count/len(processed)*100:.1f}%)")
print("说明:虽然免费请求先入队,但VIP请求被优先处理")
print("-" * 60)
def test_queue_full():
"""队列满时的处理测试"""
print("\n" + "=" * 60)
print("【场景3】队列容量限制测试")
print("=" * 60)
print("说明:每级队列容量有限,防止无限堆积")
print("-" * 60)
# 创建小容量队列
llm_queue = PriorityLLMQueue(maxsize=3)
print("【填满VIP队列】")
for i in range(5):
success = llm_queue.enqueue({"id": f"vip_user_{i}"}, PriorityLevel.VIP)
print(f" VIP请求{i}: {'入队成功' if success else '入队失败(队列满)'}")
print(f"\n最终队列状态:\n{llm_queue.get_stats()}")
print("-" * 60)
# ===================== 运行所有测试 =====================
if __name__ == "__main__":
test_basic_priority()
test_burst_priority()
test_queue_full()
print("\n" + "=" * 60)
print("测试完成!")
print("=" * 60)输出结果:
============================================================ 【场景1】基础优先级调度测试 ============================================================ 说明:VIP用户优先于普通用户,普通用户优先于免费用户 ------------------------------------------------------------ 【入队阶段】 当前队列状态: {'VIP': 2, 'NORMAL': 2, 'FREE': 2} 【调度执行阶段】 [处理] vip_user_1 (优先级: VIP) - 提示: 紧急问题 [处理] vip_user_2 (优先级: VIP) - 提示: 重要业务 [处理] normal_user_1 (优先级: NORMAL) - 提示: 普通咨询 [处理] normal_user_2 (优先级: NORMAL) - 提示: 一般问题 [处理] free_user_1 (优先级: FREE) - 提示: 你好 [处理] free_user_2 (优先级: FREE) - 提示: 谢谢 处理顺序: vip_user_1 -> vip_user_2 -> normal_user_1 -> normal_user_2 -> free_user_1 -> free_user_2 优先级顺序: VIP -> VIP -> NORMAL -> NORMAL -> FREE -> FREE ------------------------------------------------------------ ============================================================ 【场景2】突发流量下的优先级保障 ============================================================ 说明:大量免费用户请求涌入时,VIP用户请求仍能被优先处理 ------------------------------------------------------------ 【突发入队】10个免费用户请求 + 2个VIP用户请求 当前队列状态: {'VIP': 2, 'NORMAL': 0, 'FREE': 10} 【调度执行】 [ 1] vip_user_urgent | 优先级: VIP [ 2] vip_user_important | 优先级: VIP [ 3] free_user_0 | 优先级: FREE [ 4] free_user_1 | 优先级: FREE [ 5] free_user_2 | 优先级: FREE [ 6] free_user_3 | 优先级: FREE [ 7] free_user_4 | 优先级: FREE [ 8] free_user_5 | 优先级: FREE [ 9] free_user_6 | 优先级: FREE [10] free_user_7 | 优先级: FREE [11] free_user_8 | 优先级: FREE [12] free_user_9 | 优先级: FREE 统计:VIP请求处理2个(占比16.7%) 免费请求处理10个(占比83.3%) 说明:虽然免费请求先入队,但VIP请求被优先处理 ------------------------------------------------------------ ============================================================ 【场景3】队列容量限制测试 ============================================================ 说明:每级队列容量有限,防止无限堆积 ------------------------------------------------------------ 【填满VIP队列】 VIP请求0: 入队成功 VIP请求1: 入队成功 VIP请求2: 入队成功 [警告] 优先级VIP队列已满,请求vip_user_3被拒绝 VIP请求3: 入队失败(队列满) [警告] 优先级VIP队列已满,请求vip_user_4被拒绝 VIP请求4: 入队失败(队列满) 最终队列状态: {'VIP': {'队列长度': 3, '已入队': 3, '已处理': 0}, 'NORMAL': {'队列长度': 0, '已入队': 0, '已处理': 0}, 'FREE': {'队列长度': 0, '已入队': 0, '已处理': 0}} ------------------------------------------------------------ ============================================================ 测试完成! ============================================================
依据输入Prompt长度、最大生成Token数、预估推理耗时,自动将请求划分为短请求与长请求两类。分别送入独立队列、分配专属推理资源,彻底解决长请求阻塞短请求的经典问题。

以Token数量为核心判定标准,结合模型推理速度预估整体耗时。
系统支持动态阈值,根据集群实时负载自动调整长短请求划分边界,适配流量波动。

基于双队列架构实现大模型请求长短拆分,短请求(≤512 token)进入快速通道优先处理,长请求进入慢速通道独立执行,避免长文本生成阻塞短文本响应,提升整体服务吞吐量与用户体验。
import queue
import threading
import time
from dataclasses import dataclass
# 定义请求结构体(大模型标准请求格式)
@dataclass
class LLMRequest:
req_id: str
prompt: str
max_tokens: int
create_time: float = None
def __post_init__(self):
self.create_time = time.time()
class LLMLongShortRequestSplitter:
def __init__(self, short_token_threshold=512):
"""
长短请求拆分器
:param short_token_threshold: 短请求最大token数,超过即为长请求
"""
self.threshold = short_token_threshold
# 两个独立队列:短请求队列、长请求队列
self.short_queue = queue.Queue(maxsize=50)
self.long_queue = queue.Queue(maxsize=30)
# 启动独立消费者
self._start_consumers()
def _estimate_time(self, max_tokens):
"""模拟大模型推理耗时预估:token越多耗时越长"""
base_time = 0.2
token_time = max_tokens * 0.015
return round(base_time + token_time, 2)
def classify_request(self, req: LLMRequest):
"""请求分类:自动打入长/短队列"""
estimated_cost = self._estimate_time(req.max_tokens)
is_short = req.max_tokens <= self.threshold
if is_short:
try:
self.short_queue.put_nowait(req)
print(f"[短请求] 入队 | ID={req.req_id} | tokens={req.max_tokens} | 预估耗时={estimated_cost}s")
except queue.Full:
print(f"[短请求队列溢出] 拒绝请求 {req.req_id}")
else:
try:
self.long_queue.put_nowait(req)
print(f"[长请求] 入队 | ID={req.req_id} | tokens={req.max_tokens} | 预估耗时={estimated_cost}s")
except queue.Full:
print(f"[长请求队列溢出] 拒绝请求 {req.req_id}")
def _consume_short_request(self):
"""短请求消费者:低延迟、快速处理"""
while True:
try:
req = self.short_queue.get(timeout=1)
cost = self._estimate_time(req.max_tokens)
print(f"[短请求执行] ID={req.req_id} | 推理耗时={cost}s")
time.sleep(cost)
self.short_queue.task_done()
except queue.Empty:
continue
def _consume_long_request(self):
"""长请求消费者:慢速、不影响短请求"""
while True:
try:
req = self.long_queue.get(timeout=1)
cost = self._estimate_time(req.max_tokens)
print(f"[长请求执行] ID={req.req_id} | 推理耗时={cost}s")
time.sleep(cost)
self.long_queue.task_done()
except queue.Empty:
continue
def _start_consumers(self):
"""启动消费者线程"""
# 短请求用2个线程(低延迟、高吞吐)
threading.Thread(target=self._consume_short_request, daemon=True).start()
threading.Thread(target=self._consume_short_request, daemon=True).start()
# 长请求用1个线程(避免占用过多资源)
threading.Thread(target=self._consume_long_request, daemon=True).start()
# ====================== 测试 ======================
if __name__ == "__main__":
# 初始化拆分器:<=512 token 为短请求
splitter = LLMLongShortRequestSplitter(short_token_threshold=512)
# 模拟一批混合长短请求
test_requests = [
LLMRequest("req_001", "你好", max_tokens=64),
LLMRequest("req_002", "写一篇人工智能综述", max_tokens=2048),
LLMRequest("req_003", "什么是大模型", max_tokens=128),
LLMRequest("req_004", "生成1万字产品文档", max_tokens=10000),
LLMRequest("req_005", "介绍Python", max_tokens=256),
LLMRequest("req_006", "写一份年度总结报告", max_tokens=3000),
]
print("=== 开始提交请求 ===")
for req in test_requests:
splitter.classify_request(req)
time.sleep(0.2)
# 保持程序运行
input("\n按回车退出\n")输出结果:
=== 开始提交请求 === [短请求] 入队 | ID=req_001 | tokens=64 | 预估耗时=1.16s [短请求执行] ID=req_001 | 推理耗时=1.16s [长请求] 入队 | ID=req_002 | tokens=2048 | 预估耗时=30.92s [长请求执行] ID=req_002 | 推理耗时=30.92s [短请求] 入队 | ID=req_003 | tokens=128 | 预估耗时=2.12s [短请求执行] ID=req_003 | 推理耗时=2.12s [长请求] 入队 | ID=req_004 | tokens=10000 | 预估耗时=150.2s [短请求] 入队 | ID=req_005 | tokens=256 | 预估耗时=4.04s [长请求] 入队 | ID=req_006 | tokens=3000 | 预估耗时=45.2s [短请求执行] ID=req_005 | 推理耗时=4.04s [长请求执行] ID=req_004 | 推理耗时=150.2s [长请求执行] ID=req_006 | 推理耗时=45.2s
为阻塞推理队列设置最大容量上限,当排队请求达到阈值时,执行预设保护策略。防止队列无限制堆积占用内存,避免内存泄漏、进程 OOM 崩溃、服务不可用等严重故障。是大模型服务兜底稳定性的关键机制。

基于阻塞队列实现大模型请求溢出防护,队列满时低优先级请求直接丢弃、高优先级请求限时等待,配合80%容量预警与双线程消费,确保服务高负载下核心请求仍能被处理。
import queue
import threading
import time
from dataclasses import dataclass
# 定义大模型请求结构
@dataclass
class LLMRequest:
req_id: str
priority: int # 0最高 1中等 2最低
prompt: str
create_time: float = None
def __post_init__(self):
self.create_time = time.time()
class LLMBlockQueueOverflowProtect:
def __init__(self, max_queue_size=30, wait_timeout=5):
"""
阻塞队列溢出防护初始化
:param max_queue_size: 队列最大容量
:param wait_timeout: 请求队列最大等待超时(秒)
"""
self.max_queue_size = max_queue_size
self.wait_timeout = wait_timeout
# 线程安全阻塞队列
self.block_queue = queue.Queue(maxsize=self.max_queue_size)
# 启动推理消费线程
self._start_consumer()
def get_queue_usage(self):
"""获取队列使用率"""
current_size = self.block_queue.qsize()
usage = current_size / self.max_queue_size
return current_size, round(usage * 100, 2)
def alert_warning(self):
"""队列告警:使用率80%预警,100%溢出告警"""
_, usage = self.get_queue_usage()
if usage >= 100:
print(f"【严重告警】队列已满!使用率:{usage}%,触发溢出防护")
elif usage >= 80:
print(f"【预警】队列即将积压,使用率:{usage}%")
def try_enqueue(self, req: LLMRequest) -> bool:
"""
尝试入队 + 溢出防护
返回True:入队成功 False:入队被拒绝/超时
"""
self.alert_warning()
current_size, _ = self.get_queue_usage()
# 策略1:队列已满,低优先级直接丢弃
if current_size >= self.max_queue_size:
if req.priority >= 1:
print(f"【溢出丢弃】队列已满,低优请求丢弃 ID:{req.req_id} 优先级:{req.priority}")
return False
else:
# 高优请求尝试限时等待入队
try:
self.block_queue.put(req, timeout=self.wait_timeout)
print(f"【高优插队】高优先级请求限时等待入队成功 ID:{req.req_id}")
return True
except queue.Full:
print(f"【溢出拒绝】高优请求等待超时,入队失败 ID:{req.req_id}")
return False
# 队列未满,正常入队
try:
self.block_queue.put(req)
print(f"【正常入队】ID:{req.req_id} 优先级:{req.priority} 队列当前:{current_size+1}/{self.max_queue_size}")
return True
except Exception as e:
print(f"【入队异常】ID:{req.req_id} 错误:{str(e)}")
return False
def _consumer_loop(self):
"""推理消费线程:模拟LLM推理耗时"""
while True:
try:
# 从阻塞队列取任务,空则阻塞
req = self.block_queue.get(timeout=2)
# 模拟推理耗时
infer_cost = 0.5 + (req.priority * 0.3)
time.sleep(infer_cost)
print(f"【推理完成】ID:{req.req_id} 耗时:{infer_cost}s")
self.block_queue.task_done()
except queue.Empty:
continue
def _start_consumer(self):
# 启动2个推理消费线程
for _ in range(2):
t = threading.Thread(target=self._consumer_loop, daemon=True)
t.start()
# ====================== 测试演示 ======================
if __name__ == "__main__":
# 初始化:队列最大容量30,请求最大等待超时5秒
protect_queue = LLMBlockQueueOverflowProtect(max_queue_size=30, wait_timeout=5)
# 模拟连续涌入40个请求,超过队列容量,触发溢出防护
for i in range(40):
# 随机优先级 0/1/2
prio = i % 3
req = LLMRequest(
req_id=f"req_{i:03d}",
priority=prio,
prompt=f"测试请求内容{i}"
)
protect_queue.try_enqueue(req)
time.sleep(0.1)
# 保持程序运行观察消费过程
input("\n回车退出程序\n")输出结果:
【正常入队】ID:req_000 优先级:0 队列当前:1/30 【正常入队】ID:req_001 优先级:1 队列当前:1/30 【正常入队】ID:req_002 优先级:2 队列当前:1/30 【正常入队】ID:req_003 优先级:0 队列当前:2/30 【正常入队】ID:req_004 优先级:1 队列当前:3/30 【推理完成】ID:req_000 耗时:0.5s 【正常入队】ID:req_005 优先级:2 队列当前:3/30 【正常入队】ID:req_006 优先级:0 队列当前:4/30 【正常入队】ID:req_007 优先级:1 队列当前:5/30 【正常入队】ID:req_008 优先级:2 队列当前:6/30 【推理完成】ID:req_001 耗时:0.8s 【正常入队】ID:req_009 优先级:0 队列当前:6/30 【正常入队】ID:req_010 优先级:1 队列当前:7/30 【正常入队】ID:req_011 优先级:2 队列当前:8/30 【正常入队】ID:req_012 优先级:0 队列当前:9/30 【正常入队】ID:req_013 优先级:1 队列当前:10/30 【推理完成】ID:req_003 耗时:0.5s 【正常入队】ID:req_014 优先级:2 队列当前:10/30 【正常入队】ID:req_015 优先级:0 队列当前:11/30 【推理完成】ID:req_002 耗时:1.1s 【正常入队】ID:req_016 优先级:1 队列当前:11/30 【正常入队】ID:req_017 优先级:2 队列当前:12/30 【正常入队】ID:req_018 优先级:0 队列当前:13/30 【正常入队】ID:req_019 优先级:1 队列当前:14/30 【正常入队】ID:req_020 优先级:2 队列当前:15/30 【正常入队】ID:req_021 优先级:0 队列当前:16/30 【推理完成】ID:req_004 耗时:0.8s 【正常入队】ID:req_022 优先级:1 队列当前:16/30 【正常入队】ID:req_023 优先级:2 队列当前:17/30 【正常入队】ID:req_024 优先级:0 队列当前:18/30 【正常入队】ID:req_025 优先级:1 队列当前:19/30 【正常入队】ID:req_026 优先级:2 队列当前:20/30 【推理完成】ID:req_006 耗时:0.5s 【推理完成】ID:req_005 耗时:1.1s 【正常入队】ID:req_027 优先级:0 队列当前:19/30 【正常入队】ID:req_028 优先级:1 队列当前:20/30 【正常入队】ID:req_029 优先级:2 队列当前:21/30 【正常入队】ID:req_030 优先级:0 队列当前:22/30 【正常入队】ID:req_031 优先级:1 队列当前:23/30 【正常入队】ID:req_032 优先级:2 队列当前:24/30 【预警】队列即将积压,使用率:80.0% 【正常入队】ID:req_033 优先级:0 队列当前:25/30 【预警】队列即将积压,使用率:83.33% 【正常入队】ID:req_034 优先级:1 队列当前:26/30 【推理完成】ID:req_007 耗时:0.8s 【预警】队列即将积压,使用率:83.33% 【正常入队】ID:req_035 优先级:2 队列当前:26/30 【预警】队列即将积压,使用率:86.67% 【正常入队】ID:req_036 优先级:0 队列当前:27/30 【预警】队列即将积压,使用率:90.0% 【正常入队】ID:req_037 优先级:1 队列当前:28/30 【推理完成】ID:req_008 耗时:1.1s 【预警】队列即将积压,使用率:90.0% 【正常入队】ID:req_038 优先级:2 队列当前:28/30 【预警】队列即将积压,使用率:93.33% 【正常入队】ID:req_039 优先级:0 队列当前:29/30 【推理完成】ID:req_009 耗时:0.5s 【推理完成】ID:req_010 耗时:0.8s 【推理完成】ID:req_012 耗时:0.5s 【推理完成】ID:req_011 耗时:1.1s ..........(以后省略)
将全局推理队列中的排队请求,按照节点负载状态智能分发到多台推理服务器。实现多GPU节点算力统一调度,避免单节点负载过高、部分节点空闲浪费资源。是大模型服务横向扩容、支撑高并发流量的核心架构能力。

大模型服务和普通Web接口完全不是一个逻辑,它最核心的痛点就是算力稀缺、推理耗时不均,一旦没有队列治理体系,稍微一波流量峰值就容易直接拖垮服务。其实队列治理本质就是给大模型请求做有序管控、分层调度、兜底防护。从限流守住入口流量,再到优先级调度区分业务价值,配合长短请求拆分隔离任务类型,再加上阻塞队列溢出防护做兜底,最后靠集群负载均衡横向扩容,整套链路环环相扣,缺一不可。
做大模型除了懂模型调用,更要懂流量治理和资源调度。很多线上宕机、响应超时问题,根源都不是模型本身,而是排队机制混乱、没有限流和溢出防护导致的队列积压。看似简单的队列、限流、调度,实则是保障大模型服务高可用的底层基石。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。