# 反向代理接口
**本文引用的文件**
- [crates/rcoder/src/router.rs](file://crates/rcoder/src/router.rs)
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs)
- [crates/rcoder/src/handler/proxy_handler_api.rs](file://crates/rcoder/src/handler/proxy_handler_api.rs)
- [crates/agent_runner/src/handler/proxy_handler_api.rs](file://crates/agent_runner/src/handler/proxy_handler_api.rs)
- [crates/rcoder/src/handler/proxy_api.rs](file://crates/rcoder/src/handler/proxy_api.rs)
- [crates/agent_runner/src/handler/proxy_api.rs](file://crates/agent_runner/src/handler/proxy_api.rs)
- [crates/pingora-proxy/src/lib.rs](file://crates/pingora-proxy/src/lib.rs)
- [crates/pingora-proxy/src/config.rs](file://crates/pingora-proxy/src/config.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)
- [crates/rcoder/src/proxy_agent/port_manager.rs](file://crates/rcoder/src/proxy_agent/port_manager.rs)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向RCoder项目的反向代理API,聚焦/proxy/{port}/{path}端点的路由机制与请求转发逻辑,说明其如何将请求代理到AI代理在特定端口上运行的服务;解释端口管理机制与请求/响应的透明转发过程;提供curl示例,展示如何通过该接口访问代理的Web界面或API;说明与Pingora反向代理组件的集成方式,以及在处理WebSocket连接时的特殊考虑。
## 项目结构
RCoder项目包含两个主要服务:
- rcoder服务:提供聊天、会话管理、代理状态查询等API,并在启动时可选择启用Pingora反向代理服务。
- agent_runner服务:同样可启用Pingora代理服务,用于代理AI代理容器对外暴露的端口。
反向代理API在两个服务中均通过Axum路由注册,核心处理逻辑位于各自的handler模块中;而真正的代理转发由Pingora库实现。
```mermaid
graph TB
subgraph "rcoder服务"
RRouter["Axum路由
/proxy/*"]
RHandler["代理处理器
proxy_handler_api.rs"]
RState["AppState
包含Pingora服务引用"]
end
subgraph "agent_runner服务"
ARouter["Axum路由
/proxy/*"]
AHandler["代理处理器
proxy_handler_api.rs"]
AState["AppState
包含Pingora服务引用"]
end
subgraph "Pingora代理"
PServer["PingoraServerManager
启动与管理"]
PService["PingoraProxyService
端口代理实现"]
PPort["PortProxy
请求过滤/选择上游/响应过滤"]
end
RRouter --> RHandler --> RState
ARouter --> AHandler --> AState
RState --> PService
AState --> PService
PServer --> PService
PService --> PPort
```
图表来源
- [crates/rcoder/src/router.rs](file://crates/rcoder/src/router.rs#L52-L83)
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L67-L79)
- [crates/rcoder/src/handler/proxy_handler_api.rs](file://crates/rcoder/src/handler/proxy_handler_api.rs#L230-L332)
- [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-L66)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L224-L354)
章节来源
- [crates/rcoder/src/router.rs](file://crates/rcoder/src/router.rs#L52-L83)
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L67-L79)
## 核心组件
- 路由注册:在rcoder与agent_runner的router中分别注册/proxy/status、/proxy/stats、/proxy/config、/proxy/{port}、/proxy/{port}/{*path}等端点。
- 代理处理器:提供状态、统计、配置查询;以及将请求重定向到Pingora监听端口的处理器。
- Pingora服务:负责实际的请求转发、负载均衡、健康检查、指标统计与上游选择。
- 配置与启动:在rcoder主程序中根据配置启动Pingora服务器管理器,并将服务引用注入到AppState,供代理处理器读取。
章节来源
- [crates/rcoder/src/router.rs](file://crates/rcoder/src/router.rs#L52-L83)
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L67-L79)
- [crates/rcoder/src/handler/proxy_handler_api.rs](file://crates/rcoder/src/handler/proxy_handler_api.rs#L230-L332)
- [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-L66)
- [crates/rcoder/src/main.rs](file://crates/rcoder/src/main.rs#L169-L208)
## 架构总览
/proxy/{port}/{path}端点的请求流如下:
- 客户端请求到达rcoder/agent_runner的Axum路由。
- 若代理未启用,返回“服务不可用”错误。
- 若启用,处理器将请求临时重定向至Pingora监听端口的对应路径(/proxy/{port}或/ proxy/{port}/{path}),由Pingora完成实际转发。
- Pingora根据请求路径提取目标端口,动态发现后端主机,选择上游Peer,重写请求头与URI,转发到后端服务,并记录指标。
```mermaid
sequenceDiagram
participant C as "客户端"
participant AX as "Axum路由"
participant H as "代理处理器"
participant PS as "Pingora服务"
participant PR as "PortProxy"
participant BE as "后端服务"
C->>AX : "GET /proxy/{port}/{path}"
AX->>H : "匹配路由并进入处理器"
H->>PS : "读取配置/状态如需"
H-->>C : "307 临时重定向到 Pingora 监听端口"
C->>PS : "再次请求 /proxy/{port} 或 /proxy/{port}/{path}"
PS->>PR : "upstream_peer/过滤请求/响应"
PR->>PR : "提取端口/重写URI/选择上游"
PR->>BE : "转发到后端服务"
BE-->>PR : "返回响应"
PR-->>PS : "记录指标/计时"
PS-->>C : "返回最终响应"
```
图表来源
- [crates/rcoder/src/handler/proxy_handler_api.rs](file://crates/rcoder/src/handler/proxy_handler_api.rs#L230-L332)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L246-L354)
- [crates/pingora-proxy/src/pingora_server.rs](file://crates/pingora-proxy/src/pingora_server.rs#L37-L66)
## 详细组件分析
### 路由与控制器
- rcoder与agent_runner各自在router中注册/proxy/*端点,包括状态、统计、配置查询与端口代理。
- 代理处理器对/proxy/{port}与/proxy/{port}/{*path}进行处理:若代理未启用则返回错误;否则构造临时重定向到Pingora监听端口的Location头。
章节来源
- [crates/rcoder/src/router.rs](file://crates/rcoder/src/router.rs#L52-L83)
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L67-L79)
- [crates/rcoder/src/handler/proxy_handler_api.rs](file://crates/rcoder/src/handler/proxy_handler_api.rs#L230-L332)
- [crates/agent_runner/src/handler/proxy_handler_api.rs](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L230-L332)
### Pingora代理实现
- PingoraProxyService:维护后端映射、负载均衡算法、健康检查、指标统计与上下文跟踪。
- PortProxy:实现ProxyHttp,负责:
- 上游请求过滤:重写Host、添加X-Forwarded-Proto与X-Load-Balancer头;重写URI,移除/proxy/{port}前缀并保留查询参数。
- 上游Peer选择:从请求路径提取目标端口;若端口不在后端映射中则动态添加到默认主机;选择HttpPeer。
- 响应过滤:记录响应状态与耗时、更新指标、减少活跃连接数。
章节来源
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L224-L354)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L356-L409)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L411-L596)
### 端口管理机制
- rcoder服务中的PortManager负责容器端口分配与回收,避免端口冲突,确保代理后端端口可用。
- Pingora侧通过动态后端映射实现“按需发现”,首次遇到某端口时自动将其加入后端列表。
章节来源
- [crates/rcoder/src/proxy_agent/port_manager.rs](file://crates/rcoder/src/proxy_agent/port_manager.rs#L1-L96)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L300-L333)
### WebSocket连接的特殊考虑
- Pingora库基于Cloudflare Pingora,支持HTTP/1.1与HTTP/2,理论上可处理升级为WebSocket的请求。
- 由于rcoder与agent_runner的代理处理器采用临时重定向的方式,客户端需要遵循重定向并保持连接;具体WebSocket行为取决于上游后端服务是否支持升级。
- 若上游服务不支持升级,或客户端未正确处理重定向,可能出现握手失败或连接中断。
章节来源
- [crates/pingora-proxy/src/lib.rs](file://crates/pingora-proxy/src/lib.rs#L1-L58)
- [crates/pingora-proxy/src/pingora_server.rs](file://crates/pingora-proxy/src/pingora_server.rs#L37-L66)
### 请求/响应透明转发流程
```mermaid
flowchart TD
Start(["进入处理器"]) --> CheckEnabled{"代理已启用?"}
CheckEnabled --> |否| ReturnErr["返回服务不可用错误"]
CheckEnabled --> |是| BuildLoc["构造重定向到 Pingora 监听端口的 Location"]
BuildLoc --> Redirect["返回307临时重定向"]
Redirect --> Pingora["Pingora 接收请求"]
Pingora --> FilterReq["上游请求过滤
重写Host/URI/添加头部"]
FilterReq --> SelectPeer["选择上游Peer
提取端口/动态后端"]
SelectPeer --> Forward["转发到后端服务"]
Forward --> RespFilter["响应过滤
记录指标/计时"]
RespFilter --> Done(["返回响应"])
ReturnErr --> End(["结束"])
Done --> End
```
图表来源
- [crates/rcoder/src/handler/proxy_handler_api.rs](file://crates/rcoder/src/handler/proxy_handler_api.rs#L230-L332)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L246-L354)
## 依赖关系分析
- rcoder/agent_runner的路由依赖于代理处理器模块;代理处理器依赖于AppState中的Pingora服务引用。
- Pingora服务依赖于Pingora库的ProxyHttp trait实现,通过包装器将内部PortProxy暴露为Pingora服务。
- rcoder主程序在启动时根据配置创建PingoraServerManager并启动服务器,同时将服务引用注入AppState。
```mermaid
graph LR
Router["Axum路由"] --> Handler["代理处理器"]
Handler --> AppState["AppState"]
AppState --> PingoraSvc["PingoraProxyService"]
PingoraSvc --> PortProxy["PortProxy"]
PingoraMgr["PingoraServerManager"] --> PingoraSvc
Main["rcoder主程序"] --> PingoraMgr
```
图表来源
- [crates/rcoder/src/router.rs](file://crates/rcoder/src/router.rs#L52-L83)
- [crates/rcoder/src/handler/proxy_handler_api.rs](file://crates/rcoder/src/handler/proxy_handler_api.rs#L230-L332)
- [crates/pingora-proxy/src/pingora_server.rs](file://crates/pingora-proxy/src/pingora_server.rs#L37-L66)
- [crates/rcoder/src/main.rs](file://crates/rcoder/src/main.rs#L169-L208)
章节来源
- [crates/rcoder/src/router.rs](file://crates/rcoder/src/router.rs#L52-L83)
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L67-L79)
- [crates/rcoder/src/handler/proxy_handler_api.rs](file://crates/rcoder/src/handler/proxy_handler_api.rs#L230-L332)
- [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-L66)
- [crates/rcoder/src/main.rs](file://crates/rcoder/src/main.rs#L169-L208)
## 性能考量
- 负载均衡:Pingora支持轮询与一致性哈希两种算法,默认启用轮询;可根据配置切换。
- 健康检查:Pingora内置TCP健康检查,周期性探测后端连通性,支持超时与阈值配置。
- 指标统计:提供总请求数、成功率、平均响应时间、每端口统计与活跃连接数等指标,便于监控与优化。
- 动态后端:首次遇到新端口时自动加入后端映射,避免预配置开销,提升弹性。
章节来源
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L509-L596)
- [crates/pingora-proxy/src/server.rs](file://crates/pingora-proxy/src/server.rs#L143-L155)
- [crates/pingora-proxy/src/config.rs](file://crates/pingora-proxy/src/config.rs#L1-L95)
## 故障排查指南
- 代理未启用:当AppState中未注入Pingora服务或配置为空时,/proxy/*接口返回“服务不可用”错误。确认rcoder主程序已按配置启动Pingora服务。
- 端口提取失败:若请求路径不符合/proxy/{port}格式,将回退到默认后端端口。检查客户端是否使用正确的路径格式。
- 后端未发现:Pingora在首次遇到端口时会动态添加默认主机;若后端主机不可达,健康检查会标记为不健康。检查后端服务状态与网络连通性。
- 重定向链路:代理处理器返回307临时重定向,客户端需跟随重定向并保持连接(尤其WebSocket场景)。
章节来源
- [crates/rcoder/src/handler/proxy_handler_api.rs](file://crates/rcoder/src/handler/proxy_handler_api.rs#L31-L114)
- [crates/agent_runner/src/handler/proxy_handler_api.rs](file://crates/agent_runner/src/handler/proxy_handler_api.rs#L31-L114)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L300-L333)
## 结论
RCoder的反向代理API通过Axum路由与Pingora代理实现解耦:路由层负责接入与状态查询,Pingora负责高性能转发与负载均衡。/proxy/{port}/{path}端点采用临时重定向到Pingora监听端口的方式,使客户端透明地访问任意端口的后端服务。结合动态后端与健康检查,系统具备良好的弹性与可观测性。
## 附录
### curl示例
以下示例展示如何通过/proxy接口访问不同后端服务(请将localhost替换为实际部署地址与端口):
- 访问默认后端健康检查
- curl "http://localhost:3000/proxy/8080/health"
- 访问特定端口的API
- curl "http://localhost:3000/proxy/3000/api/users"
- 访问代理状态
- curl "http://localhost:3000/proxy/status"
- 访问代理统计
- curl "http://localhost:3000/proxy/stats"
- 访问代理配置
- curl "http://localhost:3000/proxy/config"
章节来源
- [crates/rcoder/src/router.rs](file://crates/rcoder/src/router.rs#L173-L193)
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L173-L193)
### 与Pingora集成要点
- 启动方式:rcoder主程序创建PingoraServerManager并启动服务器,监听配置中的listen_port。
- 服务注入:将Pingora服务引用注入AppState,代理处理器可读取配置与指标。
- 路由规则:Pingora内部处理/proxy/{port}与/proxy/{port}/{path},移除前缀并重写URI,转发到后端。
章节来源
- [crates/rcoder/src/main.rs](file://crates/rcoder/src/main.rs#L169-L208)
- [crates/pingora-proxy/src/pingora_server.rs](file://crates/pingora-proxy/src/pingora_server.rs#L37-L66)
- [crates/pingora-proxy/src/service.rs](file://crates/pingora-proxy/src/service.rs#L246-L354)