mirror of
https://github.com/linshenkx/prompt-optimizer.git
synced 2026-06-15 18:06:21 +08:00
- 新增 122-docker-api-proxy 目录,包含项目概述、技术实现、开发经验等文档- 详细介绍了 Docker 环境下的 API 代理解决方案,包括架构设计、关键技术要点、实施步骤等 - 提供了完整的开发经验和最佳实践总结,为类似项目提供了参考 - 更新了档案总表,增加了 122号项目的记录 - 移除了旧的架构对比和关键修复文档,精简了工作空间资料
232 lines
6.6 KiB
Markdown
232 lines
6.6 KiB
Markdown
# 技术实现详解
|
||
|
||
## 🔧 架构设计
|
||
|
||
### 整体架构
|
||
```
|
||
前端应用 → nginx (80) → Node Proxy (3001) → 外部LLM API
|
||
```
|
||
|
||
### 设计理念
|
||
基于**Docker受信环境**假设,采用**简化优先**的设计原则:
|
||
- 重点关注功能实现而非复杂安全防护
|
||
- 避免nginx动态代理的复杂性
|
||
- 零依赖实现,提高可维护性
|
||
|
||
### 架构优势
|
||
- ✅ 避免nginx动态代理的DNS解析问题
|
||
- ✅ 配置简单,易于维护
|
||
- ✅ 适合Docker容器的受信环境
|
||
- ✅ 职责清晰:nginx负责转发,Node.js负责代理逻辑
|
||
|
||
## 🐛 问题诊断与解决
|
||
|
||
### 核心技术挑战
|
||
|
||
#### 1. nginx动态代理复杂性
|
||
**问题**:nginx动态代理需要复杂的DNS解析和变量处理
|
||
**解决方案**:采用nginx本地转发 + Node.js代理的简化架构
|
||
```nginx
|
||
location /api/proxy {
|
||
proxy_pass http://127.0.0.1:3001;
|
||
proxy_http_version 1.1;
|
||
}
|
||
```
|
||
|
||
#### 2. 流式响应透传
|
||
**问题**:SSE流式响应需要实时透传,不能缓冲
|
||
**解决方案**:
|
||
- nginx配置:`proxy_buffering off`、`X-Accel-Buffering no`
|
||
- Node.js实现:使用`Readable.fromWeb()`正确处理流
|
||
|
||
#### 3. CORS头重复设置
|
||
**问题**:nginx和Node.js同时设置CORS头导致重复
|
||
**解决方案**:统一由Node.js处理CORS,nginx不设置
|
||
|
||
#### 4. 超时策略优化
|
||
**问题**:LLM流式请求可能需要很长时间,统一超时不合理
|
||
**解决方案**:差异化超时策略
|
||
- 流式请求:5分钟超时
|
||
- 普通请求:2分钟超时
|
||
- 支持环境变量配置
|
||
|
||
## 📝 实施步骤
|
||
|
||
### 阶段1:基础代理功能实现
|
||
1. **创建Node.js代理服务**
|
||
- 零依赖实现,只使用内置模块
|
||
- 支持所有HTTP方法
|
||
- 基础错误处理
|
||
|
||
2. **配置nginx转发**
|
||
- 添加`/api/proxy`和`/api/stream`路径
|
||
- 本地转发到127.0.0.1:3001
|
||
- 基础CORS配置
|
||
|
||
3. **Docker集成**
|
||
- 修改supervisord.conf添加node-proxy进程
|
||
- 环境变量配置支持
|
||
|
||
### 阶段2:流式代理和UI集成
|
||
1. **流式响应优化**
|
||
- nginx流式配置优化
|
||
- Node.js使用`Readable.fromWeb()`处理流
|
||
- 流式超时策略
|
||
|
||
2. **前端UI集成**
|
||
- 环境检测逻辑
|
||
- ModelManager.vue添加Docker代理选项
|
||
- 国际化文本支持
|
||
|
||
3. **数据持久化**
|
||
- ModelConfig接口添加useDockerProxy
|
||
- 配置保存和加载逻辑
|
||
|
||
### 阶段3:错误处理与体验优化
|
||
1. **增强错误处理**
|
||
- 智能错误分类:超时504、连接错误502、格式错误400
|
||
- 用户友好错误消息
|
||
- 请求追踪系统
|
||
|
||
2. **LLM服务集成**
|
||
- OpenAI服务添加Docker代理支持
|
||
- Gemini服务添加Docker代理支持
|
||
- 类型定义完善
|
||
|
||
3. **端到端验证**
|
||
- 功能测试:基础代理、错误处理、流式响应
|
||
- 性能测试:响应时间、内存使用、并发处理
|
||
- 集成测试:前端UI、LLM服务、构建系统
|
||
|
||
## 🔍 调试过程
|
||
|
||
### 调试工具组合
|
||
- **Nginx access_log**:记录/api/*专用日志
|
||
- **Node Proxy日志**:详细的请求处理日志
|
||
- **浏览器网络面板**:前端请求状态检查
|
||
|
||
### 关键调试点
|
||
1. **CORS问题**:确保只有Node.js设置CORS头
|
||
2. **流式响应**:检查nginx缓冲配置和Node.js流处理
|
||
3. **超时处理**:验证不同类型请求的超时策略
|
||
4. **错误分类**:确保错误码和消息的正确性
|
||
|
||
## 🧪 测试验证
|
||
|
||
### 功能测试用例
|
||
```javascript
|
||
// 基础代理测试
|
||
GET /api/proxy?url=https://httpbin.org/get
|
||
期望:200状态码,正确的JSON响应
|
||
|
||
// 错误处理测试
|
||
GET /api/proxy?url=https://nonexistent-domain.com
|
||
期望:502状态码,友好错误消息
|
||
|
||
// 流式响应测试
|
||
GET /api/stream?url=https://httpbin.org/stream/5
|
||
期望:实时流式数据,无缓冲延迟
|
||
```
|
||
|
||
### 性能测试指标
|
||
- **响应时间**:6-7秒(httpbin.org正常延迟)
|
||
- **内存使用**:稳定,无内存泄漏
|
||
- **并发处理**:支持多个同时请求
|
||
- **资源清理**:定时器正确清理
|
||
|
||
### 集成测试验证
|
||
- **前端UI**:代理选项正确显示和保存
|
||
- **LLM服务**:Docker代理配置正确传递
|
||
- **构建系统**:Core和UI包构建成功
|
||
- **类型检查**:TypeScript检查通过
|
||
|
||
## 🔧 核心代码实现
|
||
|
||
### Node.js代理服务核心逻辑
|
||
```javascript
|
||
// 零依赖实现,只使用内置模块
|
||
const http = require('http');
|
||
const { Readable } = require('stream');
|
||
|
||
// 流式响应处理
|
||
if (upstreamRes.headers['content-type']?.includes('text/event-stream')) {
|
||
const stream = Readable.fromWeb(upstreamRes.body);
|
||
stream.pipe(res);
|
||
}
|
||
|
||
// 智能错误处理
|
||
const handleError = (error, res, requestId) => {
|
||
if (error.code === 'ENOTFOUND') {
|
||
return sendError(res, 502, 'DNS resolution failed', requestId);
|
||
}
|
||
if (error.code === 'ECONNREFUSED') {
|
||
return sendError(res, 502, 'Connection refused', requestId);
|
||
}
|
||
return sendError(res, 500, 'Internal server error', requestId);
|
||
};
|
||
```
|
||
|
||
### nginx配置核心部分
|
||
```nginx
|
||
# 基础代理配置
|
||
location /api/proxy {
|
||
proxy_pass http://127.0.0.1:3001;
|
||
proxy_http_version 1.1;
|
||
}
|
||
|
||
# 流式响应配置
|
||
location /api/stream {
|
||
proxy_pass http://127.0.0.1:3001;
|
||
proxy_buffering off;
|
||
proxy_request_buffering off;
|
||
add_header X-Accel-Buffering no always;
|
||
}
|
||
```
|
||
|
||
### 前端环境检测
|
||
```typescript
|
||
export const checkDockerApiAvailability = async (): Promise<boolean> => {
|
||
try {
|
||
const response = await fetch('/api/docker-status');
|
||
return response.ok;
|
||
} catch {
|
||
return false;
|
||
}
|
||
};
|
||
```
|
||
|
||
## 📊 性能优化
|
||
|
||
### 关键优化点
|
||
1. **流式透传**:nginx关闭缓冲,Node.js使用`Readable.fromWeb()`
|
||
2. **超时策略**:差异化超时,流式5分钟,普通2分钟
|
||
3. **错误处理**:快速失败,避免长时间等待
|
||
4. **资源清理**:及时清理定时器和连接
|
||
|
||
### 监控指标
|
||
- **请求追踪**:唯一请求ID
|
||
- **性能日志**:响应时间、状态码、错误率
|
||
- **资源使用**:内存、CPU、连接数
|
||
|
||
## 🔒 安全考虑
|
||
|
||
### 当前安全措施
|
||
- **受信环境假设**:基于Docker容器的受信环境
|
||
- **基础CORS配置**:允许跨域访问
|
||
- **错误信息过滤**:避免泄露敏感信息
|
||
|
||
### 可选安全增强
|
||
- **URL白名单**:限制可访问的目标域名
|
||
- **请求频率限制**:防止滥用
|
||
- **请求大小限制**:防止大文件攻击
|
||
|
||
## 🎯 技术亮点
|
||
|
||
1. **零依赖实现**:提高安全性和可维护性
|
||
2. **架构简洁**:避免复杂的nginx动态代理配置
|
||
3. **流式透传**:正确处理SSE流式响应
|
||
4. **智能错误处理**:用户友好的错误分类和消息
|
||
5. **完整集成**:前端UI、LLM服务、类型定义全面支持
|
||
|
||
这个实现为Docker部署环境提供了完整、可靠、易维护的API代理解决方案。
|