Day 192 图解 — 代理池
全部为 ASCII / Mermaid,渲染时不需要图片文件。
1. 一次请求的完整路径
```text ┌──────────┐ 1. acquire(domain) ┌───────────────────────────┐ │ Scheduler│ ─────────────────────► │ ProxyPool │ └──────────┘ │ │ │ 冷却中? ──yes──► 跳过 │ │ 新出口? ──yes──► 探针优先│ │ 粘滞域? ──yes──► 复用 │ │ 否则 ────────► 最高分 │ └─────────────┬─────────────┘ │ exit ▼ ┌───────────────────────────┐ │ TokenBucket[exit].acquire │ │ (等在这里,不占用出口) │ └─────────────┬─────────────┘ ▼ ┌───────────────────────────┐ │ Fetcher: urllib + Proxy │ └─────────────┬─────────────┘ ┌────────────────────────┼────────────────────────┐ ▼ ▼ ▼ 200 OK 429 / 403 timeout / 502 │ │ │ success++ / EWMA cooldown(Retry-After) fail++ / 熔断 │ │ │ └────────────────────────┴────────────────────────┘ ▼ metrics / 水位告警 ```
2. 冷却状态机
```mermaid stateDiagram-v2 [*] --> Healthy
Healthy --> Cooling: 429 / 403 / 连续失败 N 次
Cooling --> HalfOpen: cooldown 到期
HalfOpen --> Healthy: 探针 200
HalfOpen --> Cooling: 探针失败,冷却 ×2
Cooling --> Cooling: 请求一律不分配
note right of Cooling
冷却期间流量转移到其他出口
水位下降,触发扩容告警
end note
```
3. 评分函数的形状
```text score 1.0 │● │ ● 0.8 │ ● success_rate = 1.0 │ ● 0.6 │ ● │ ● 0.4 │ ● │ ● 0.2 │ ● ← 延迟越高,分数越低 └───┬───┬───┬───┬───┬───┬────► latency 0 50 100 200 400 800 ms ```
同一延迟下,成功率的影响是平方级的:
```text success_rate: 1.0 0.9 0.7 0.5 score(100ms): 0.48 0.39 0.24 0.11 ```
结论:一个 70% 成功率的快出口,打不过一个 100% 成功率的中速出口。 稳定性优先于速度。
4. 令牌桶与"轮换不等于提速"
```text 错误模型(每个 worker 各自 sleep) worker1 ──► p1 3 req/s worker2 ──► p2 3 req/s 目标站看到:每个出口 3 req/s → 全部 429 worker3 ──► p3 3 req/s
正确模型(每出口一个桶) p1 [bucket 1/s] ──► 1 req/s p2 [bucket 1/s] ──► 1 req/s 总吞吐 3 req/s,每个出口都在配额内 p3 [bucket 1/s] ──► 1 req/s ```
5. 轮换 vs 粘滞
```text 时间 ─────────────────────────────►
轮换 rotating shop#1 p1 shop#2 p2 shop#3 p3 shop#4 p1 cookie: p1 p2 p3 p1 ← 每次都断
粘滞 sticky shop#1 p1 shop#2 p1 shop#3 p1 shop#4 p1 cookie: p1 p1 p1 p1 ← 会话连续 ```
例外:p1 进入冷却时,粘滞必须迁移,并记一次 `migration`。
6. 健康检查的三个层次
```text Level 1 TCP connect "进程活着" │ Level 2 HTTP 任意响应 "能转发,但可能是登录页/劫持页" │ Level 3 200 + 预期标记 "真的从该出口到达了目标" │ ▼ 只有 Level 3 可以作为 healthy 判据 ```
7. 出口池水位
```text 可用/总数 100% ┤████████████████████ 健康 80% ┤████████████████ 60% ┤████████████ 健康下限 40% ┤███████ 紧张:降速 + 补充 20% ┤███ 危险:暂停任务 + 告警 0% ┤ 熔断:全站停止 ```