Skip to content

Commit 0b6799d

Browse files
author
Taois
committed
feat: py文件修改
1 parent 85620d5 commit 0b6799d

File tree

5 files changed

+704
-60
lines changed

5 files changed

+704
-60
lines changed

proxy/README.md

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# 代理服务器优化版本
2+
3+
## 🚀 优化内容
4+
5+
### 内存泄漏问题解决
6+
7+
1. **连接池管理**
8+
- 实现了全局HTTP客户端单例,避免重复创建
9+
- 配置连接池限制:最大100个连接,保持20个活跃连接
10+
- 设置连接过期时间:30秒自动清理空闲连接
11+
12+
2. **资源自动释放**
13+
- 自定义`ProxyStreamingResponse`确保流式响应正确关闭
14+
- 实现`stream_response_with_cleanup`自动清理响应资源
15+
- 应用生命周期管理,启动和关闭时正确初始化和清理资源
16+
17+
3. **内存监控系统**
18+
- 实时监控内存使用情况(每30秒检查一次)
19+
- 内存使用超过500MB时自动触发清理
20+
- 内存使用超过400MB时执行轻量级垃圾回收
21+
- 提供手动清理接口:`POST /admin/cleanup`
22+
23+
4. **超时和错误处理**
24+
- 连接超时:10秒
25+
- 读取超时:60秒
26+
- 写入超时:10秒
27+
- 连接池超时:5秒
28+
- 详细的错误分类和处理
29+
30+
## 📊 性能提升
31+
32+
- **内存使用优化**:解决了无限内存增长问题
33+
- **连接复用**:减少连接建立开销
34+
- **自动清理**:防止资源泄漏
35+
- **监控告警**:实时掌握服务器状态
36+
37+
## 🛠️ 安装和使用
38+
39+
### 1. 安装依赖
40+
41+
```bash
42+
cd proxy
43+
pip install -r requirements.txt
44+
```
45+
46+
### 2. 启动服务器
47+
48+
#### 方式一:直接启动
49+
```bash
50+
python proxy.py
51+
```
52+
53+
#### 方式二:使用启动脚本(推荐)
54+
```bash
55+
python start_proxy.py --host 0.0.0.0 --port 8000
56+
```
57+
58+
#### 方式三:使用环境变量配置
59+
```bash
60+
export PROXY_HOST=0.0.0.0
61+
export PROXY_PORT=8000
62+
export PROXY_MAX_MEMORY_USAGE=300
63+
python proxy.py
64+
```
65+
66+
### 3. 健康检查
67+
68+
访问 `http://localhost:8000/health` 查看服务器状态和内存使用情况。
69+
70+
### 4. 手动清理内存
71+
72+
```bash
73+
curl -X POST http://localhost:8000/admin/cleanup
74+
```
75+
76+
## ⚙️ 配置选项
77+
78+
### 环境变量配置
79+
80+
| 变量名 | 默认值 | 说明 |
81+
|--------|--------|------|
82+
| `PROXY_HOST` | 0.0.0.0 | 绑定主机地址 |
83+
| `PROXY_PORT` | 8000 | 绑定端口 |
84+
| `PROXY_MAX_CONNECTIONS` | 100 | 最大连接数 |
85+
| `PROXY_MAX_KEEPALIVE_CONNECTIONS` | 20 | 最大保持连接数 |
86+
| `PROXY_KEEPALIVE_EXPIRY` | 30.0 | 连接保持时间(秒) |
87+
| `PROXY_CONNECT_TIMEOUT` | 10.0 | 连接超时(秒) |
88+
| `PROXY_READ_TIMEOUT` | 60.0 | 读取超时(秒) |
89+
| `PROXY_WRITE_TIMEOUT` | 10.0 | 写入超时(秒) |
90+
| `PROXY_MEMORY_CHECK_INTERVAL` | 30 | 内存检查间隔(秒) |
91+
| `PROXY_MAX_MEMORY_USAGE` | 500 | 最大内存使用(MB) |
92+
| `PROXY_CLEANUP_THRESHOLD` | 400 | 清理阈值(MB) |
93+
94+
### 配置文件
95+
96+
创建 `proxy_config.json` 文件:
97+
98+
```json
99+
{
100+
"host": "0.0.0.0",
101+
"port": 8000,
102+
"max_connections": 100,
103+
"max_keepalive_connections": 20,
104+
"keepalive_expiry": 30.0,
105+
"connect_timeout": 10.0,
106+
"read_timeout": 60.0,
107+
"write_timeout": 10.0,
108+
"memory_check_interval": 30,
109+
"max_memory_usage": 500,
110+
"cleanup_threshold": 400
111+
}
112+
```
113+
114+
## 📈 监控和日志
115+
116+
### 日志文件
117+
118+
服务器运行日志保存在 `proxy.log` 文件中,包含:
119+
- 请求日志
120+
- 内存使用情况
121+
- 错误信息
122+
- 清理操作记录
123+
124+
### 监控接口
125+
126+
- `GET /health` - 健康检查和内存使用情况
127+
- `POST /admin/cleanup` - 手动触发内存清理
128+
129+
### 示例监控脚本
130+
131+
```bash
132+
#!/bin/bash
133+
# monitor.sh - 监控脚本示例
134+
135+
while true; do
136+
response=$(curl -s http://localhost:8000/health)
137+
memory=$(echo $response | jq -r '.memory_usage_mb')
138+
139+
echo "$(date): 内存使用 ${memory}MB"
140+
141+
if (( $(echo "$memory > 400" | bc -l) )); then
142+
echo "内存使用过高,触发清理..."
143+
curl -X POST http://localhost:8000/admin/cleanup
144+
fi
145+
146+
sleep 60
147+
done
148+
```
149+
150+
## 🔧 故障排除
151+
152+
### 常见问题
153+
154+
1. **内存使用仍然很高**
155+
- 检查 `PROXY_MAX_MEMORY_USAGE``PROXY_CLEANUP_THRESHOLD` 设置
156+
- 查看日志文件确认清理操作是否正常执行
157+
- 考虑降低 `PROXY_MAX_CONNECTIONS`
158+
159+
2. **连接超时**
160+
- 调整 `PROXY_CONNECT_TIMEOUT``PROXY_READ_TIMEOUT`
161+
- 检查目标服务器的响应时间
162+
163+
3. **服务器无响应**
164+
- 检查端口是否被占用
165+
- 查看日志文件中的错误信息
166+
- 尝试重启服务器
167+
168+
### 性能调优建议
169+
170+
1. **根据服务器配置调整连接数**
171+
- 低配置服务器:`MAX_CONNECTIONS=50`
172+
- 高配置服务器:`MAX_CONNECTIONS=200`
173+
174+
2. **根据网络环境调整超时**
175+
- 内网环境:较短的超时时间
176+
- 外网环境:较长的超时时间
177+
178+
3. **根据内存大小调整阈值**
179+
- 小内存服务器:降低 `MAX_MEMORY_USAGE`
180+
- 大内存服务器:可以适当提高阈值
181+
182+
## 📝 更新日志
183+
184+
### v2.0.0 (当前版本)
185+
- ✅ 解决内存泄漏问题
186+
- ✅ 添加连接池管理
187+
- ✅ 实现内存监控系统
188+
- ✅ 优化资源释放机制
189+
- ✅ 添加健康检查接口
190+
- ✅ 完善错误处理
191+
- ✅ 添加配置管理
192+
193+
### v1.0.0 (原始版本)
194+
- ❌ 存在内存泄漏问题
195+
- ❌ 缺乏资源管理
196+
- ❌ 无监控机制

proxy/config.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
"""
2+
代理服务器配置文件
3+
可以通过环境变量或配置文件覆盖默认设置
4+
"""
5+
6+
import os
7+
from typing import Optional
8+
9+
class Config:
10+
"""配置类"""
11+
12+
# 服务器配置
13+
HOST: str = os.getenv("PROXY_HOST", "0.0.0.0")
14+
PORT: int = int(os.getenv("PROXY_PORT", "8000"))
15+
WORKERS: int = int(os.getenv("PROXY_WORKERS", "1"))
16+
17+
# 连接池配置
18+
MAX_CONNECTIONS: int = int(os.getenv("PROXY_MAX_CONNECTIONS", "100"))
19+
MAX_KEEPALIVE_CONNECTIONS: int = int(os.getenv("PROXY_MAX_KEEPALIVE_CONNECTIONS", "20"))
20+
KEEPALIVE_EXPIRY: float = float(os.getenv("PROXY_KEEPALIVE_EXPIRY", "30.0"))
21+
22+
# 超时配置
23+
CONNECT_TIMEOUT: float = float(os.getenv("PROXY_CONNECT_TIMEOUT", "10.0"))
24+
READ_TIMEOUT: float = float(os.getenv("PROXY_READ_TIMEOUT", "60.0"))
25+
WRITE_TIMEOUT: float = float(os.getenv("PROXY_WRITE_TIMEOUT", "10.0"))
26+
POOL_TIMEOUT: float = float(os.getenv("PROXY_POOL_TIMEOUT", "5.0"))
27+
28+
# 内存监控配置
29+
MEMORY_CHECK_INTERVAL: int = int(os.getenv("PROXY_MEMORY_CHECK_INTERVAL", "30"))
30+
MAX_MEMORY_USAGE: int = int(os.getenv("PROXY_MAX_MEMORY_USAGE", "500"))
31+
CLEANUP_THRESHOLD: int = int(os.getenv("PROXY_CLEANUP_THRESHOLD", "400"))
32+
33+
# 日志配置
34+
LOG_LEVEL: str = os.getenv("PROXY_LOG_LEVEL", "INFO")
35+
LOG_FILE: Optional[str] = os.getenv("PROXY_LOG_FILE", "proxy.log")
36+
37+
# 安全配置
38+
VERIFY_SSL: bool = os.getenv("PROXY_VERIFY_SSL", "false").lower() == "true"
39+
ALLOWED_HOSTS: Optional[str] = os.getenv("PROXY_ALLOWED_HOSTS") # 逗号分隔的主机列表
40+
41+
# 性能配置
42+
CHUNK_SIZE: int = int(os.getenv("PROXY_CHUNK_SIZE", "8192"))
43+
ENABLE_COMPRESSION: bool = os.getenv("PROXY_ENABLE_COMPRESSION", "true").lower() == "true"
44+
45+
@classmethod
46+
def get_allowed_hosts(cls) -> list:
47+
"""获取允许的主机列表"""
48+
if cls.ALLOWED_HOSTS:
49+
return [host.strip() for host in cls.ALLOWED_HOSTS.split(",")]
50+
return ["*"] # 默认允许所有主机
51+
52+
@classmethod
53+
def load_from_file(cls, config_file: str):
54+
"""从配置文件加载配置"""
55+
try:
56+
import json
57+
with open(config_file, 'r', encoding='utf-8') as f:
58+
config_data = json.load(f)
59+
60+
for key, value in config_data.items():
61+
if hasattr(cls, key.upper()):
62+
setattr(cls, key.upper(), value)
63+
except FileNotFoundError:
64+
pass # 配置文件不存在时使用默认值
65+
except Exception as e:
66+
print(f"加载配置文件失败: {e}")
67+
68+
@classmethod
69+
def save_to_file(cls, config_file: str):
70+
"""保存配置到文件"""
71+
import json
72+
73+
config_data = {}
74+
for attr in dir(cls):
75+
if attr.isupper() and not attr.startswith('_'):
76+
config_data[attr.lower()] = getattr(cls, attr)
77+
78+
with open(config_file, 'w', encoding='utf-8') as f:
79+
json.dump(config_data, f, indent=2, ensure_ascii=False)
80+
81+
# 默认配置实例
82+
config = Config()
83+
84+
# 尝试加载配置文件
85+
config.load_from_file("proxy_config.json")

0 commit comments

Comments
 (0)