简体   繁体   English

Rust rayon tcp 阻塞

[英]Rust rayon tcp blocking

I'm writing a program which executes a command on server using ssh and gets the output.我正在编写一个程序,该程序使用 ssh 在服务器上执行命令并获取输出。

The part I don't understand is lower in the code.我不明白的部分在代码中较低。

If the function waits and then returns a string, it works as expected, but if work with TCP it starts performing very bad.如果函数等待然后返回一个字符串,它会按预期工作,但如果使用 TCP,它开始表现得很糟糕。 I expect that using 100 threads on 100 hosts will perform 100 times faster, because will open 100 sockets simultaneously.我希望在 100 台主机上使用 100 个线程会快 100 倍,因为会同时打开 100 个套接字。

In the sleep version, changing poolThreads directly affects the time of execution.在 sleep 版本中,更改poolThreads直接影响执行时间。 In the version with TCP streams, changing pool from 1 to 100 with 100 hosts only speeds it up from 90 to 67 because some hosts are offline.在带有 TCP 流的版本中,将pool从 1 更改为 100 与 100 个主机只会将其从 90 加速到 67,因为某些主机处于离线状态。

I read the documentation, but cannot find anything to help me.我阅读了文档,但找不到任何帮助我的东西。

use clap::{App, Arg};
use rayon::prelude::*;
use rayon::ThreadPoolBuilder;
use ssh2::Session;
use std::fmt::Display;
use std::io::prelude::*;
use std::io::{BufReader, Read};
use std::net::{TcpStream, ToSocketAddrs};
use std::thread::sleep;
use std::time::Duration;

fn process_host<A>(hostname: A) -> Result<String, String>
where
    A: ToSocketAddrs + Display,
{
    sleep(Duration::from_secs(1));
    return Ok(hostname.to_string());
    // here is the problem
    // -----------------------------------------------------------
    let tcp = match TcpStream::connect(&hostname) {
        Ok(a) => a,
        Err(e) => {
            return Err(format!("{}:{}", hostname, e).to_string());
        }
    };
    let mut sess = match Session::new() {
        Ok(a) => a,
        Err(e) => {
            // todo logging
            return Err(format!("{}:{}", hostname, e).to_string());
        }
    };
    sess.set_tcp_stream(tcp);
    match sess.handshake() {
        Ok(a) => a,
        Err(e) => {
            return Err(format!("{}:{}", hostname, e).to_string());
        }
    };
    Ok(format!("{}", hostname))
}


fn main() {

    let hosts = vec!["aaaaa:22", "bbbbbbb:22"];
    let pool = ThreadPoolBuilder::new()
        .num_threads(10)
        .build()
        .expect("failed creating pool");
    pool.install(|| {
        hosts
            .par_iter()
            .map(|x| process_host(x))
            .for_each(|x| println!("{:?}", x))
    });
}

To debug a such a problem, you need to analysis, where your program wastes its time.要调试这样的问题,您需要分析您的程序在哪里浪费了时间。 There're to ways: profiling and analyzing of TCP connections.有方法:分析和分析 TCP 连接。
I suggest you 2 way, cause it's much easier.我建议你 2 种方式,因为它更容易。 Dump traffic with wireshark, filter it by port 22. After this, use conversations tab.使用wireshark 转储流量,通过端口22 对其进行过滤。之后,使用对话选项卡。 Here you can sort connections by time, and can see, that program doesn't speedup because of no time limit for ssh connection.在这里您可以按时间对连接进行排序,并且可以看到,由于 ssh 连接没有时间限制,该程序没有加速。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM