rust网络框架Pingora源码阅读3
内容提要
本文是Pingora源码阅读系列的最后一篇文章,重点介绍了监听服务的钩子函数,即业务代码的编写地方。钩子函数分为代理前和代理后两部分,功能分为缓存类、过滤类和错误处理类。主要业务逻辑在process_request函数中,将客户端请求转发给后端的处理交给proxy_to_upstream函数。代码分解了process_request和proxy_to_upstream函数的具体实现。整个Pingora框架提供了丰富的钩子函数和功能,方便实现流控和负载均衡等业务。
延伸解读
钩子函数的两阶段划分
Pingora 的钩子函数按处理阶段分为代理前和代理后。代理前包括 request_filter 和 upstream_peer,用于控制是否处理请求以及选择哪个后端;代理后包括 connected_to_upstream、upstream_request_filter、upstream_response_filter 等,在发送请求到上游或下游前处理各部分。这种划分让开发者能清晰地在不同阶段插入业务逻辑。
process_request 的核心流程
process_request 是主要业务逻辑所在,依次执行:调用 request_filter 判断是否直接返回、获取客户端压缩算法、尝试缓存命中、通过 proxy_upstream_filter 决定是否转发、进入重试循环调用 proxy_to_upstream,最多重试 16 次。若代理出错且缓存允许,会尝试发送陈旧缓存,最后调用 logging 并返回连接重用状态。
流量转发的实现机制
proxy_to_upstream 负责将客户端请求转发给后端,先通过 upstream_peer 获取后端对象,再从连接池获取会话,然后根据协议调用 proxy_to_h1_upstream 等。在 proxy_1to1 中,将客户端和后端的连接分割为发送端和接收端,通过 tokio::try_join! 启动两个异步任务实现双向传输,并调用 upstream_request_filter 等钩子。
缓存与错误处理的钩子
Pingora 提供缓存类钩子如 request_cache_filter 和 response_cache_filter 以提升性能,但默认禁用。错误处理类钩子包括 fail_to_connect、fail_to_proxy 和 error_while_proxy,用于出错时回调及重试。process_request 中若代理出错且缓存可服务陈旧错误,会调用 handle_stale_if_error 尝试返回缓存内容。
Q&A
Pingora框架中的钩子函数有什么作用?
钩子函数用于在特定阶段处理业务逻辑,分为代理前和代理后两部分,功能包括缓存、过滤和错误处理。
process_request函数的主要逻辑是什么?
process_request函数主要负责判断是否继续处理请求、获取压缩算法、处理缓存和请求转发。
Pingora如何实现流量转发?
Pingora通过proxy_to_upstream函数将客户端请求转发给后端,并处理不同协议的流量转发。
Pingora框架提供了哪些类型的钩子函数?
Pingora框架提供的钩子函数主要包括缓存类、过滤类和错误处理类的函数。
在Pingora中,如何处理请求的缓存?
Pingora使用request_cache_filter和response_cache_filter等函数来处理请求的缓存,以提升性能。
Pingora的代理前和代理后钩子函数有什么区别?
代理前钩子函数控制请求的处理和后端选择,代理后钩子函数在发送前处理请求的各个部分。