Блокировка ТЧП в Ржавском районе - PullRequest
0 голосов
/ 15 января 2020

Я пишу программу, которая выполняет команду на сервере, используя s sh и получает вывод.

Часть, которую я не понимаю, ниже в коде.

Если функция ждет, а затем возвращает строку, она работает как положено, но если работает с 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))
    });
}

1 Ответ

0 голосов
/ 17 января 2020

Чтобы отладить такую ​​проблему, вам нужно проанализировать, где ваша программа тратит свое время. Есть способы: профилирование и анализ TCP-соединений.
Я предлагаю вам 2 способа, потому что это намного проще. Дамп траффи c с Wireshark, отфильтруйте его по порту 22. После этого используйте вкладку сеансы связи . Здесь вы можете отсортировать соединения по времени и увидеть, что программа не ускоряется из-за отсутствия ограничения по времени для соединения s sh.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...