Files

1 line
35 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"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<div align=\"center\">\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</div>\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 <PID>\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<div align=\"center\">\n\n**如果这个项目对你有帮助,请给个 ⭐ Star!**\n\n[⬆ 回到顶部](#cil-router---极简版-claude-api-转发器)\n\n</div>\n"}}}}