Files
qiming/qiming-rcoder/.qoder/repowiki/zh/content/反向代理服务/请求处理与路由.md
2026-06-01 13:54:52 +08:00

395 lines
19 KiB
Markdown
Raw 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.
# 请求处理与路由
<cite>
**本文引用的文件**
- [crates/agent_runner/src/handler/proxy_handler_api.rs](file://crates/agent_runner/src/handler/proxy_handler_api.rs)
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs)
- [crates/agent_runner/src/handler/proxy_api.rs](file://crates/agent_runner/src/handler/proxy_api.rs)
- [crates/agent_runner/src/config.rs](file://crates/agent_runner/src/config.rs)
- [crates/pingora-proxy/src/lib.rs](file://crates/pingora-proxy/src/lib.rs)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs)
- [crates/pingora-proxy/src/server.rs](file://crates/pingora-proxy/src/server.rs)
- [crates/pingora-proxy/src/pingora_server.rs](file://crates/pingora-proxy/src/pingora_server.rs)
- [crates/rcoder/src/main.rs](file://crates/rcoder/src/main.rs)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件围绕基于 Pingora 的反向代理请求处理与路由机制展开,重点解析:
- 基于 Axum 的 API 路由与重定向逻辑
- `/proxy/{port}/{path}` 路由规则的实现原理
- 动态端口映射、请求头传递、超时控制与健康检查
- 负载均衡策略(轮询与一致性哈希)
- 从 Axum 路由到 Pingora 服务的请求转发链路
- 实际请求示例与调试技巧
## 项目结构
该仓库采用多 crate 组织,其中与反向代理直接相关的核心模块如下:
- agent_runner提供 API 层Axum 路由、状态查询、统计信息),并持有 Pingora 服务引用以读取指标
- pingora-proxy提供 Pingora 代理服务、负载均衡、健康检查与请求过滤
- rcoder应用入口负责启动 Pingora 服务器管理器、注入 AppState、合并路由
```mermaid
graph TB
subgraph "应用层"
AR["agent_runner<br/>API 路由与状态查询"]
CFG["agent_runner/config.rs<br/>应用配置"]
MAIN["rcoder/src/main.rs<br/>应用入口与路由合并"]
end
subgraph "代理层"
PINGORA_LIB["pingora-proxy/lib.rs<br/>库入口与特性说明"]
PINGORA_SRV["pingora-proxy/server.rs<br/>代理服务器管理器"]
PINGORA_SVC["pingora-proxy/service.rs<br/>代理服务与负载均衡"]
PINGORA_MGR["pingora-proxy/pingora_server.rs<br/>Pingora 服务器启动"]
end
MAIN --> AR
AR --> CFG
MAIN --> PINGORA_MGR
PINGORA_MGR --> PINGORA_SRV
PINGORA_SRV --> PINGORA_SVC
PINGORA_LIB --> PINGORA_SVC
```
图表来源
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L41-L70)
- [crates/agent_runner/src/config.rs](file://crates/agent_runner/src/config.rs#L38-L110)
- [crates/rcoder/src/main.rs](file://crates/rcoder/src/main.rs#L170-L265)
- [crates/pingora-proxy/src/lib.rs](file://crates/pingora-proxy/src/lib.rs#L60-L120)
- [crates/pingora-proxy/src/server.rs](file://crates/pingora-proxy/src/server.rs#L1-L100)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L223-L355)
- [crates/pingora-proxy/src/pingora_server.rs](file://crates/pingora-proxy/src/pingora_server.rs#L37-L106)
章节来源
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L41-L70)
- [crates/agent_runner/src/config.rs](file://crates/agent_runner/src/config.rs#L38-L110)
- [crates/rcoder/src/main.rs](file://crates/rcoder/src/main.rs#L170-L265)
## 核心组件
- Axum 路由与代理 API
- 提供 `/proxy/status``/proxy/stats``/proxy/config` 等状态查询接口
- 提供 `/proxy/{port}``/proxy/{port}/{*path}` 的重定向逻辑,将请求转发至 Pingora 监听端口
- Pingora 代理服务
- 路径解析:从 `/proxy/{port}` 前缀提取目标端口,剥离前缀得到目标路径
- 动态后端:若端口未在映射中,自动添加默认主机映射
- 请求过滤:重写 Host、添加 X-Forwarded-Proto、X-Port-Proxy、X-Load-Balancer 等头部
- 响应过滤:记录指标、计算平均响应时间、维护活跃连接数
- 负载均衡支持轮询与一致性哈希Ketama并内置健康检查
- 应用入口与状态注入
- 启动 Pingora 服务器管理器,提取服务引用注入 AppState供 API 查询使用
章节来源
- [crates/agent_runner/src/handler/proxy_handler_api.rs](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L230-L332)
- [crates/agent_runner/src/handler/proxy_api.rs](file://crates/agent_runner/src/handler/proxy_api.rs#L1-L195)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L252-L355)
- [crates/pingora-proxy/src/server.rs](file://crates/pingora-proxy/src/server.rs#L1-L100)
- [crates/rcoder/src/main.rs](file://crates/rcoder/src/main.rs#L170-L265)
## 架构总览
下图展示了从客户端请求到 Pingora 代理再到后端服务的整体链路,以及 API 层对代理状态与统计的读取。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant API as "Axum 路由层<br/>/proxy/*"
participant State as "AppState<br/>持有 Pingora 服务引用"
participant PingoraMgr as "Pingora 服务器管理器"
participant PingoraSvc as "Pingora 代理服务"
participant Backend as "后端服务"
Client->>API : "GET /proxy/{port}/{path}"
API->>API : "校验代理配置是否启用"
API->>Client : "307 临时重定向到 127.0.0.1 : {listen_port}/proxy/{port}{path}"
Client->>PingoraMgr : "GET /proxy/{port}{/path}"
PingoraMgr->>PingoraSvc : "upstream_peer()<br/>提取端口并选择后端"
PingoraSvc->>PingoraSvc : "upstream_request_filter()<br/>重写 Host/URI/添加代理头"
PingoraSvc->>Backend : "转发请求"
Backend-->>PingoraSvc : "响应"
PingoraSvc->>PingoraSvc : "response_filter()<br/>记录指标/活跃连接"
PingoraSvc-->>Client : "返回响应"
```
图表来源
- [crates/agent_runner/src/handler/proxy_handler_api.rs](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L230-L332)
- [crates/pingora-proxy/src/pingora_server.rs](file://crates/pingora-proxy/src/pingora_server.rs#L37-L106)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L252-L355)
## 详细组件分析
### Axum 路由与代理 API
- 路由注册
- API 路由与代理 API 路由分别注册,最终合并到一个 Router
- 代理 API 路由包括状态、统计、配置查询,以及 `/proxy/{port}``/proxy/{port}/{*path}` 的重定向
- 重定向逻辑
- `/proxy/{port}`:构造 Location 为 `http://127.0.0.1:{listen_port}/proxy/{port}`
- `/proxy/{port}/{*path}`:保持路径,构造 Location 为 `http://127.0.0.1:{listen_port}/proxy/{port}{path}`
- 状态查询与统计
- `/proxy/status`:读取 Pingora 服务配置、后端映射与健康快照
- `/proxy/stats`:读取总请求数、成功率、平均响应时间、按端口统计
- `/proxy/config`:读取监听端口、默认后端、负载均衡算法与健康检查配置
```mermaid
flowchart TD
Start(["进入代理 API"]) --> CheckCfg["检查代理配置是否启用"]
CheckCfg --> |未启用| Return503["返回 503 错误"]
CheckCfg --> |已启用| RouteType{"请求路径类型?"}
RouteType --> |/proxy/{port}| BuildLoc1["构造 Location: 127.0.0.1:{listen_port}/proxy/{port}"]
RouteType --> |/proxy/{port}/{*path}| BuildLoc2["构造 Location: 127.0.0.1:{listen_port}/proxy/{port}{path}"]
BuildLoc1 --> Redirect["307 临时重定向"]
BuildLoc2 --> Redirect
Redirect --> End(["完成"])
Return503 --> End
```
图表来源
- [crates/agent_runner/src/handler/proxy_handler_api.rs](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L230-L332)
章节来源
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L41-L70)
- [crates/agent_runner/src/handler/proxy_handler_api.rs](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L230-L332)
- [crates/agent_runner/src/handler/proxy_api.rs](file://crates/agent_runner/src/handler/proxy_api.rs#L1-L195)
### Pingora 代理服务与负载均衡
- 端口提取与路径重写
- 从请求 URI 中提取端口:优先解析 `/proxy/{port}` 前缀;若不存在则回退到默认端口
- 重写请求 URI移除 `/proxy/{port}` 前缀,保留查询参数
- 重写 Host 为 127.0.0.1,并添加 X-Forwarded-Proto、X-Port-Proxy、X-Load-Balancer 等头部
- 动态后端管理
- 若目标端口不在映射中,自动添加默认主机映射
- 支持添加/移除后端、列出后端、检查后端存在性、统计后端数量
- 指标与健康检查
- 维护总请求数、成功/失败计数、平均响应时间、每端口统计
- 维护活跃连接数,原子递增/递减
- 健康检查:基于 TCP 连接超时检测,周期性更新健康状态快照
- 负载均衡
- 支持轮询与一致性哈希Ketama可通过配置切换
- 内置健康检查,可配置检查频率、超时与阈值
```mermaid
classDiagram
class PingoraProxyService {
+config : ProxyConfig
+backends : HashMap<u16, String>
+use_round_robin : bool
+metrics : ProxyMetrics
+health_map : HashMap<u16, HealthInfo>
+create_pingora_proxy() PortProxy
+add_backend(port, host) void
+remove_backend(port) void
+list_backends() HashMap<u16, String>
+has_backend(port) bool
+backend_count() usize
+extract_target_port(req) u16
+get_target_backend(port) String
+create_load_balancer(backend_list) LoadBalancer
+start_health_check_loop(interval, timeout) void
+health_snapshot() HashMap<u16, HealthInfo>
}
class PortProxy {
+backends : HashMap<u16, String>
+default_backend_port : u16
+backend_host : String
+use_round_robin : bool
+metrics : ProxyMetrics
+upstream_peer(session, ctx) HttpPeer
+upstream_request_filter(session, upstream_request, ctx) void
+response_filter(session, upstream_response, ctx) void
-extract_target_port(session) u16
-extract_target_path(session) String
-get_backend_host(port) String
}
class ProxyMetrics {
+total_requests : AtomicU64
+successful_responses : AtomicU64
+failed_responses : AtomicU64
+total_response_time_ns : AtomicU64
+active_connections : AtomicU64
+record_request() void
+record_request_port(port) void
+record_response(status_text, duration) void
+record_response_port(port, status_text, duration) void
+avg_response_time_ms() f64
+inc_active() void
+dec_active() void
+active() u64
+port_snapshots() Vec<PortSnapshot>
}
PingoraProxyService --> PortProxy : "创建代理实例"
PortProxy --> ProxyMetrics : "记录指标"
```
图表来源
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L223-L355)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L509-L596)
章节来源
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L252-L355)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L509-L596)
### Pingora 服务器启动与运行
- 服务器管理器
- 创建 Opt、Server、HTTP 代理服务,绑定 TCP 监听端口
- 通过 ProxyServiceWrapper 将 PortProxy 实现适配为 Pingora 的 ProxyHttp
- 提供启动/停止与服务引用获取能力
- 应用入口集成
- rcoder 在启动时创建 PingoraServerManager提取服务引用注入 AppState
- 启动健康检查循环(按配置)
- 合并 API 路由与 Swagger UI
```mermaid
sequenceDiagram
participant Main as "rcoder/main.rs"
participant Manager as "PingoraServerManager"
participant Server as "Pingora Server"
participant Service as "PingoraProxyService"
participant Wrapper as "ProxyServiceWrapper"
Main->>Manager : "new(config)"
Main->>Manager : "start()"
Manager->>Server : "创建 Server/HTTP 代理服务"
Manager->>Wrapper : "包装 PortProxy"
Wrapper-->>Server : "实现 ProxyHttp"
Server-->>Main : "run_forever() 运行"
Main->>Service : "service() 获取引用"
Main-->>Main : "注入 AppState 并启动 API 服务"
```
图表来源
- [crates/rcoder/src/main.rs](file://crates/rcoder/src/main.rs#L170-L265)
- [crates/pingora-proxy/src/pingora_server.rs](file://crates/pingora-proxy/src/pingora_server.rs#L37-L106)
- [crates/pingora-proxy/src/server.rs](file://crates/pingora-proxy/src/server.rs#L1-L100)
章节来源
- [crates/rcoder/src/main.rs](file://crates/rcoder/src/main.rs#L170-L265)
- [crates/pingora-proxy/src/pingora_server.rs](file://crates/pingora-proxy/src/pingora_server.rs#L37-L106)
- [crates/pingora-proxy/src/server.rs](file://crates/pingora-proxy/src/server.rs#L1-L100)
## 依赖关系分析
- 组件耦合
- agent_runner 的路由层依赖 AppState 中的 Pingora 服务引用,用于读取状态与统计
- rcoder 的 main.rs 负责创建 PingoraServerManager 并注入 AppState
- pingora-proxy 的 service.rs 与 pingora_server.rs 分别承担服务实现与服务器启动职责
- 外部依赖
- Pingora 库提供高性能代理、负载均衡与健康检查
- Axum 提供路由与 HTTP 处理
- Tokio 提供异步运行时与任务管理
```mermaid
graph LR
AR["agent_runner/router.rs"] --> API["agent_runner/handler/proxy_handler_api.rs"]
API --> CFG["agent_runner/config.rs"]
API --> STATE["AppState<br/>持有 Pingora 服务引用"]
STATE --> MAIN["rcoder/main.rs"]
MAIN --> MGR["pingora_proxy/pingora_server.rs"]
MGR --> SRV["pingora_proxy/server.rs"]
SRV --> SVC["pingora_proxy/service.rs"]
LIB["pingora_proxy/lib.rs"] --> SVC
```
图表来源
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L41-L70)
- [crates/agent_runner/src/handler/proxy_handler_api.rs](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L230-L332)
- [crates/agent_runner/src/config.rs](file://crates/agent_runner/src/config.rs#L38-L110)
- [crates/rcoder/src/main.rs](file://crates/rcoder/src/main.rs#L170-L265)
- [crates/pingora-proxy/src/pingora_server.rs](file://crates/pingora-proxy/src/pingora_server.rs#L37-L106)
- [crates/pingora-proxy/src/server.rs](file://crates/pingora-proxy/src/server.rs#L1-L100)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L223-L355)
- [crates/pingora-proxy/src/lib.rs](file://crates/pingora-proxy/src/lib.rs#L60-L120)
章节来源
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L41-L70)
- [crates/agent_runner/src/handler/proxy_handler_api.rs](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L230-L332)
- [crates/agent_runner/src/config.rs](file://crates/agent_runner/src/config.rs#L38-L110)
- [crates/rcoder/src/main.rs](file://crates/rcoder/src/main.rs#L170-L265)
- [crates/pingora-proxy/src/pingora_server.rs](file://crates/pingora-proxy/src/pingora_server.rs#L37-L106)
- [crates/pingora-proxy/src/server.rs](file://crates/pingora-proxy/src/server.rs#L1-L100)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L223-L355)
- [crates/pingora-proxy/src/lib.rs](file://crates/pingora-proxy/src/lib.rs#L60-L120)
## 性能考量
- 路由与重定向
- 代理 API 层采用 307 重定向,避免在 API 服务中直接发起网络请求,降低延迟与资源占用
- 负载均衡与健康检查
- 轮询与一致性哈希两种策略可按需切换;健康检查周期与超时可配置,平衡准确性与开销
- 指标与可观测性
- 提供总请求数、成功率、平均响应时间、每端口统计与活跃连接数,便于性能分析与容量规划
- 异步与并发
- 基于 Tokio 的异步 I/OPingora 代理服务在高并发场景下具备良好吞吐能力
[本节为通用性能讨论,不直接分析具体文件]
## 故障排查指南
- 代理未启用
- 现象:调用 `/proxy/status``/proxy/stats``/proxy/config` 返回 503
- 排查:确认应用配置中启用了代理,且 Pingora 服务器已启动
- 端口提取失败
- 现象:请求未命中预期后端
- 排查:检查请求路径是否符合 `/proxy/{port}` 格式;确认端口参数是否有效
- 后端未发现
- 现象:动态添加后端后仍报“未找到后端”
- 排查:确认端口已被加入映射;检查默认主机配置与健康检查状态
- 超时与连接问题
- 现象:健康检查超时或连接失败
- 排查:调整健康检查超时与间隔;检查后端服务监听端口与防火墙策略
- 请求头与路径问题
- 现象:后端服务无法识别 Host 或路径被错误重写
- 排查:确认上游请求过滤已正确重写 Host 与 URI检查查询参数是否保留
章节来源
- [crates/agent_runner/src/handler/proxy_handler_api.rs](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L31-L174)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L252-L355)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L556-L596)
## 结论
该系统通过 Axum 的轻量 API 层与 Pingora 的高性能代理服务实现了灵活、可扩展的反向代理能力。其核心优势包括:
- 清晰的路由与重定向机制,简化了 API 层与代理层的职责分离
- 动态端口映射与请求头传递,保证了透明代理与可观测性
- 可配置的负载均衡与健康检查,满足生产环境的稳定性需求
- 丰富的指标与状态查询接口,便于运维与性能优化
[本节为总结性内容,不直接分析具体文件]
## 附录
### 实际请求示例
- 查询代理状态
- 请求GET /proxy/status
- 作用:返回代理服务状态、监听端口、默认后端、后端列表与负载均衡配置
- 查询代理统计
- 请求GET /proxy/stats
- 作用:返回总请求数、成功率、平均响应时间、按端口统计与活跃连接数
- 查询代理配置
- 请求GET /proxy/config
- 作用:返回监听端口、默认后端、负载均衡算法与健康检查配置
- 代理到指定端口(无路径)
- 请求GET /proxy/{port}
- 作用307 重定向到 127.0.0.1:{listen_port}/proxy/{port}
- 代理到指定端口与路径
- 请求GET /proxy/{port}/{*path}
- 作用307 重定向到 127.0.0.1:{listen_port}/proxy/{port}{path}
章节来源
- [crates/agent_runner/src/handler/proxy_handler_api.rs](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L230-L332)
- [crates/agent_runner/src/handler/proxy_api.rs](file://crates/agent_runner/src/handler/proxy_api.rs#L1-L195)
### 调试技巧
- 启用健康检查
- 在配置中开启健康检查,并设置合理的间隔与超时,观察健康状态快照
- 观察指标
- 通过 `/proxy/stats``/proxy/status` 持续监控请求量、成功率与平均响应时间
- 路径与端口验证
- 使用 curl 验证重定向行为与端口提取逻辑,确保路径前缀被正确剥离
- 日志与追踪
- 关注 Pingora 与应用层日志,定位请求过滤与响应过滤阶段的问题
章节来源
- [crates/rcoder/src/main.rs](file://crates/rcoder/src/main.rs#L170-L265)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L556-L596)