1 个不稳定版本

0.2.0 2024年5月12日

#1006HTTP服务器

Apache-2.0

24KB
216 代码行

Pingora上游模块

此crate帮助配置Pingora的上游功能。它在与允许条件应用多个上游配置的virtual-hosts-module crate结合使用时最有用。

目前仅提供了一个配置选项:upstream (作为命令行选项的--upstream)。值应该是类似于 http://127.0.0.1:8081https://example.com 的URL。

支持的URL方案是 http://https://。除了方案之外,只有主机名和端口号被考虑。如果存在,URL的其他部分将被忽略。

UpstreamHandler 类型必须在 request_filterupstream_peer Pingora代理阶段中调用。前者选择一个上游节点,并通过添加适当的 Host 头部来修改请求。后者检索先前选择的上游节点。

use async_trait::async_trait;
use upstream_module::UpstreamHandler;
use module_utils::RequestFilter;
use pingora_core::Error;
use pingora_core::upstreams::peer::HttpPeer;
use pingora_proxy::{ProxyHttp, Session};

pub struct MyServer {
    upstream_handler: UpstreamHandler,
}

#[async_trait]
impl ProxyHttp for MyServer {
    type CTX = <UpstreamHandler as RequestFilter>::CTX;
    fn new_ctx(&self) -> Self::CTX {
        UpstreamHandler::new_ctx()
    }

    async fn request_filter(
        &self,
        session: &mut Session,
        ctx: &mut Self::CTX,
    ) -> Result<bool, Box<Error>> {
        // Select upstream peer according to configuration. This could be called based on some
        // conditions.
        self.upstream_handler.handle(session, ctx).await
    }

    async fn upstream_peer(
        &self,
        session: &mut Session,
        ctx: &mut Self::CTX,
    ) -> Result<Box<HttpPeer>, Box<Error>> {
        // Return previously selected peer if any
        UpstreamHandler::upstream_peer(session, ctx).await
    }
}

要创建一个处理器,您通常会从配置文件中读取其配置,可选地结合命令行选项。以下代码将相应地扩展Pingora的常规配置文件和命令行选项。

use upstream_module::{UpstreamConf, UpstreamHandler, UpstreamOpt};
use module_utils::{merge_conf, merge_opt, FromYaml};
use pingora_core::server::Server;
use pingora_core::server::configuration::{Opt as ServerOpt, ServerConf};
use structopt::StructOpt;

#[merge_opt]
struct Opt {
    server: ServerOpt,
    upstream: UpstreamOpt,
}

#[merge_conf]
struct Conf {
    server: ServerConf,
    upstream: UpstreamConf,
}

let opt = Opt::from_args();
let mut conf = opt
    .server
    .conf
    .as_ref()
    .and_then(|path| Conf::load_from_yaml(path).ok())
    .unwrap_or_else(Conf::default);
conf.upstream.merge_with_opt(opt.upstream);

let mut server = Server::new_with_opt_and_conf(opt.server, conf.server);
server.bootstrap();

let upstream_handler: UpstreamHandler = conf.upstream.try_into().unwrap();

有关完整和更现实的代码,请参阅存储库中的 virtual-hosts 示例。

依赖项

~37–52MB
~1M SLoC