rust网络框架Pingora源码阅读2

💡 原文中文,约8700字,阅读约需21分钟。
📝

内容提要

本文介绍了Pingora服务中的监听部分代码。Pingora内置两种服务:后台服务和监听服务。代码分为两部分:服务的创建和初始化,以及将服务添加到服务器对象并启动服务器对象。监听服务支持HTTP、HTTPS和Unix Socket三种监听类型。监听服务根据添加的端点创建对应数量的协议栈对象,然后将连接传递给应用逻辑处理。处理过程中,根据协议类型调用不同的处理函数。

🔎

延伸解读

惰性构建:启动时才创建资源

Pingora 在 Service 配置阶段仅封装对象,如添加监听地址时只是将 TransportStackBuilder 推入 stacks 列表,并不立即获取端口或初始化协议栈。真正的构建发生在启动时,由 start_service 调用 listeners.build(fds) 完成。这种惰性设计避免了启动前的资源占用,也便于统一管理生命周期。

传输层与应用层的职责分离

监听服务中的 stack 负责传输层抽象,包括 TCP 和 TLS 握手,不触碰应用层协议。握手完成后,连接被交给 app_logic(即 HttpProxy)处理。这种分层使得传输层可以独立变化,而 HTTP 处理逻辑通过 ServerApp 和 HttpServerApp 两个 trait 进一步解耦,便于扩展。

HTTP/2 连接复用与处理差异

process_new 根据 ALPN 或请求头区分协议版本。HTTP/2 需要额外的应用层握手,并在一个 TCP 连接上循环获取多个 stream,每个 stream 独立交给 process_new_http 处理。而 HTTP/1 则直接处理整个连接。这体现了 HTTP/2 多路复用特性对连接管理方式的影响。

长连接保持与关闭信号处理

在 process_new_http 中,若服务即将关闭,会通过 session.set_keepalive(None) 阻止下游复用连接;否则默认设置 60 秒的 keepalive。同时,run_endpoint 通过监听 shutdown 信号来优雅停止接受新连接。这些机制共同保障了服务关闭时的连接清理和资源释放。

❓

Q&A

Pingora的监听服务支持哪些协议类型?

Pingora的监听服务支持HTTP、HTTPS和Unix Socket三种协议类型。

如何初始化Pingora的服务?

初始化Pingora的服务需要创建一个实现Service Trait的对象,并配置服务类型和监听入口。

Pingora的服务调用链是怎样的?

Pingora的服务调用链从Server启动开始,最终创建异步任务运行Service的start_service方法。

Pingora的run_endpoint函数有什么作用?

run_endpoint函数负责开始监听请求,处理新获取的连接并进行握手。

Pingora的HttpProxy是如何处理HTTP请求的?

HttpProxy通过session对象处理请求的各个阶段,主要在process_new_http函数中进行。

Pingora的监听服务如何添加监听端口?

可以通过调用add_tcp方法将监听端口添加到服务中,例如lb.add_tcp("0.0.0.0:10080");

🏷️

标签

➡️

继续阅读