DeepSeek 扛高并发实战:架构思路与配置清单整理
DeepSeek 高并发解决方案|附配置文件
随着大模型应用从“体验式 Demo”走向“生产级系统”,越来越多企业开始将 DeepSeek 等大语言模型接入客服、知识库问答、代码助手、数据分析、智能办公等业务场景。与此同时,一个非常现实的问题也随之出现:当用户量上来之后,DeepSeek 服务如何支撑高并发访问?
很多团队在早期接入大模型时,往往只关注“能不能调用成功”“回答质量怎么样”,但一旦进入真实业务环境,就会遇到一系列高并发问题:
- 多个用户同时请求,接口响应变慢;
- 大模型推理耗时长,连接容易超时;
- 流式输出占用连接时间长;
- 单机部署资源不足,GPU/CPU 压力飙升;
- 上游请求突增,后端模型服务被打垮;
- 缺少限流、排队、熔断机制,导致雪崩;
- 日志、监控、告警不完善,问题难以及时定位。
本文将从架构设计、服务拆分、负载均衡、缓存、限流、异步队列、流式响应、模型部署、Nginx 配置、Docker Compose 配置、应用配置等多个角度,系统介绍一套适用于 DeepSeek 的高并发解决方案,并附上可参考的配置文件。
一、DeepSeek 高并发的核心挑战
在讨论解决方案之前,必须先明确大模型服务和传统 Web 服务的不同之处。
普通 Web 服务一次请求可能几十毫秒到几百毫秒就可以完成,而 DeepSeek 这类大模型请求往往需要几秒甚至几十秒。尤其是长文本生成、复杂推理、多轮对话、代码生成等场景,请求耗时更长。
这会带来几个明显问题。
1. 请求耗时长,连接占用高
假设普通接口平均响应时间是 100ms,那么一个服务实例每秒可以处理较多请求。但如果 DeepSeek 平均响应时间是 10 秒,同样的并发量下,服务连接数会迅速堆积。
例如:
- 每秒进入 100 个请求;
- 每个请求平均耗时 10 秒;
- 那么系统中同时存在的请求大约是 1000 个。
如果没有合理的连接池、线程池、异步处理和限流机制,系统很容易被拖垮。
2. 流式输出导致连接持续占用
很多 DeepSeek 应用会使用流式输出,也就是模型边生成边返回。这样用户体验更好,但也意味着 HTTP 连接会持续保持。
如果同时有大量用户使用流式对话,Nginx、应用服务、模型服务都需要承受大量长连接压力。
3. 模型推理资源昂贵
大模型推理通常依赖 GPU,资源成本远高于普通服务。GPU 显存、计算能力、批处理能力都会影响并发上限。
如果每个请求都直接打到模型推理服务,而且没有排队、批处理、缓存等优化,就会出现 GPU 利用率不稳定、请求排队过长、服务超时等问题。
4. 上游突发流量容易造成雪崩
大模型服务不是无限可扩容的。假如业务入口突然涌入大量请求,如果没有限流机制,所有请求都会压到后端模型服务,最终可能导致:
- 应用线程池打满;
- Nginx 连接耗尽;
- 模型服务崩溃;
- Redis、数据库被拖慢;
- 用户全部请求失败。
因此,高并发架构中必须考虑“保护系统”而不是盲目接收所有请求。
二、整体架构设计
一套较为稳妥的 DeepSeek 高并发架构可以设计为如下结构:
用户 / 前端
|
CDN / WAF
|
Nginx / API Gateway
|
限流层 / 鉴权层
|
业务应用服务集群
|
任务队列 / Redis / Kafka
|
DeepSeek 调用服务 / 推理服务集群
|
模型服务 / 第三方 DeepSeek API / 本地部署模型
如果是企业内部知识库问答,还可能增加:
向量数据库
知识库检索服务
Rerank 服务
Embedding 服务
完整链路可以理解为:
- 用户发起请求;
- 网关进行鉴权、限流、路由;
- 业务应用接收请求,判断是否命中缓存;
- 如果需要模型生成,则进入 DeepSeek 调用层;
- 对高耗时任务进行异步处理或排队;
- 模型服务返回结果;
- 应用服务通过普通响应或 SSE 流式响应返回给用户;
- 日志系统记录请求链路,监控系统采集指标。
三、高并发优化原则
DeepSeek 高并发方案不是单点优化,而是一套组合拳。核心原则包括:
1. 能缓存就缓存
对于完全相同或高度相似的问题,可以使用缓存减少模型调用。例如:
- 常见 FAQ;
- 固定知识库问答;
- 提示词模板生成结果;
- 简短分类任务;
- 用户重复提问。
缓存可以放在 Redis 中,也可以建立语义缓存,即通过 Embedding 判断语义相似问题是否可以复用答案。
2. 能异步就异步
对于不要求立即返回的任务,可以异步处理。例如:
- 长文总结;
- 报告生成;
- 批量文档分析;
- 代码扫描;
- 多文件知识库处理。
用户提交任务后,系统返回任务 ID,前端轮询或通过 WebSocket/SSE 获取结果。
3. 能限流就限流
限流不是为了拒绝用户,而是为了保护系统。常见限流维度包括:
- IP 限流;
- 用户 ID 限流;
- API Key 限流;
- 租户限流;
- 接口级限流;
- 模型级限流。
不同用户等级可以配置不同额度,例如普通用户每分钟 10 次,付费用户每分钟 100 次。
4. 能降级就降级
当 DeepSeek 服务压力过高时,可以考虑:
- 返回缓存答案;
- 使用更小模型;
- 关闭深度推理;
- 限制最大 token;
- 提示用户稍后重试;
- 对低优先级任务延迟执行。
5. 能拆分就拆分
不要把所有逻辑都堆在一个服务里。可以拆分为:
- 用户鉴权服务;
- 对话管理服务;
- Prompt 构建服务;
- 模型调用服务;
- 知识库检索服务;
- 日志分析服务;
- 异步任务服务。
服务拆分之后,可以针对不同模块独立扩容。
四、Nginx 高并发配置
Nginx 通常位于入口层,负责反向代理、连接管理、负载均衡、限流、超时控制等。
下面是一份适用于 DeepSeek 应用的参考配置。
user nginx;
worker_processes auto;
events {
worker_connections 65535;
use epoll;
multi_accept on;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 10000;
client_max_body_size 20m;
client_body_timeout 30s;
client_header_timeout 30s;
proxy_connect_timeout 10s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
gzip on;
gzip_min_length 1k;
gzip_comp_level 5;
gzip_types text/plain application/json text/css application/javascript;
log_format deepseek_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time '
'uct=$upstream_connect_time '
'uht=$upstream_header_time '
'urt=$upstream_response_time';
access_log /var/log/nginx/deepseek_access.log deepseek_log;
error_log /var/log/nginx/deepseek_error.log warn;
limit_req_zone $binary_remote_addr zone=ip_limit:20m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=addr_conn:20m;
upstream deepseek_backend {
least_conn;
server app-1:8080 max_fails=3 fail_timeout=30s;
server app-2:8080 max_fails=3 fail_timeout=30s;
server app-3:8080 max_fails=3 fail_timeout=30s;
keepalive 256;
}
server {
listen 80;
server_name deepseek.example.com;
limit_conn addr_conn 50;
location /api/ {
limit_req zone=ip_limit burst=30 nodelay;
proxy_pass http://deepseek_backend;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection "";
proxy_buffering off;
proxy_cache off;
proxy_connect_timeout 10s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}
location /health {
access_log off;
return 200 "ok";
}
}
}
配置说明
上述配置中,有几个重点:
worker_processes auto:根据 CPU 核心数自动设置工作进程;worker_connections 65535:提高单个 worker 的连接能力;use epoll:Linux 下高性能事件模型;proxy_read_timeout 300s:适配大模型长耗时响应;proxy_buffering off:适合 SSE 流式输出;least_conn:优先把请求转发给连接数较少的后端;limit_req_zone:对 IP 做请求速率限制;limit_conn_zone:限制单个 IP 的并发连接数。
如果你的系统使用 SSE 流式输出,proxy_buffering off 非常重要,否则可能出现后端已经返回内容,但前端迟迟收不到的问题。
五、应用服务线程池配置
对于 Java Spring Boot 应用,可以通过线程池控制并发请求,避免请求无限制进入业务逻辑。
application.yml 示例
server:
port: 8080
tomcat:
threads:
max: 800
min-spare: 50
accept-count: 1000
max-connections: 10000
connection-timeout: 30000
spring:
application:
name: deepseek-chat-service
data:
redis:
host: redis
port: 6379
password: your_password
timeout: 3000ms
lettuce:
pool:
max-active: 200
max-idle: 50
min-idle: 10
max-wait: 3000ms
deepseek:
api:
base-url: https://api.deepseek.com
key: ${DEEPSEEK_API_KEY}
connect-timeout: 10000
read-timeout: 300000
max-connections: 1000
max-connections-per-route: 300
model:
name: deepseek-chat
max-tokens: 4096
temperature: 0.7
rate-limit:
user-per-minute: 30
ip-per-minute: 60
cache:
enabled: true
ttl-seconds: 3600
线程池配置建议
如果使用 Spring Boot,不建议所有模型调用都直接使用 Tomcat 请求线程完成。更好的做法是将模型调用放入独立线程池。
executor:
deepseek:
core-pool-size: 100
max-pool-size: 300
queue-capacity: 2000
keep-alive-seconds: 60
对应的 Java 配置示例:
@Configuration
public class ExecutorConfig {
@Bean("deepseekExecutor")
public ThreadPoolTaskExecutor deepseekExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(100);
executor.setMaxPoolSize(300);
executor.setQueueCapacity(2000);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("deepseek-task-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
这里需要注意,线程池不是越大越好。如果线程数过大,会导致上下文切换增加,反而降低吞吐。线程池大小应该结合机器 CPU、内存、接口平均耗时、第三方 API 限额进行压测后确定。
六、Redis 限流配置与实现思路
高并发场景下,Redis 常用于限流、缓存、会话管理和任务状态保存。
Redis 配置示例
bind 0.0.0.0
port 6379
protected-mode yes
requirepass your_password
tcp-backlog 511
timeout 0
tcp-keepalive 300
databases 16
maxmemory 4gb
maxmemory-policy allkeys-lru
appendonly yes
appendfsync everysec
save 900 1
save 300 10
save 60 10000
io-threads 4
io-threads-do-reads yes
基于 Redis 的用户限流逻辑
可以使用滑动窗口或令牌桶算法。简单实现可以使用固定窗口:
key: rate:user:{userId}:{minute}
value: count
expire: 60 seconds
伪代码如下:
public boolean allowRequest(String userId) {
String key = "rate:user:" + userId + ":" + currentMinute();
Long count = redisTemplate.opsForValue().increment(key);
if (count == 1) {
redisTemplate.expire(key, Duration.ofSeconds(60));
}
return count <= 30;
}
如果需要更平滑的限流,可以使用 Lua 脚本实现令牌桶,避免并发下的非原子问题。
local key = KEYS[1]
local max_tokens = tonumber(ARGV[1])
local refill_rate = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local requested = tonumber(ARGV[4])
local bucket = redis.call("HMGET", key, "tokens", "timestamp")
local tokens = tonumber(bucket[1])
local timestamp = tonumber(bucket[2])
if tokens == nil then
tokens = max_tokens
timestamp = now
end
local delta = math.max(0, now - timestamp)
local filled_tokens = math.min(max_tokens, tokens + delta * refill_rate)
local allowed = filled_tokens >= requested
if allowed then
filled_tokens = filled_tokens - requested
end
redis.call("HMSET", key, "tokens", filled_tokens, "timestamp", now)
redis.call("EXPIRE", key, 60)
if allowed then
return 1
else
return 0
end
七、DeepSeek 调用层优化
模型调用层是系统的核心瓶颈之一。这里需要重点优化。
1. 设置合理的超时时间
大模型接口不能使用普通接口的短超时配置。建议:
- 连接超时:5 到 10 秒;
- 读取超时:120 到 300 秒;
- 流式响应:根据业务设置 300 秒或更高;
- 总体任务超时:建议设置硬上限,避免无限等待。
2. 限制最大输入和输出 Token
很多并发问题来自超长上下文。如果用户输入没有限制,极端情况下一个请求就可能消耗大量资源。
建议配置:
deepseek:
token-limit:
max-input-tokens: 12000
max-output-tokens: 4096
max-history-rounds: 10
对于多轮对话,应定期压缩历史消息,而不是无限追加。
3. Prompt 模板化
Prompt 应该尽可能结构化、模板化,减少无效 token。
例如:
你是一个企业知识库问答助手。
请严格基于给定资料回答问题。
如果资料中没有答案,请回答“根据现有资料无法确定”。
【资料】
{context}
【用户问题】
{question}
不要在每次请求中传入大量重复且无意义的说明。
4. 使用流式输出提升体验
在高并发场景下,流式输出并不一定能减少总资源消耗,但可以显著改善用户体验。用户无需等待完整答案生成完成。
SSE 响应头示例:
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
Nginx 中也需要关闭代理缓冲:
proxy_buffering off;
八、异步任务队列方案
对于耗时较长的任务,建议采用异步队列。典型场景包括:
- 批量生成文章;
- 长文档总结;
- PPT 大纲生成;
- 数据报表分析;
- 大批量客服质检;
- 多文件代码审查。
架构如下:
用户提交任务
|
应用服务写入任务表
|
发送消息到 Kafka / RabbitMQ / Redis Stream
|
Worker 消费任务
|
调用 DeepSeek
|
结果写入数据库 / Redis
|
用户查询任务结果
Docker Compose 中 RabbitMQ 配置
rabbitmq:
image: rabbitmq:3.13-management
container_name: rabbitmq
ports:
- "5672:5672"
- "15672:15672"
environment:
RABBITMQ_DEFAULT_USER: admin
RABBITMQ_DEFAULT_PASS: admin_password
volumes:
- rabbitmq_data:/var/lib/rabbitmq
networks:
- deepseek-net
队列消费配置示例
mq:
deepseek:
queue-name: deepseek.task.queue
exchange-name: deepseek.task.exchange
routing-key: deepseek.task
concurrent-consumers: 20
max-concurrent-consumers: 100
prefetch-count: 5
这里的 prefetch-count 不宜设置过大,否则单个消费者可能一次拿走大量任务,导致任务分布不均。
九、缓存策略设计
缓存是降低 DeepSeek 调用成本和提升并发能力的重要手段。
1. 精确缓存
对于完全相同的问题,可以直接缓存。
缓存 Key 示例:
deepseek:answer:{model}:{promptHash}
其中 promptHash 可以由用户问题、系统 Prompt、知识库上下文等内容计算得到。
2. 语义缓存
对于相似问题,可以使用 Embedding 进行语义匹配。
例如用户问:
公司年假政策是什么?
另一个用户问:
员工每年可以休几天年假?
两者语义相近,可以命中同一份答案。
语义缓存流程:
- 对用户问题生成向量;
- 到向量数据库中检索相似问题;
- 如果相似度大于阈值,例如 0.92;
- 返回缓存答案;
- 否则调用 DeepSeek 并写入缓存。
3. 缓存注意事项
不是所有内容都适合缓存。例如:
- 涉及用户隐私的数据;
- 强实时数据;
- 个性化推荐;
- 权限敏感内容;
- 金融、医疗、法律等高风险答案。
对于企业知识库,可以将缓存与权限绑定,避免 A 用户看到 B 用户无权限访问的内容。
十、本地部署 DeepSeek 推理服务的配置思路
如果使用本地部署模型,需要重点关注 GPU 资源调度。常见推理框架包括 vLLM、TGI、Ollama、LMDeploy 等。
以 vLLM 为例,配置示例如下:
vllm:
image: vllm/vllm-openai:latest
container_name: deepseek-vllm
runtime: nvidia
environment:
NVIDIA_VISIBLE_DEVICES: all
ports:
- "8000:8000"
volumes:
- /data/models:/models
command:
- python
- -m
- vllm.entrypoints.openai.api_server
- --model
- /models/deepseek
- --host
- 0.0.0.0
- --port
- "8000"
- --tensor-parallel-size
- "2"
- --gpu-memory-utilization
- "0.9"
- --max-model-len
- "32768"
networks:
- deepseek-net
关键参数说明:
--tensor-parallel-size:张量并行数量,需要结合 GPU 数量;--gpu-memory-utilization:GPU 显存利用比例;--max-model-len:最大上下文长度;--model:模型路径。
如果并发较高,可以通过多个 vLLM 实例加负载均衡,但要注意模型加载会占用大量显存,不是简单复制容器就能解决。
十一、Docker Compose 完整示例
下面是一份简化版 Docker Compose 配置,包含 Nginx、应用服务、Redis、RabbitMQ。
version: "3.9"
services:
nginx:
image: nginx:1.25
container_name: deepseek-nginx
ports:
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./logs/nginx:/var/log/nginx
depends_on:
- app-1
- app-2
- app-3
networks:
- deepseek-net
app-1:
image: deepseek-chat-service:latest
container_name: app-1
environment:
SPRING_PROFILES_ACTIVE: prod
DEEPSEEK_API_KEY: your_api_key
ports:
- "8081:8080"
depends_on:
- redis
- rabbitmq
networks:
- deepseek-net
app-2:
image: deepseek-chat-service:latest
container_name: app-2
environment:
SPRING_PROFILES_ACTIVE: prod
DEEPSEEK_API_KEY: your_api_key
ports:
- "8082:8080"
depends_on:
- redis
- rabbitmq
networks:
- deepseek-net
app-3:
image: deepseek-chat-service:latest
container_name: app-3
environment:
SPRING_PROFILES_ACTIVE: prod
DEEPSEEK_API_KEY: your_api_key
ports:
- "8083:8080"
depends_on:
- redis
- rabbitmq
networks:
- deepseek-net
redis:
image: redis:7.2
container_name: deepseek-redis
command: redis-server /etc/redis/redis.conf
ports:
- "6379:6379"
volumes:
- ./redis/redis.conf:/etc/redis/redis.conf
- redis_data:/data
networks:
- deepseek-net
rabbitmq:
image: rabbitmq:3.13-management
container_name: deepseek-rabbitmq
ports:
- "5672:5672"
- "15672:15672"
environment:
RABBITMQ_DEFAULT_USER: admin
RABBITMQ_DEFAULT_PASS: admin_password
volumes:
- rabbitmq_data:/var/lib/rabbitmq
networks:
- deepseek-net
volumes:
redis_data:
rabbitmq_data:
networks:
deepseek-net:
driver: bridge
这份配置适合中小规模生产环境的基础部署。对于更大规模场景,建议迁移到 Kubernetes,通过 HPA、服务发现、滚动发布、资源限制等能力进一步提升稳定性。
十二、Kubernetes 部署建议
如果业务并发量较高,推荐使用 Kubernetes 管理应用服务。
Deployment 示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: deepseek-chat-service
spec:
replicas: 6
selector:
matchLabels:
app: deepseek-chat-service
template:
metadata:
labels:
app: deepseek-chat-service
spec:
containers:
- name: app
image: deepseek-chat-service:latest
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: prod
- name: DEEPSEEK_API_KEY
valueFrom:
secretKeyRef:
name: deepseek-secret
key: api-key
resources:
requests:
cpu: "1"
memory: "2Gi"
limits:
cpu: "4"
memory: "6Gi"
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 60
periodSeconds: 30
HPA 示例
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: deepseek-chat-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: deepseek-chat-service
minReplicas: 6
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 65
需要注意的是,对于大模型应用,仅根据 CPU 扩容并不一定准确。更好的方式是结合:
- 请求排队长度;
- 平均响应时间;
- P95/P99 延迟;
- 模型调用成功率;
- 当前活跃 SSE 连接数;
- Redis 队列长度;
- GPU 利用率。
十三、监控与告警
高并发系统必须有完善的可观测性。否则系统出问题时,只能靠猜。
建议至少监控以下指标:
1. 网关层指标
- QPS;
- 并发连接数;
- 4xx/5xx 错误率;
- Nginx upstream 响应时间;
- 限流次数;
- 请求体大小。
2. 应用层指标
- 接口平均响应时间;
- P95/P99 延迟;
- 线程池活跃线程数;
- 线程池队列长度;
- JVM 内存使用率;
- GC 次数和耗时;
- 请求失败率。
3. 模型调用指标
- DeepSeek 调用次数;
- 成功率;
- 平均耗时;
- 首 token 返回时间;
- 总 token 消耗;
- 输入 token 数;
- 输出 token 数;
- 超时次数;
- 重试次数。
4. 队列指标
- 消息积压数量;
- 消费速度;
- 消费失败数量;
- 重试次数;
- 死信队列数量。
5. GPU 指标
如果是本地部署模型,需要监控:
- GPU 使用率;
- 显存使用率;
- GPU 温度;
- 推理吞吐;
- batch size;
- KV Cache 使用情况。
十四、压测方法
没有压测数据的高并发方案是不完整的。建议分阶段压测:
第一阶段:普通接口压测
验证应用服务基础承载能力,例如健康检查、简单业务接口。
第二阶段:非流式 DeepSeek 压测
模拟真实 prompt,测试模型调用耗时、成功率和系统吞吐。
第三阶段:流式接口压测
重点观察长连接数量、Nginx 连接占用、应用线程池状态。
第四阶段:突发流量压测
模拟短时间内请求暴涨,验证限流、熔断、排队是否有效。
第五阶段:长时间稳定性压测
持续运行 4 到 24 小时,观察内存泄漏、连接泄漏、日志膨胀等问题。
可以使用 wrk、JMeter、k6 等工具。以 k6 为例:
import http from 'k6/http';
import { sleep, check } from 'k6';
export const options = {
vus: 200,
duration: '10m',
};
export default function () {
const payload = JSON.stringify({
messages: [
{ role: "user", content: "请总结一下高并发系统设计的关键点" }
],
stream: false
});
const params = {
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer test-token'
},
timeout: '300s'
};
const res = http.post('http://deepseek.example.com/api/chat', payload, params);
check(res, {
'status is 200': r => r.status === 200,
'response time < 30s': r => r.timings.duration < 30000,
});
sleep(1);
}
十五、生产环境最佳实践
最后总结一些生产环境中非常重要的实践经验。
1. 不要让用户请求无限等待
大模型生成时间不可控,必须设置超时。如果超过业务可接受时间,应返回提示:
当前请求处理时间较长,请稍后重试或查看任务结果。
2. 给不同模型设置不同并发池
如果系统同时使用 deepseek-chat、deepseek-reasoner 或本地多个模型,不建议共用同一个线程池和限流策略。推理模型通常耗时更长,应单独控制并发。
3. 限制上下文轮数
多轮对话不要无限携带历史记录。可以设置:
- 最近 10 轮完整保留;
- 更早内容进行摘要;
- 超过 token 限制自动裁剪。
4. 建立失败重试机制
对于网络抖动,可以进行有限重试。但重试必须谨慎,避免在高峰期放大流量。
建议:
- 最多重试 1 到 2 次;
- 使用指数退避;
- 对超时请求不盲目重试;
- 对流式请求谨慎重试。
5. 使用熔断保护模型服务
当模型服务错误率过高或延迟过高时,可以临时熔断,避免所有请求继续打到异常服务。
熔断期间可以返回:
- 缓存答案;
- 降级模型结果;
- 稍后重试提示;
- 异步任务 ID。
6. 记录完整链路日志
每次请求建议记录:
- requestId;
- userId;
- model;
- prompt token;
- completion token;
- latency;
- status;
- error code;
- 是否命中缓存;
- 是否触发限流;
- 是否走异步队列。
这样才能定位问题、分析成本、优化系统。
十六、推荐容量规划方式
容量规划不能只看 QPS,还要看平均耗时。
可以使用一个简单公式估算:
并发请求数 ≈ QPS × 平均响应时间
例如:
- QPS = 50;
- 平均响应时间 = 8 秒;
- 那么同时在处理的请求约为 400。
如果是 SSE 流式响应,连接保持时间可能更长,比如 20 秒:
并发连接数 ≈ 50 × 20 = 1000
这意味着 Nginx、应用服务、线程池、连接池都要支撑至少 1000 个活跃连接。
此外,还要根据 token 消耗估算模型吞吐:
总输出 token/s = QPS × 平均输出 token
如果每个请求平均输出 800 token,QPS 为 20,则每秒输出需求约为:
20 × 800 = 16000 token/s
这对于本地推理服务是非常关键的容量指标。
十七、最终推荐方案
对于大多数 DeepSeek 应用,推荐采用以下组合方案:
Nginx 网关限流
+ 应用服务集群横向扩展
+ Redis 缓存与用户限流
+ 独立 DeepSeek 调用线程池
+ 长任务异步队列
+ SSE 流式响应
+ 熔断降级机制
+ 完整监控告警
如果并发量较小,可以从 Docker Compose 起步;如果并发量较大,建议迁移到 Kubernetes;如果对数据安全、成本和响应速度有更高要求,可以考虑本地部署模型推理服务。
结语
DeepSeek 高并发解决方案的关键不在于某一个配置参数,而在于整体架构的稳定性设计。大模型服务天然具有高耗时、高资源消耗、长连接、成本敏感等特点,因此不能简单按照传统 Web 接口的方式处理。
真正可靠的方案应该同时具备:
- 入口限流能力;
- 请求排队能力;
- 缓存复用能力;
- 异步处理能力;
- 模型调用保护能力;
- 服务横向扩展能力;
- 实时监控和告警能力;
- 故障降级与恢复能力。
只有这样,DeepSeek 才能从“可以调用”走向“稳定可用”,从单用户体验走向大规模生产落地。