{"repo": "alencryenfo/cilrouter", "files": {"README.md": {"2ed6e45fcdfa40614f50a7785cd45f4d18454715": {"t": 1785674409.005228, "n": 25791, "h": "1c28a5349a3ae7c0", "c": "# 如果需要二次开发请Fork Production分支,当前分支存在较大问题且作者最近时间较紧未维护,Bug较多\n\n\n# CIL Router - 极简版 Claude Code API 转发器\n\n
\n\n![License](https://img.shields.io/badge/license-MIT-blue.svg)\n![Python](https://img.shields.io/badge/python-3.10+-blue.svg)\n![Version](https://img.shields.io/badge/version-1.0.2-green.svg)\n![Docker](https://img.shields.io/badge/docker-ready-blue.svg)\n![FastAPI](https://img.shields.io/badge/FastAPI-framework-green.svg)\n![Tests](https://img.shields.io/badge/tests-100%25%20pass-brightgreen.svg)\n\n**极简的 Claude Code API 转发器,专为替换 API Key 和透明转发设计**\n\n[功能特性](#功能特性) • [快速开始](#快速开始) • [部署方式](#部署方式) • [API 文档](#api-文档) • [配置说明](#配置说明)\n\n[English](README_EN.md) | 简体中文\n\n
\n\n> 警告:使用本项目必须符合当地相关法规,其一切使用后果由用户自行承担\n> \n> 本项目为个人使用构建开源~~水平菜菜~~,且大量AI编码,使用后果自负,欢迎PR增加功能\n\n---\n\n## 📋 目录\n\n- [功能特性](#功能特性)\n- [快速开始](#快速开始)\n- [部署方式](#部署方式)\n - [本地部署](#本地部署)\n - [Docker 部署](#docker-部署)\n - [Docker Compose 部署](#docker-compose-部署推荐)\n- [配置说明](#配置说明)\n - [环境变量配置](#环境变量配置)\n - [代码配置](#代码配置)\n- [API 文档](#api-文档)\n - [基础接口](#基础接口)\n - [转发接口](#转发接口)\n - [使用示例](#使用示例)\n- [高级功能](#高级功能)\n - [流式请求支持](#流式请求支持)\n - [鉴权功能](#鉴权功能)\n - [健康检查](#健康检查)\n- [故障排除](#故障排除)\n- [开发指南](#开发指南)\n- [许可证](#许可证)\n\n---\n\n## 🚀 功能特性\n\n### 核心功能\n- 🌐 **全HTTP方法支持** - 支持所有HTTP方法(GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, TRACE)\n- 🎯 **完全透明转发** - 完整转发所有请求内容(URL参数、请求头、请求体)\n- 🔑 **智能API Key处理** - 自动检测并替换Authorization头部,没有则添加\n- 🌊 **流式请求支持** - 自动检测并正确处理流式响应(如Claude的stream模式)\n- 🔄 **手动切换供应商** - 通过 `/select` 接口实时切换API供应商\n- ⚖️ **负载均衡** - 同供应商内多个端点自动轮询负载均衡\n- 🔁 **失败重试** - 端点失败时自动重试其他端点\n- 🛡️ **智能限流** - 基于令牌桶算法的IP限流,支持突发流量\n- 🌏 **Cloudflare支持** - 完整的CDN代理支持,准确获取真实客户端IP\n- 🚫 **IP阻止功能** - 支持动态IP黑名单,自动重载阻止列表\n- 📝 **完整日志记录** - 结构化日志,支持请求追踪和性能监控\n- 🚀 **零配置启动** - 只需配置供应商的 `base_url` 和 `api_key`\n- 📦 **轻量级设计** - 只有 3 个核心依赖包,代码极简\n\n### 技术特点\n- ⚡ **高性能** - 基于FastAPI和httpx,支持异步并发\n- 🐳 **容器化就绪** - 完整的Docker支持和健康检查\n- 🔧 **灵活配置** - 支持环境变量和代码两种配置方式\n- 🛡️ **安全可靠** - 可选的API密钥鉴权功能\n- 📊 **监控友好** - 内置状态接口和健康检查\n- 🧪 **测试完善** - 100%测试覆盖率,生产级质量保证\n- 🔒 **内存安全** - 优化内存管理,防止泄漏和竞态条件\n\n---\n\n## ⚡ 快速开始\n\n### 方式一:Docker Compose(推荐)\n\n```bash\n# 1. 克隆项目\ngit clone https://github.com/alencryenfo/cilrouter.git\ncd cilrouter\n\n# 2. 配置环境变量\ncp .env.example .env\nvim .env # 编辑配置文件\n\n# 3. 启动服务\ndocker-compose up -d\n\n# 4. 测试服务\ncurl http://localhost:8000/\n```\n\n### 方式二:本地运行\n\n```bash\n# 1. 安装依赖\npip install -r requirements.txt\n\n# 2. 配置供应商(二选一)\n# 方式A:环境变量配置\ncp .env.example .env\nvim .env\n\n# 方式B:代码配置\nvim config/config.py\n\n# 3. 启动服务\npython app/main.py\n```\n\n---\n\n## 🚀 部署方式\n\n### 本地部署\n\n#### 环境要求\n- Python 3.10+\n- pip 包管理器\n\n#### 步骤详解\n\n1. **克隆项目**\n```bash\ngit clone https://github.com/alencryenfo/cilrouter.git\ncd cilrouter\n```\n\n2. **创建虚拟环境(推荐)**\n```bash\npython -m venv .venv\nsource .venv/bin/activate # Linux/Mac\n# 或 .venv\\Scripts\\activate # Windows\n```\n\n3. **安装依赖**\n```bash\npip install -r requirements.txt\n```\n\n4. **配置供应商信息**\n\n**方式A:环境变量配置(推荐)**\n```bash\ncp .env.example .env\n```\n\n编辑 `.env` 文件:\n```bash\n# 供应商配置\nPROVIDER_0_BASE_URL=https://api.anthropic.com\nPROVIDER_0_API_KEY=sk-ant-your-key-1\n\nPROVIDER_1_BASE_URL=https://api.provider2.com\nPROVIDER_1_API_KEY=your-key-2\n\n# 服务器配置\nHOST=0.0.0.0\nPORT=8000\nCURRENT_PROVIDER_INDEX=0\n```\n\n**方式B:代码配置**\n编辑 `config/config.py`:\n```python\nDEFAULT_PROVIDERS = [\n {\n \"base_url\": \"https://api.anthropic.com\",\n \"api_key\": \"sk-ant-your-key-1\"\n },\n {\n \"base_url\": \"https://api.provider2.com\", \n \"api_key\": \"your-key-2\"\n }\n]\n```\n\n5. **启动服务**\n```bash\npython app/main.py\n```\n\n6. **验证安装**\n```bash\ncurl http://localhost:8000/\n```\n\n### Docker 部署\n\n#### 单容器部署\n\n```bash\n# 1. 构建镜像\ndocker build -t cilrouter .\n\n# 2. 运行容器\ndocker run -d \\\n -p 8000:8000 \\\n -e PROVIDER_0_BASE_URL=\"https://api.anthropic.com\" \\\n -e PROVIDER_0_API_KEY=\"sk-ant-your-key\" \\\n -e PROVIDER_1_BASE_URL=\"https://api.provider2.com\" \\\n -e PROVIDER_1_API_KEY=\"your-key-2\" \\\n -e CURRENT_PROVIDER_INDEX=\"0\" \\\n --name cilrouter \\\n --restart unless-stopped \\\n cilrouter\n\n# 3. 查看日志\ndocker logs cilrouter\n\n# 4. 测试服务\ncurl http://localhost:8000/\n```\n\n### Docker Compose 部署(推荐)\n\n#### 标准部署\n\n```bash\n# 1. 准备配置文件\ncp .env.example .env\n\n# 2. 编辑环境变量\nvim .env\n```\n\n`.env` 文件示例:\n```bash\n# 服务器配置\nHOST=0.0.0.0\nPORT=8000\n\n# 当前供应商索引\nCURRENT_PROVIDER_INDEX=0\n\n# 超时配置\nREQUEST_TIMEOUT=60\nSTREAM_TIMEOUT=120\n\n# 鉴权配置(可选)\nAUTH_KEY=your-secret-auth-key\n\n# 供应商配置\nPROVIDER_0_BASE_URL=https://api.anthropic.com\nPROVIDER_0_API_KEY=sk-ant-your-key-1\n\nPROVIDER_1_BASE_URL=https://api.provider2.com\nPROVIDER_1_API_KEY=your-key-2\n\nPROVIDER_2_BASE_URL=https://api.provider3.com\nPROVIDER_2_API_KEY=your-key-3\n```\n\n```bash\n# 3. 启动服务\ndocker-compose up -d\n\n# 4. 查看状态\ndocker-compose ps\ndocker-compose logs -f\n\n# 5. 停止服务\ndocker-compose down\n```\n\n#### 生产环境部署\n\n```yaml\n# docker-compose.prod.yml\nversion: '3.8'\n\nservices:\n cilrouter:\n build: .\n ports:\n - \"80:8000\"\n env_file:\n - .env.prod\n restart: always\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8000/\"]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 10s\n deploy:\n resources:\n limits:\n memory: 512M\n reservations:\n memory: 256M\n```\n\n```bash\n# 生产环境启动\ndocker-compose -f docker-compose.prod.yml up -d\n```\n\n---\n\n## ⚙️ 配置说明\n\n### 环境变量配置\n\n#### 服务器配置\n| 变量名 | 默认值 | 说明 |\n|--------|--------|------|\n| `HOST` | `0.0.0.0` | 服务监听地址 |\n| `PORT` | `8000` | 服务端口 |\n| `CURRENT_PROVIDER_INDEX` | `0` | 当前使用的供应商索引 |\n\n#### 超时配置\n| 变量名 | 默认值 | 说明 |\n|--------|--------|------|\n| `REQUEST_TIMEOUT` | `60` | 普通请求超时(秒) |\n| `STREAM_TIMEOUT` | `120` | 流式请求超时(秒) |\n\n#### 鉴权配置\n| 变量名 | 默认值 | 说明 |\n|--------|--------|------|\n| `AUTH_KEY` | `` | API访问密钥(可选) |\n\n#### 供应商配置\n供应商配置使用 `PROVIDER_N_*` 格式,支持多端点负载均衡:\n\n```bash\n# 供应商 0 - 单个端点\nPROVIDER_0_BASE_URL=https://api.anthropic.com\nPROVIDER_0_API_KEY=sk-ant-your-key-1\n\n# 供应商 1 - 多个端点(逗号分隔,实现负载均衡)\nPROVIDER_1_BASE_URL=https://api.provider2.com,https://api2.provider2.com,https://backup.provider2.com\nPROVIDER_1_API_KEY=your-key-2a,your-key-2b,your-key-2c\n\n# 供应商 2 - 两个端点\nPROVIDER_2_BASE_URL=https://api.provider3.com,https://api-backup.provider3.com\nPROVIDER_2_API_KEY=your-key-3a,your-key-3b\n\n# 可以继续添加更多供应商...\n```\n\n#### 限流配置\n| 变量名 | 默认值 | 说明 |\n|--------|--------|------|\n| `RATE_LIMIT_ENABLED` | `false` | 是否启用限流功能 |\n| `RATE_LIMIT_RPM` | `100` | 每分钟允许的请求数 |\n| `RATE_LIMIT_BURST` | `10` | 突发容量(允许短时间内超过平均速率的请求数) |\n| `RATE_LIMIT_TRUST_PROXY` | `true` | 是否信任代理头部获取真实IP(适用于Cloudflare等CDN) |\n\n**注意事项:**\n- 索引必须从 0 开始且连续,不能有间断\n- 每个供应商都需要同时配置 `BASE_URL` 和 `API_KEY`\n- 如果某个索引缺失,后续的供应商将被忽略\n\n### 代码配置\n\n如果不使用环境变量,可以直接修改 `config/config.py` 文件:\n\n```python\n# config/config.py\nDEFAULT_PROVIDERS = [\n {\n \"base_url\": \"https://api.anthropic.com\",\n \"api_key\": \"sk-ant-your-key-1\" # 在这里填入你的 API Key\n },\n {\n \"base_url\": \"https://api.provider2.com\", \n \"api_key\": \"your-key-2\" # 第二个供应商的 API Key\n },\n {\n \"base_url\": \"https://api.provider3.com\",\n \"api_key\": \"your-key-3\" # 第三个供应商的 API Key\n }\n]\n```\n\n### 配置优先级\n\n配置加载优先级如下:\n1. **环境变量** - 最高优先级\n2. **代码配置** - 当环境变量不存在时使用\n\n---\n\n## 📚 API 文档\n\n### 基础接口\n\n#### 1. 状态查询\n\n```http\nGET /\n```\n\n**响应示例:**\n```json\n{\n \"app\": \"CIL Router\",\n \"version\": \"1.0.1\",\n \"current_provider_index\": 0,\n \"total_providers\": 3,\n \"current_provider_endpoints\": 1,\n \"current_provider_urls\": [\"https://api.anthropic.com\"],\n \"load_balancing\": \"round_robin\"\n}\n```\n\n#### 2. 供应商切换\n\n```http\nPOST /select\nContent-Type: text/plain\n\n0\n```\n\n**请求参数:**\n- Body: 供应商索引(数字字符串,如 `\"0\"`, `\"1\"`, `\"2\"`)\n\n**成功响应:**\n```json\n{\n \"success\": true,\n \"message\": \"已切换到供应商 1\",\n \"current_index\": 1,\n \"total_providers\": 3\n}\n```\n\n**错误响应:**\n```json\n{\n \"success\": false,\n \"message\": \"无效的供应商索引: 5. 有效范围: 0-2\",\n \"current_index\": 0,\n \"total_providers\": 3\n}\n```\n\n### 转发接口\n\n#### 通用转发规则\n\n所有非 `/` 和 `/select` 的路径都会被转发到当前供应商。\n\n**转发过程:**\n1. 保留原始请求的所有内容(路径、参数、头部、请求体)\n2. 替换 `Authorization` 头部为当前供应商的 API Key\n3. 转发到当前供应商的 `base_url`\n4. 返回供应商的完整响应\n\n#### 支持的HTTP方法\n\n- ✅ GET - 查询请求\n- ✅ POST - 创建请求 \n- ✅ PUT - 更新请求\n- ✅ DELETE - 删除请求\n- ✅ PATCH - 部分更新请求\n- ✅ HEAD - 头部请求\n- ✅ OPTIONS - 选项请求\n- ✅ TRACE - 跟踪请求\n\n### 使用示例\n\n#### 基础使用\n\n```bash\n# 1. 查看当前状态\ncurl http://localhost:8000/\n\n# 2. 切换到供应商 1\ncurl -X POST http://localhost:8000/select -d \"1\"\n\n# 3. 发送 Claude API 请求\ncurl -X POST http://localhost:8000/v1/messages \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"model\": \"claude-3-5-sonnet-20241022\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}],\n \"max_tokens\": 1024\n }'\n```\n\n#### Claude API 转发示例\n\n**普通聊天请求:**\n```bash\ncurl -X POST http://localhost:8000/v1/messages \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"model\": \"claude-3-5-sonnet-20241022\",\n \"messages\": [\n {\"role\": \"user\", \"content\": \"请介绍一下人工智能\"}\n ],\n \"max_tokens\": 1024\n }'\n```\n\n**流式聊天请求:**\n```bash\ncurl -X POST http://localhost:8000/v1/messages \\\n -H \"Content-Type: application/json\" \\\n -H \"Accept: text/event-stream\" \\\n -d '{\n \"model\": \"claude-3-5-sonnet-20241022\",\n \"messages\": [\n {\"role\": \"user\", \"content\": \"请写一首诗\"}\n ],\n \"max_tokens\": 1024,\n \"stream\": true\n }'\n```\n\n**获取模型列表:**\n```bash\ncurl -X GET http://localhost:8000/v1/models\n```\n\n**带参数的请求:**\n```bash\ncurl -X GET \"http://localhost:8000/v1/messages/limit?count=10&offset=0\"\n```\n\n#### 多供应商使用\n\n```bash\n# 场景:在多个API供应商之间切换使用\n\n# 1. 使用供应商 0(Anthropic官方)\ncurl -X POST http://localhost:8000/select -d \"0\"\ncurl -X POST http://localhost:8000/v1/messages \\\n -H \"Content-Type: application/json\" \\\n -d '{\"model\": \"claude-3-5-sonnet-20241022\", \"messages\": [{\"role\": \"user\", \"content\": \"Hello from provider 0\"}], \"max_tokens\": 100}'\n\n# 2. 切换到供应商 1(第三方API)\ncurl -X POST http://localhost:8000/select -d \"1\" \ncurl -X POST http://localhost:8000/v1/messages \\\n -H \"Content-Type: application/json\" \\\n -d '{\"model\": \"claude-3-5-sonnet-20241022\", \"messages\": [{\"role\": \"user\", \"content\": \"Hello from provider 1\"}], \"max_tokens\": 100}'\n\n# 3. 切换到供应商 2(备用API)\ncurl -X POST http://localhost:8000/select -d \"2\"\ncurl -X POST http://localhost:8000/v1/messages \\\n -H \"Content-Type: application/json\" \\\n -d '{\"model\": \"claude-3-5-sonnet-20241022\", \"messages\": [{\"role\": \"user\", \"content\": \"Hello from provider 2\"}], \"max_tokens\": 100}'\n```\n\n#### 客户端集成示例\n\n**Python 示例:**\n```python\nimport requests\nimport json\n\nclass CILRouterClient:\n def __init__(self, base_url=\"http://localhost:8000\"):\n self.base_url = base_url\n \n def select_provider(self, index):\n \"\"\"切换供应商\"\"\"\n response = requests.post(f\"{self.base_url}/select\", data=str(index))\n return response.json()\n \n def chat(self, messages, model=\"claude-3-5-sonnet-20241022\", stream=False):\n \"\"\"发送聊天请求\"\"\"\n payload = {\n \"model\": model,\n \"messages\": messages,\n \"max_tokens\": 1024,\n \"stream\": stream\n }\n \n headers = {\"Content-Type\": \"application/json\"}\n if stream:\n headers[\"Accept\"] = \"text/event-stream\"\n \n response = requests.post(\n f\"{self.base_url}/v1/messages\",\n headers=headers,\n json=payload,\n stream=stream\n )\n \n if stream:\n return response.iter_lines()\n else:\n return response.json()\n\n# 使用示例\nclient = CILRouterClient()\n\n# 切换到供应商 1\nclient.select_provider(1)\n\n# 发送聊天请求\nmessages = [{\"role\": \"user\", \"content\": \"Hello, Claude!\"}]\nresponse = client.chat(messages)\nprint(response)\n```\n\n**JavaScript 示例:**\n```javascript\nclass CILRouterClient {\n constructor(baseUrl = 'http://localhost:8000') {\n this.baseUrl = baseUrl;\n }\n \n async selectProvider(index) {\n const response = await fetch(`${this.baseUrl}/select`, {\n method: 'POST',\n body: index.toString()\n });\n return await response.json();\n }\n \n async chat(messages, model = 'claude-3-5-sonnet-20241022', stream = false) {\n const payload = {\n model,\n messages,\n max_tokens: 1024,\n stream\n };\n \n const headers = {\n 'Content-Type': 'application/json'\n };\n \n if (stream) {\n headers['Accept'] = 'text/event-stream';\n }\n \n const response = await fetch(`${this.baseUrl}/v1/messages`, {\n method: 'POST',\n headers,\n body: JSON.stringify(payload)\n });\n \n if (stream) {\n return response.body.getReader();\n } else {\n return await response.json();\n }\n }\n}\n\n// 使用示例\nconst client = new CILRouterClient();\n\n// 切换供应商并发送请求\nawait client.selectProvider(0);\nconst response = await client.chat([\n { role: 'user', content: 'Hello, Claude!' }\n]);\nconsole.log(response);\n```\n\n---\n\n## 🔧 高级功能\n\n### 流式请求支持\n\nCIL Router 自动检测并处理流式请求,无需额外配置。\n\n#### 流式检测机制\n\n系统通过以下方式检测流式请求:\n1. **Accept头部检测** - `Accept: text/event-stream`\n2. **请求体检测** - 请求体中包含 `\"stream\": true`\n\n#### 流式请求示例\n\n```bash\n# 方式1:通过Accept头部\ncurl -X POST http://localhost:8000/v1/messages \\\n -H \"Content-Type: application/json\" \\\n -H \"Accept: text/event-stream\" \\\n -d '{\n \"model\": \"claude-3-5-sonnet-20241022\",\n \"messages\": [{\"role\": \"user\", \"content\": \"写一首诗\"}],\n \"max_tokens\": 1024\n }'\n\n# 方式2:通过请求体参数\ncurl -X POST http://localhost:8000/v1/messages \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"model\": \"claude-3-5-sonnet-20241022\", \n \"messages\": [{\"role\": \"user\", \"content\": \"写一首诗\"}],\n \"max_tokens\": 1024,\n \"stream\": true\n }'\n```\n\n#### 流式响应处理\n\n```python\nimport requests\n\ndef handle_stream_response():\n response = requests.post(\n \"http://localhost:8000/v1/messages\",\n headers={\n \"Content-Type\": \"application/json\",\n \"Accept\": \"text/event-stream\"\n },\n json={\n \"model\": \"claude-3-5-sonnet-20241022\",\n \"messages\": [{\"role\": \"user\", \"content\": \"写一首诗\"}],\n \"max_tokens\": 1024,\n \"stream\": True\n },\n stream=True\n )\n \n for line in response.iter_lines():\n if line:\n print(line.decode('utf-8'))\n\nhandle_stream_response()\n```\n\n### 鉴权功能\n\nCIL Router 支持可选的API密钥鉴权功能。\n\n#### 启用鉴权\n\n在环境变量中设置 `AUTH_KEY`:\n```bash\nAUTH_KEY=your-secret-auth-key\n```\n\n#### 使用鉴权\n\n当启用鉴权后,所有转发请求(除 `/` 和 `/select`)都需要在Authorization头部提供正确的密钥:\n\n```bash\n# 正确的鉴权请求\ncurl -X POST http://localhost:8000/v1/messages \\\n -H \"Authorization: Bearer your-secret-auth-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"model\": \"claude-3-5-sonnet-20241022\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}],\n \"max_tokens\": 1024\n }'\n\n# 错误的鉴权请求(将返回401错误)\ncurl -X POST http://localhost:8000/v1/messages \\\n -H \"Authorization: Bearer wrong-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"model\": \"claude-3-5-sonnet-20241022\", \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}], \"max_tokens\": 1024}'\n```\n\n#### 鉴权错误响应\n\n```json\n{\n \"detail\": \"Invalid authentication credentials\"\n}\n```\n\n### 健康检查\n\nCIL Router 内置健康检查功能,适用于容器化部署和负载均衡器。\n\n#### 健康检查端点\n\n```bash\n# 基本健康检查\ncurl http://localhost:8000/\n\n# 响应示例\n{\n \"app\": \"CIL Router\",\n \"version\": \"1.0.2\", \n \"current_provider_index\": 0,\n \"total_providers\": 2,\n \"current_provider_endpoints\": 1,\n \"current_provider_urls\": [\"https://api.anthropic.com\"],\n \"load_balancing\": \"round_robin\"\n}\n```\n\n#### Docker健康检查\n\nDocker Compose 配置自动包含健康检查:\n```yaml\nhealthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8000/\"]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 10s\n```\n\n#### Kubernetes健康检查\n\n```yaml\napiVersion: v1\nkind: Pod\nspec:\n containers:\n - name: cilrouter\n image: cilrouter:latest\n livenessProbe:\n httpGet:\n path: /\n port: 8000\n initialDelaySeconds: 10\n periodSeconds: 30\n readinessProbe:\n httpGet:\n path: /\n port: 8000\n initialDelaySeconds: 5\n periodSeconds: 10\n```\n\n### 智能限流功能 ⚡\n\nCIL Router 基于令牌桶算法实现智能限流,支持突发流量处理。\n\n#### 启用限流\n```bash\n# 环境变量配置\nRATE_LIMIT_ENABLED=true\nRATE_LIMIT_RPM=100 # 每分钟100请求\nRATE_LIMIT_BURST=10 # 允许10个突发请求\nRATE_LIMIT_TRUST_PROXY=true # 信任代理头部获取真实IP\n```\n\n#### 限流响应\n触发限流时返回429状态码:\n```json\n{\n \"error\": \"请求频率限制\",\n \"message\": \"来自 192.168.1.100 的请求过于频繁\",\n \"requests_per_minute\": 100,\n \"burst_size\": 10,\n \"current_tokens\": 0,\n \"retry_after\": 60\n}\n```\n\n### IP阻止功能 🚫\n\n支持动态IP黑名单,可在运行时热重载。\n\n#### 启用IP阻止\n```bash\n# 环境变量配置\nIP_BLOCK_ENABLED=true\nBLOCKED_IPS_FILE=app/data/blocked_ips.json\n```\n\n#### 阻止列表格式\n```json\n[\n \"192.168.1.100\",\n \"10.0.0.50\",\n \"2001:db8::1\"\n]\n```\n\n被阻止的IP访问时返回444状态码(Connection Closed Without Response)。\n\n### 完整日志记录 📝\n\n支持结构化日志,便于监控和调试。\n\n#### 启用日志\n```bash\n# 环境变量配置\nLOG_LEVEL=INFO # 日志等级\nLOG_DIR=app/data/log # 日志目录\n```\n\n#### 日志级别\n- `NONE` - 无日志\n- `DEBUG` - 记录所有详细信息\n- `INFO` - 记录一般信息\n- `WARNING` - 记录警告信息\n- `ERROR` - 只记录错误信息\n\n#### 日志示例\n```json\n{\n \"message\": \"请求开始\",\n \"type\": \"request_start\",\n \"method\": \"POST\",\n \"path\": \"/v1/messages\",\n \"client_ip\": \"192.168.1.100\",\n \"timestamp\": \"2025-01-01T12:00:00\"\n}\n```\n\n---\n\n## 🐛 故障排除\n\n### 常见问题\n\n#### 1. 无法启动服务\n\n**问题:** `Address already in use`\n```bash\nERROR: [Errno 98] error while attempting to bind on address ('0.0.0.0', 8000): address already in use\n```\n\n**解决方案:**\n```bash\n# 查找占用端口的进程\nlsof -i :8000\n\n# 杀死占用进程\nkill -9 \n\n# 或者使用不同端口\nPORT=8001 python app/main.py\n```\n\n#### 2. 供应商配置问题\n\n**问题:** 供应商索引无效\n```json\n{\n \"success\": false,\n \"message\": \"无效的供应商索引: 2. 有效范围: 0-1\"\n}\n```\n\n**解决方案:**\n1. 检查环境变量配置是否连续\n2. 确认 `PROVIDER_N_BASE_URL` 和 `PROVIDER_N_API_KEY` 都已设置\n3. 重启服务使配置生效\n\n#### 3. API Key 无效\n\n**问题:** 供应商返回认证错误\n```json\n{\n \"error\": {\n \"type\": \"authentication_error\",\n \"message\": \"Invalid API Key\"\n }\n}\n```\n\n**解决方案:**\n1. 检查 API Key 是否正确\n2. 确认 API Key 格式符合供应商要求\n3. 验证 API Key 是否有足够权限\n\n#### 4. 网络连接问题\n\n**问题:** 连接超时\n```bash\nhttpx.TimeoutException: timeout\n```\n\n**解决方案:**\n1. 检查网络连接\n2. 调整超时配置:\n```bash\nREQUEST_TIMEOUT=120\nSTREAM_TIMEOUT=300\n```\n3. 验证供应商 URL 是否可访问\n\n#### 5. Docker 相关问题\n\n**问题:** Docker 构建失败\n```bash\nError: Could not find config.config module\n```\n\n**解决方案:**\n确保项目结构完整,包含所有必要文件:\n```bash\n# 检查项目结构\nls -la app/ config/\n\n# 重新构建镜像\ndocker build --no-cache -t cilrouter .\n```\n\n### 日志调试\n\n#### 启用详细日志\n\n```bash\n# 设置日志级别\nexport LOG_LEVEL=DEBUG\n\n# 启动服务\npython app/main.py\n```\n\n#### Docker 日志查看\n\n```bash\n# 查看容器日志\ndocker logs cilrouter\n\n# 实时跟踪日志\ndocker logs -f cilrouter\n\n# 查看最近100行日志\ndocker logs --tail 100 cilrouter\n```\n\n#### 请求跟踪\n\n使用curl的详细输出来调试请求:\n```bash\n# 显示详细的请求和响应信息\ncurl -v -X POST http://localhost:8000/v1/messages \\\n -H \"Content-Type: application/json\" \\\n -d '{\"model\": \"claude-3-5-sonnet-20241022\", \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}], \"max_tokens\": 1024}'\n```\n\n### 性能优化\n\n#### 1. 连接池优化\n\n修改 `config/config.py` 添加连接池配置:\n```python\n# 连接池配置\nCONNECTION_POOL_SIZE = 100\nCONNECTION_POOL_MAX_SIZE = 1000\n```\n\n#### 2. 超时优化\n\n根据使用场景调整超时设置:\n```bash\n# 快速响应场景\nREQUEST_TIMEOUT=30\nSTREAM_TIMEOUT=60\n\n# 长时间处理场景 \nREQUEST_TIMEOUT=180\nSTREAM_TIMEOUT=600\n```\n\n#### 3. 资源限制\n\nDocker 部署时设置资源限制:\n```yaml\nservices:\n cilrouter:\n deploy:\n resources:\n limits:\n memory: 512M\n cpus: '0.5'\n reservations:\n memory: 256M\n cpus: '0.25'\n```\n\n---\n\n## 🛠️ 开发指南\n\n### 项目结构\n\n```\nCILRouter/\n├── app/\n│ ├── __init__.py\n│ └── main.py # 主应用文件(FastAPI应用)\n├── config/\n│ ├── __init__.py\n│ └── config.py # 配置管理模块\n├── test_suites/ # 测试套件\n│ ├── unit/ # 单元测试\n│ ├── integration/ # 集成测试\n│ ├── stress/ # 压力测试\n│ ├── security/ # 安全测试\n│ ├── performance/ # 性能测试\n│ └── reports/ # 测试报告\n├── .env.example # 环境变量示例\n├── .gitignore # Git忽略文件\n├── CLAUDE.md # 项目文档(私有)\n├── Dockerfile # Docker构建文件\n├── docker-compose.yml # Docker Compose配置\n├── requirements.txt # Python依赖\n└── README.md # 项目文档\n```\n\n### 本地开发\n\n#### 1. 开发环境设置\n\n```bash\n# 克隆项目\ngit clone https://github.com/alencryenfo/cilrouter.git\ncd cilrouter\n\n# 创建虚拟环境\npython -m venv .venv\nsource .venv/bin/activate\n\n# 安装开发依赖\npip install -r requirements.txt\npip install pytest pytest-asyncio black flake8\n\n# 配置开发环境\ncp .env.example .env\nvim .env\n```\n\n#### 2. 代码风格\n\n项目使用以下代码规范:\n- **Python**: PEP 8 标准\n- **格式化工具**: Black\n- **代码检查**: Flake8\n\n```bash\n# 格式化代码\nblack app/ config/ tests/\n\n# 代码检查\nflake8 app/ config/ tests/\n```\n\n#### 3. 运行测试\n\n```bash\n# 使用测试运行器(推荐)\npython run_tests.py all -v # 运行所有测试\npython run_tests.py quick # 快速测试\npython run_tests.py unit # 单元测试\npython run_tests.py integration # 集成测试\npython run_tests.py stress # 压力测试\npython run_tests.py security # 安全测试\npython run_tests.py report # 生成测试报告\n\n# 或直接使用pytest\npytest test_suites/ -v # 运行所有测试\npytest test_suites/unit/ -v # 运行单元测试\n\n# 生成覆盖率报告\npytest test_suites/ --cov=app --cov=config --cov-report=html\n```\n\n#### 4. 开发服务器\n\n```bash\n# 启动开发服务器(自动重载)\nuvicorn app.main:app --reload --host 0.0.0.0 --port 8000\n\n# 或者直接运行\npython app/main.py\n```\n\n### 扩展开发\n\n#### 1. 添加新功能\n\n在 `app/main.py` 中添加新的路由:\n```python\n@app.get(\"/custom/endpoint\")\nasync def custom_endpoint():\n \"\"\"自定义端点\"\"\"\n return {\"message\": \"Custom functionality\"}\n```\n\n#### 2. 修改配置\n\n在 `config/config.py` 中添加新的配置项:\n```python\n# 新配置项\ncustom_setting: str = os.getenv('CUSTOM_SETTING', 'default_value')\n\ndef get_custom_setting() -> str:\n \"\"\"获取自定义配置\"\"\"\n return custom_setting\n```\n\n#### 3. 添加中间件\n\n```python\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=[\"*\"],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n```\n\n### 测试开发\n\n#### 1. 编写单元测试\n\n```python\n# test_suites/unit/test_custom.py\nimport pytest\nfrom fastapi.testclient import TestClient\nfrom app.main import app\n\nclient = TestClient(app)\n\ndef test_custom_endpoint():\n \"\"\"测试自定义端点\"\"\"\n response = client.get(\"/custom/endpoint\")\n assert response.status_code == 200\n assert response.json()[\"message\"] == \"Custom functionality\"\n```\n\n#### 2. 集成测试\n\n```python\n# test_suites/integration/test_integration.py\nimport pytest\nimport httpx\n\n@pytest.mark.asyncio\nasync def test_full_workflow():\n \"\"\"测试完整工作流程\"\"\"\n base_url = \"http://localhost:8000\"\n \n async with httpx.AsyncClient() as client:\n # 1. 检查状态\n response = await client.get(f\"{base_url}/\")\n assert response.status_code == 200\n \n # 2. 切换供应商\n response = await client.post(f\"{base_url}/select\", data=\"1\")\n assert response.status_code == 200\n \n # 3. 发送请求\n response = await client.post(\n f\"{base_url}/v1/messages\",\n json={\n \"model\": \"claude-3-5-sonnet-20241022\",\n \"messages\": [{\"role\": \"user\", \"content\": \"test\"}],\n \"max_tokens\": 10\n }\n )\n # 注:这个测试需要有效的API密钥\n```\n\n### 部署最佳实践\n\n#### 1. 环境分离\n\n```bash\n# 开发环境\n.env.development\n\n# 测试环境 \n.env.testing\n\n# 生产环境\n.env.production\n```\n\n#### 2. 安全配置\n\n生产环境配置示例:\n```bash\n# .env.production\n\n# 服务器配置\nHOST=127.0.0.1 # 仅本地访问\nPORT=8000\n\n# 启用鉴权\nAUTH_KEY=your-very-secure-secret-key\n\n# 较短的超时时间\nREQUEST_TIMEOUT=30\nSTREAM_TIMEOUT=60\n\n# 供应商配置(从安全的地方获取)\nPROVIDER_0_API_KEY=${SECRET_API_KEY_1}\nPROVIDER_1_API_KEY=${SECRET_API_KEY_2}\n```\n\n#### 3. 监控和日志\n\n```python\n# app/main.py - 添加日志记录\nimport logging\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\n@app.middleware(\"http\")\nasync def log_requests(request: Request, call_next):\n start_time = time.time()\n response = await call_next(request)\n process_time = time.time() - start_time\n \n logger.info(\n f\"{request.method} {request.url.path} - \"\n f\"Status: {response.status_code} - \"\n f\"Time: {process_time:.3f}s\"\n )\n \n return response\n```\n\n---\n\n## 🔒 安全说明\n\n### API Key 安全\n\n1. **环境变量存储** - 始终使用环境变量存储API密钥,never硬编码\n2. **访问控制** - 在生产环境中启用 `AUTH_KEY` 鉴权\n3. **网络隔离** - 考虑在内网环境中部署\n4. **定期轮换** - 定期更换API密钥\n\n### 网络安全\n\n1. **HTTPS代理** - 在生产环境中使用反向代理(如Nginx)提供HTTPS\n2. **防火墙配置** - 限制访问来源IP\n3. **速率限制** - 考虑添加请求频率限制\n\n### 容器安全\n\n1. **非root用户** - 容器内使用非特权用户运行\n2. **最小权限** - 只授予必要的系统权限\n3. **镜像扫描** - 定期扫描基础镜像漏洞\n\n---\n\n## 📝 更新日志\n\n### v1.0.1 (当前版本)\n- ✅ 基于令牌桶算法的智能限流\n- ✅ 支持突发流量处理,允许合理的瞬时高峰\n- ✅ 基于IP的请求频率控制(完整支持IPv4/IPv6)\n- ✅ 完整的Cloudflare代理支持(CF-Connecting-IP, CF-IPCountry等)\n- ✅ 可配置代理信任模式(安全性与实用性平衡)\n- ✅ 中文错误提示信息,用户体验友好\n- ✅ 自动过期bucket清理机制,防止内存泄露\n- ✅ 多端点负载均衡,提高服务可用性\n- ✅ 自动失败重试机制\n- ✅ 环境变量支持逗号分隔的多URL配置\n\n### v1.0.0\n- ✅ 初始版本发布\n- ✅ 支持多供应商配置和切换\n- ✅ 完整的环境变量配置支持\n- ✅ Docker 和 Docker Compose 支持\n- ✅ 流式请求自动检测和处理\n- ✅ 可选的API密钥鉴权功能\n- ✅ 健康检查和监控支持\n- ✅ 完整的文档和测试覆盖\n\n### 计划功能\n- 📊 请求统计和监控面板\n- 🔐 更多鉴权方式支持\n- 🌐 WebSocket 支持 \n- 📈 性能优化和缓存\n\n---\n\n## 🤝 贡献指南\n\n欢迎贡献代码!请遵循以下步骤:\n\n1. Fork 项目\n2. 创建功能分支:`git checkout -b feature/amazing-feature`\n3. 提交更改:`git commit -m 'Add amazing feature'`\n4. 推送到分支:`git push origin feature/amazing-feature`\n5. 创建 Pull Request\n\n### 贡献规范\n\n- 遵循现有代码风格\n- 添加适当的测试\n- 更新文档\n- 确保所有测试通过\n\n---\n\n## 📋 更新日志\n\n### v1.0.2 (当前版本) - 2025-08-12\n\n**🔧 重大bug修复和稳定性提升**\n\n#### 修复的严重问题\n- 🛠️ **内存泄漏修复** - 优化令牌桶清理机制,防止内存无限增长\n- 🔒 **竞态条件修复** - 负载均衡计数器现在线程安全\n- 📤 **请求体处理优化** - 统一预读取机制,避免FastAPI重复读取限制\n- ✅ **配置验证增强** - 增加URL和API Key格式验证,提升配置安全性\n\n#### 稳定性改进\n- 🌊 **流式响应优化** - 统一错误格式,改进流式请求错误处理\n- 🌐 **代理检测增强** - 改进Cloudflare等CDN的真实IP检测逻辑\n- 📝 **异常处理改进** - 优化日志记录和错误传播机制\n- ⚡ **性能优化** - 内存管理和资源清理优化\n\n#### 测试和质量保证\n- 🧪 **100%测试覆盖** - 全面测试验证,确保修复效果\n- 📊 **质量提升** - 代码稳定性和可靠性显著提升\n- 🔍 **问题预防** - 增强错误检测和预防机制\n\n**推荐所有用户立即升级到此版本!**\n\n### v1.0.1\n\n#### 新增功能\n- ✅ 基于令牌桶算法的智能限流\n- ✅ IP阻止功能,支持动态黑名单\n- ✅ 完整的日志记录系统\n- ✅ Cloudflare代理支持\n- ✅ 多端点负载均衡和自动重试\n\n### v1.0.0\n\n#### 初始版本\n- ✅ 基础API转发功能\n- ✅ 多供应商支持\n- ✅ Docker部署支持\n- ✅ 流式请求处理\n\n---\n\n## 📄 许可证\n\n本项目采用 MIT 许可证。详情请参阅 [LICENSE](LICENSE) 文件。\n\n---\n\n## 📞 支持与反馈\n\n- **Issues**: [GitHub Issues](https://github.com/alencryenfo/cilrouter/issues)\n- **讨论**: [GitHub Discussions](https://github.com/alencryenfo/cilrouter/discussions)\n\n---\n\n
\n\n**如果这个项目对你有帮助,请给个 ⭐ Star!**\n\n[⬆ 回到顶部](#cil-router---极简版-claude-api-转发器)\n\n
\n"}}}}