快速运行

1
2
3
cargo new mypingora
cargo add async-trait
cargo add pingora --features=lb

main.rs

1
2
3
4
5
6
7
8
9
10
use async_trait::async_trait;
use pingora::prelude::*;
use std::sync::Arc;


fn main() {
let mut my_server = Server::new(None).unwrap();
my_server.bootstrap();
my_server.run_forever();
}

添加一个使用RR策略的负载均衡器

1
pub struct LB(Arc<LoadBalancer<RoundRobin>>);

实现ProxyHttp反向代理接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#[async_trait]
impl ProxyHttp for LB {

/// For this small example, we don't need context storage
type CTX = ();
fn new_ctx(&self) -> () {
()
}

async fn upstream_peer(&self, _session: &mut Session, _ctx: &mut ()) -> Result<Box<HttpPeer>> {
let upstream = self.0
.select(b"", 256) // hash doesn't matter for round robin
.unwrap();

println!("upstream peer is: {upstream:?}");

// Set SNI to one.one.one.one
let peer = Box::new(HttpPeer::new(upstream, true, "one.one.one.one".to_string()));
Ok(peer)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
impl ProxyHttp for LB {
// ...
async fn upstream_request_filter(
&self,
_session: &mut Session,
upstream_request: &mut RequestHeader,
_ctx: &mut Self::CTX,
) -> Result<()> {
upstream_request.insert_header("Host", "one.one.one.one").unwrap();
Ok(())
}
}

创建反向代理Service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
fn main() {
let mut my_server = Server::new(None).unwrap();
my_server.bootstrap();

let upstreams =
LoadBalancer::try_from_iter(["1.1.1.1:443", "1.0.0.1:443"]).unwrap();

let mut lb = http_proxy_service(&my_server.configuration, LB(Arc::new(upstreams)));
lb.add_tcp("0.0.0.0:6188");

my_server.add_service(lb);

my_server.run_forever();
}

使用cargo run即可运行起来

我们可以使用curl访问这个反向代理服务

1
curl 127.0.0.1:6188 -svo /dev/null

参考资料

官方用户文档目录

反向代理工作的各个阶段状态图