< 返回版块

lsk569937453 发表于 2024-03-01 09:17

Cargo.toml如下

[package]
name = "hyper_1"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[[bin]]
name = "silverwind"
path = "src/main.rs"
[dependencies]
hyper = { version = "1.2.0", features = ["full"] }
tokio = { version = "1.36.0", features = ["full"] }
hyper-util = { version = "0.1.3", features = ["full"] }
bytes = "1"
http-body-util = { version = "0.1.0"}
anyhow = { version = "1.0.80", default-features = false }
log4rs = "1.3.0"

main.rs如下

use anyhow::anyhow;
use hyper::{server::conn::http1, service::service_fn};
use std::net::SocketAddr;
use tokio::net::TcpListener;

use bytes::Bytes;
use http_body_util::{combinators::BoxBody, BodyExt, Full};
use hyper::body::Incoming;

use hyper::{Request, Response, Uri};
use hyper_util::client::legacy::{connect::HttpConnector, Client};
use hyper_util::rt::TokioIo;
use std::convert::Infallible;
use tokio::runtime;
#[tokio::main]
async fn main() {
    if let Err(err) = start_with_error().await {
        println!("Failed to serve the connection: {:?}", err);
    }
}
async fn check(uri: Uri) -> Result<(), anyhow::Error> {
    let backend_path = uri.path_and_query().ok_or(anyhow!(""))?.as_str();
    Ok(())
}
async fn do_req(
    client: Client<HttpConnector, BoxBody<Bytes, Infallible>>,
    req: Request<BoxBody<Bytes, Infallible>>,
) -> Result<Response<BoxBody<Bytes, Infallible>>, Infallible> {
    let uri = req.uri().clone();
    check(uri)
        .await
        .map_err(|_| -> Infallible { unreachable!() })?;
    let response_incoming = client
        .request(req)
        .await
        .map_err(|_| -> Infallible { unreachable!() })?;
    let res = response_incoming
        .map(|b| b.boxed())
        .map(|item| item.map_err(|_| -> Infallible { unreachable!() }).boxed());
    Ok(res)
}
async fn start_with_error() -> Result<(), Box<dyn std::error::Error>> {
    let in_addr: SocketAddr = ([0, 0, 0, 0], 6667).into();
    let out_addr_clone = "http://backend:8080";
    let listener = TcpListener::bind(in_addr).await?;

    println!("Listening on http://{}", in_addr);
    println!("Proxying on http://{}", out_addr_clone);
    let client = Client::builder(hyper_util::rt::TokioExecutor::new()).build(HttpConnector::new());
    loop {
        let (stream, _) = listener.accept().await?;
        let io = TokioIo::new(stream);
        let client_clone = client.clone();
        let service = service_fn(move |mut req: Request<Incoming>| {
            let client_clone1 = client_clone.clone();
            let uri_now: hyper::http::uri::Uri = out_addr_clone.parse().unwrap();
            *req.uri_mut() = uri_now.clone();
            let req = req.map(|item| item.map_err(|_| -> Infallible { unreachable!() }).boxed());
            do_req(client_clone1, req)
        });

        tokio::task::spawn(async move {
            if let Err(err) = http1::Builder::new()
                .preserve_header_case(true)
                .title_case_headers(true)
                .serve_connection(io, service)
                .await
            {
                println!("Failed to serve the connection: {:?}", err);
            }
        });
    }
}

加了log4rs = "1.3.0"依赖之后,gateway的tps大概是40000。 去除了log4rs = "1.3.0"依赖之后,gateway的tps大概是70000。

tps差的有点多,主要是代码都没变过。代码已经放到https://gist.github.com/lsk569937453/b42a8cfce21bd20c5da8737db1f5a1b1.

评论区

写评论
作者 lsk569937453 2024-03-04 08:51

方案1:工程源代码中不使用anyhow这个crates就好了。工程依赖的crates中如果有anyhow这个依赖的话不会有问题

方案2:工程源代码中使用anyhow这个crates且不开启std,并且第三方依赖的crates不能依赖开启std的anyhow。

--
👇
lithbitren: 所以这个最终咋解决啊

lithbitren 2024-03-03 01:15

所以这个最终咋解决啊

作者 lsk569937453 2024-03-02 12:05

应该不是这个问题,anyhow我换成anyhow = { version = "1.0.70"},还是有同样的问题

Bai-Jinlin 2024-03-01 19:44

查了下你还别说,已经有人提了,是backtrack的问题,https://github.com/dtolnay/anyhow/issues/347

--
👇
Ryan-Git: 去提个 issue?这差距有点大啊。看看火焰图呢

Ryan-Git 2024-03-01 18:44

去提个 issue?这差距有点大啊。看看火焰图呢

作者 lsk569937453 2024-03-01 17:01

查到问题了,是由于log4rs引入了anyhow = { version = "1.0.xx"}导致的。由于项目里面还有个依赖delay_timer = "0.11.5"也引入了anyhow = { version = "1.0.xx" }。所以把这两个都排除掉就没有问题了。 至于为什么anyhow会引起性能快速下降,我也不知道。

asuper 2024-03-01 09:35

代码中没有任何地方引用这个库,应该不是库中的代码影响的,我猜是不是加入这个库,导致你其他依赖的版本变化了,而其中某个库的性能有差异,建议对比一下看看

1 共 7 条评论, 1 页