Files
2026-06-01 13:54:52 +08:00

269 lines
15 KiB
Markdown
Raw Permalink 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/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)
</cite>
## 目录
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路由<br/>/proxy/*"]
RHandler["代理处理器<br/>proxy_handler_api.rs"]
RState["AppState<br/>包含Pingora服务引用"]
end
subgraph "agent_runner服务"
ARouter["Axum路由<br/>/proxy/*"]
AHandler["代理处理器<br/>proxy_handler_api.rs"]
AState["AppState<br/>包含Pingora服务引用"]
end
subgraph "Pingora代理"
PServer["PingoraServerManager<br/>启动与管理"]
PService["PingoraProxyService<br/>端口代理实现"]
PPort["PortProxy<br/>请求过滤/选择上游/响应过滤"]
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["上游请求过滤<br/>重写Host/URI/添加头部"]
FilterReq --> SelectPeer["选择上游Peer<br/>提取端口/动态后端"]
SelectPeer --> Forward["转发到后端服务"]
Forward --> RespFilter["响应过滤<br/>记录指标/计时"]
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)