武汉源创会回归,4月20聊聊大模型”
Pingap是基于pingora开发的,基于 Apache-2.0 license协议开源,源代码可查阅https://github.com/vicanso/pingap。pingora提供了各类模块便于rust开发者使用,但并不方便非rust开发者使用,因此pingap提供了以toml的形式配置简单易用的反向代理,实现支持多location代理转发,通过插件的形式支持更多的需求场景。特性如下:
- 支持多location配置,可通过请求的路径与域名筛选
- 支持HTTP1与HTTP2两种协议
- 无中断请求的配置更新,方便实时更新应用配置
- 模板式的请求日志输出,可按模板指定各种输出
- 提供Web界面式的配置,简化操作
- 支持各种插件形式,根据需要灵活配置各种特性:如静态文件目录、服务性能指标、WEB后台配置应用等
Location的处理逻辑
该Server下的所有location在初始化时根据权重按高至低排序,接受到请求时按顺序一个个匹配到符合的location为止,若无符合的则返回出错。在选择对应的location之后,判断是否有配置重写pathh(若无则不需要),添加请求头(若无则不需要),成功响应时添加响应头(若无则不需要)。
let header = session.req_header_mut(); let path = header.uri.path(); let host = header.uri.host().unwrap_or_default(); let (location_index, lo) = self .locations .iter() .enumerate() .find(|(_, item)| item.matched(host, path)) .ok_or_else(|| pingora::Error::new_str(LOCATION_NOT_FOUND))?; if let Some(mut new_path) = lo.rewrite(path) { if let Some(query) = header.uri.query() { new_path = format!("{new_path}?{query}"); } // TODO parse error let _ = new_path.parse::().map(|uri| header.set_uri(uri)); }
Location主要配置请求的匹配、请求头响应头的插入,以及各种插件的关联,是整个流程中的最重要组成部分。下面是相关参数的详细说明:
upstream
: 配置该location对应的upstream,若该location所有的处理均由插件完成,则可不配置host
: 匹配的域名,如果是多个域名则使用,
分隔path
: 匹配的路径,具体使用后续细说proxy_headers
: 转发至upstream时添加的请求头headers
: 响应至downstream时添加的响应头rewrite
: 请求路径的重写规则proxy_plugins
: 添加至该location的插件列表,按顺序执行
Location支持配置对应host(支持多个)与path规则,path支持以下的规则,权重由高至低:
- 全等模式,配置以
=
开始,如=/api
表示匹配path等于/api
的请求 - 正则模式,配置以
~
开始,如~^/(api|rest)
表示匹配path以/api
或/rest
开始请求 - 前缀模式,如
/api
表示匹配path为/api
开始的请求 - 空模式,若未指定path则表示所有的path均匹配,一般建议配置一个
/
的前缀模式即可,无需使用空模式
插件体系
Pingap中通过Locaton添加各种插件支持更多的应用场景,如鉴权、流控等。现在插件支持在request_filter
与proxy_upstream_filter
阶段执行,均为转发到上游节点前的处理。下面介绍一下proxy plunin
的具体逻辑,trait如下:
#[async_trait] pub trait ProxyPlugin: Sync + Send { fn category(&self) -> ProxyPluginCategory; fn step(&self) -> ProxyPluginStep; async fn handle(&self, _session: &mut Session, _ctx: &mut State) -> pingora::Result { Ok(false) } }
主要分三个实现:
category
: 插件类型,用于区分该插件是哪类形式的插件step
: 插件的执行阶段,现只支持在request_filter
与proxy_upstream_filter
阶段执行handle
: 插件的执行逻辑,若返回的是Ok(true)
,则表示请求已处理完成,不再转发到上游节点
Upstream的处理逻辑
Upstream的逻辑比较简单,在匹配location后,根据该location配置的upstream节点列表,按算法选择可用节点,并将请求转发至该节点即可。虽然注意,插件也可配置在proxy_upstream_filter
转发至upstream之前执行,可按需配置对应的插件。
Upstream配置为节点地址列表,配置为域名则会根据解析后的IP添加所有节点地址(之后并不会再次刷新域名解析),需要注意节点会使用默认的tcp health check的形式检测节点是否可用,建议配置为http health chech。下面针对相关参数详细说明:
addrs
: 节点地址列表,地址为ip:port weight
的形式,weight
权重可不指定,默认为1algo
: 节点的选择算法,支持hash
与round_robin
两种形式,如hash:ip
表示按ip hash选择节点。默认为round_robin
sni
: 若配置的是https,需要设置对应的SNIverify_cert
: 若配置的是http,是否需要校验证书有效性health_check
: 节点健康检测配置,支持http与tcp形式ipv4_only
: 若配置为域名时,是否仅添加解析的ipv4节点alpn
: 在tls握手时,alpn的配置,默认为H1connection_timeout
: tcp连接超时,默认为无total_connection_timeout
: 连接超时,对于https包括tls握手部分,默认为无read_timeout
: 读取超时,默认为无write_timeout
: 写超时,默认为无idle_timeout
: 空闲超时,指定连接空闲多久后会自动回收,如果设置为0,则连接不复用,需要注意有些网络设备对于无数据的tcp连接会过期自动关闭,因此可根据需要设置对应的值。默认为无
还没有评论,来说两句吧...