添加qiming-rcoder模块

This commit is contained in:
Codex
2026-06-01 13:54:52 +08:00
parent 8092c4b1f8
commit 4b1a580132
539 changed files with 151650 additions and 0 deletions

View File

@@ -0,0 +1,395 @@
# 请求处理与路由
<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)