Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

may_http耗时不符合预期 #92

Closed
loongs-zhang opened this issue Feb 2, 2022 · 5 comments
Closed

may_http耗时不符合预期 #92

loongs-zhang opened this issue Feb 2, 2022 · 5 comments

Comments

@loongs-zhang
Copy link

loongs-zhang commented Feb 2, 2022

发起10次http请求,耗时是10+s,而不是1+s。这是我的toml:

[dependencies]
docopt = "1"
serde = "1"
serde_derive = "1"
http = "0.2"
may = { git = "https://github.com/Xudong-Huang/may.git" }
may_http = { git = "https://github.com/rust-may/may_http" }

以下是发起请求的代码:

#[macro_use]
extern crate may;
extern crate may_http;

use std::io::{self, Read};
use std::ops::RangeInclusive;
use std::thread::Thread;
use std::time::{Duration, SystemTime, UNIX_EPOCH};

use http::Uri;
use may::coroutine::*;
use may_http::client::*;

fn main() -> io::Result<()> {
    // see https://github.com/dragon-zhang/kotlin-study/blob/master/provider/src/main/kotlin/com/example/demo/TestController.kt
    let uri: Uri = "http://127.0.0.1:8081/rust".parse().unwrap();
    let mut client = {
        let host = uri.host().unwrap_or("127.0.0.1");
        let port = uri.port_u16().unwrap_or(80);
        HttpClient::connect((host, port))?
    };

    let all_start = current_time_millis();
    let mut s = String::new();
    for i in 0..10 {
        let uri = uri.clone();
        let start = current_time_millis();
        let mut rsp = client.get(uri)?;
        let end1 = current_time_millis();
        rsp.read_to_string(&mut s)?;
        let end2 = current_time_millis();
        println!("{} get response={}, request cost{}ms read cost{}ms",
                 i, s, end1 - start, end2 - end1);
        s.clear();
    }
    println!("all cost{}ms", current_time_millis() - all_start);
    Ok(())
}

pub fn current_time_millis() -> i64 {
    let since_the_epoch = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .expect("Time went backwards");
    let ms = since_the_epoch.as_secs() as i64 * 1000i64 + (since_the_epoch.subsec_nanos() as f64 / 1_000_000.0) as i64;
    return ms;
}

下面是控制台输出的结果:

0 get response={"param":"rust"}, request cost1014ms read cost0ms
1 get response={"param":"rust"}, request cost1010ms read cost0ms
2 get response={"param":"rust"}, request cost1007ms read cost0ms
3 get response={"param":"rust"}, request cost1004ms read cost0ms
4 get response={"param":"rust"}, request cost1003ms read cost0ms
5 get response={"param":"rust"}, request cost1004ms read cost0ms
6 get response={"param":"rust"}, request cost1008ms read cost0ms
7 get response={"param":"rust"}, request cost1010ms read cost0ms
8 get response={"param":"rust"}, request cost1010ms read cost0ms
9 get response={"param":"rust"}, request cost1009ms read cost0ms
all cost10080ms

可以看到,使用may_http发起10次请求,总共耗时10+ s,如果用go语言编写相同的逻辑,耗时在1.1s以内,因此这里到底是may有问题,还是may_http有问题?@Xudong-Huang

@loongs-zhang
Copy link
Author

处理http://127.0.0.1:8081/rust的代码如下,大概逻辑就是睡眠1s,然后返回给客户端。

import com.alibaba.fastjson.JSON
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController

@RestController
class TestController {

    @GetMapping("/rust")
    fun rust(@RequestParam(defaultValue = "rust") param: String?): String? {
        try {
            //模拟耗时操作
            Thread.sleep(1000)
        } catch (e: InterruptedException) {
            e.printStackTrace()
        }
        val map = HashMap<String, String?>()
        map["param"] = param
        return JSON.toJSONString(map)
    }
}

@Xudong-Huang
Copy link
Owner

你的逻辑就是一个一个的请求啊,没有任何并发操作

for i in 0..10 {
        let uri = uri.clone();
        let start = current_time_millis();
        let mut rsp = client.get(uri)?;
        let end1 = current_time_millis();
        rsp.read_to_string(&mut s)?;
        let end2 = current_time_millis();
        println!("{} get response={}, request cost{}ms read cost{}ms",
                 i, s, end1 - start, end2 - end1);
        s.clear();
    }

@loongs-zhang
Copy link
Author

loongs-zhang commented Feb 8, 2022

你的逻辑就是一个一个的请求啊,没有任何并发操作

for i in 0..10 {
        let uri = uri.clone();
        let start = current_time_millis();
        let mut rsp = client.get(uri)?;
        let end1 = current_time_millis();
        rsp.read_to_string(&mut s)?;
        let end2 = current_time_millis();
        println!("{} get response={}, request cost{}ms read cost{}ms",
                 i, s, end1 - start, end2 - end1);
        s.clear();
    }

如果要并行请求,直接用go!宏来包一下就好了?看了下没有直接发起异步请求的方法。

@Xudong-Huang
Copy link
Owner

可以用join!宏,也可以使用go!的返回值进行统一等待结束

@loongs-zhang
Copy link
Author

好的,感谢。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants