0

我正在编写一个程序,它使用 ssh 在服务器上执行命令并获取输出。

我不明白的部分在代码中较低。

如果函数等待然后返回一个字符串,它会按预期工作,但如果使用 TCP,它会开始表现得很糟糕。我希望在 100 台主机上使用 100 个线程的速度会提高 100 倍,因为会同时打开 100 个套接字。

在睡眠版本中,更改poolThreads直接影响执行时间。在带有 TCP 流的版本中,pool从 1 更改为 100 有 100 个主机只会将其从 90 加速到 67,因为某些主机处于脱机状态。

我阅读了文档,但找不到任何可以帮助我的东西。

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))
    });
}
4

1 回答 1

0

要调试这样的问题,您需要分析您的程序在哪里浪费了时间。方法有:分析和分析 TCP 连接。
我建议你 2 方式,因为它更容易。使用wireshark转储流量,按端口22过滤。之后,使用对话 选项卡。在这里您可以按时间对连接进行排序,并且可以看到,该程序没有加速,因为 ssh 连接没有时间限制。

于 2020-01-17T18:06:16.520 回答