Виміряйте загальну затримку сеансу SSH


15

Чи є спосіб виміряти / повідомити загальну затримку в тунельному сеансі SSH?

Моя особлива настройка:

  • Клієнт (OS X + wifi маршрутизатор + ADSL модем)
  • Сервер шлюзу шлюзу піддається впливу Інтернету
  • Внутрішня ціль SSH, до якої я тунелю

Мені цікаво побачити затримку між консоллю на моїй локальній машині та кінцевою машиною, на якій я відкриваю сеанс.


Чому б не тунель SSH на перший сервер, а потім консоль SSH на другий сервер.
Берт

Відповіді:


6

Намагався зробити це сам і придумав це. Напевно, є більш простий спосіб, але це те, що я придумав.

Спочатку підготуйте труби, які використовуватимуться для того, щоб програма бенчмаркінгу спілкувалася через з'єднання SSH.

$ mkfifo /tmp/up /tmp/down

Потім встановіть з'єднання в режимі ControlMaster, не виконуючи жодної віддаленої команди. Це дозволяє нам автентифікувати автентифікацію з хостом. Після встановлення з'єднання SSH просто "висить" тут на передньому плані.

$ ssh $HOST -N -M -S /tmp/control

У паралельному терміналі виконайте віддалений catу фоновому режимі. Це буде наш ехо-сервер, затримку якого ми будемо вимірювати. Входи та виходи підключаються до FIFO:

$ ssh $HOST -S /tmp/control cat </tmp/up >/tmp/down &

А потім порівняйте невелику програму (відправте байт у upFIFO, отримайте байт від downFIFO):

$ python -m timeit -s 'import os' \
    'os.write(3, "z"); z=os.read(4, 1); assert z=="z", "got %s" % z' \
    3>/tmp/up 4</tmp/down
10 loops, best of 3: 24.6 msec per loop

Очевидно, цей показник показує затримку в зворотному напрямку. Якщо вам потрібно повторити експеримент, запустіть дві останні команди ( sshі python) ще раз.

Якщо щось здається не так, використовуйте -vпрапор SSH, щоб отримати більше результатів налагодження.


4

Я пропустив кілька кроків, запропонованих @ nicht-verstehen:

python -m timeit --setup 'import subprocess; p = subprocess.Popen(["ssh", "user@host", "cat"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=0)' 'p.stdin.write(b"z"); assert p.stdout.read(1) == b"z"'

Де

python -m timeitвиконує timeitмодуль Python.

-s/--setupОпція вказує , timeitякий оператор (и) для виконання перед кожним повтором.

subprocess.Popen(["ssh", "user@host", "cat"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=0)запуски ssh- виконання catна вашому хості - як дочірній / підпроцес, перенаправляючи його потоки вводу-виводу на об’єкти, схожі на файл Python. bufsize=0гарантує відсутність буферизації IO, що може спричинити очікування IO.

І для кожного циклу:
p.stdin.write(b"z")записує один байт дитині (по черзі через ssh to cat).
p.stdout.read(1)читає один байт від дитини. Твердження навколо нього перевіряє, чи той байт такий, як той, який ви йому написали.

Зводиться до того ж, але пропускає, створюючи названі труби ( mkfifo). Я помітив, що чим більше циклів ви запускаєте, тим швидше кожен цикл. Керуйте ним, використовуючи -n/--number:python -m timeit --number 50 ...


3

Дивіться sshpingутиліту: https://github.com/spook/sshping

Приклад:

# sshping 172.16.47.143
--- Login: 1725 msec
--- Minimum Latency: 4046 nsec
---  Median Latency: 11026 nsec  +/- 0 std dev
--- Average Latency: 178105 nsec
--- Maximum Latency: 8584886 nsec
---      Echo count: 1000 Bytes
---  Transfer Speed: 11694919 Bytes/second

# sshping --help
Usage: sshping [options] [user@]addr[:port]

  SSH-based ping that measures interactive character echo latency
  and file transfer throughput.  Pronounced "shipping".

Options:
  -c  --count NCHARS   Number of characters to echo, default 1000
  -e  --echocmd CMD    Use CMD for echo command; default: cat > /dev/null
  -h  --help           Print usage and exit
  -i  --identity FILE  Identity file, ie ssh private keyfile
  -p  --password PWD   Use password PWD (can be seen, use with care)
  -r  --runtime SECS   Run for SECS seconds, instead of count limit
  -t  --tests e|s      Run tests e=echo s=speed; default es=both
  -v  --verbose        Show more output, use twice for more: -vv

0

Моя ідея полягала в тому, щоб використовувати для цього послідовності термінальних запитів; Перевага полягає в тому, що це можна просто запустити на сервері, недоліком є ​​те, що він вимірює термінальну затримку, а не лише затримку підключення (але, мабуть, зазвичай, час відгуку вашого термінала буде незначним порівняно із затримками мережі) —можливо це навіть те, що ви маєте на увазі із загальною затримкою

#!/usr/bin/env python3
# Measure terminal latency (round-trip time) using "Query device code" command
from sys import stdin, stdout
import tty, termios, time

oldtty = termios.tcgetattr(stdin)
try:
    tty.setcbreak(stdout)

    runs = 10
    results = []
    for _ in range(runs):
        stdout.write("\x1b[c")
        stdout.flush()
        t1 = time.time()
        ch = stdin.read(1)
        assert(ch == '\x1b')
        t2 = time.time()
        while stdin.read(1) != 'c': # swallow rest of report
            continue
        latency = (t2 - t1) * 1000
        print('%.1fms' % (latency))
        results.append(latency)

    print()
    print('avg: %.1fms min: %.1fms max: %.1fms' % (
        sum(results) / runs,
        min(results),
        max(results)))
finally:
    termios.tcsetattr(stdin, termios.TCSADRAIN, oldtty)

(Для цього використовується "Запит коду пристрою", всі термінали, на які я намагався відповісти на це: xterm, alacritty, gnome-terminal. Я не можу сам спробувати це на MacOS. Так YMMV, якщо цього немає, ще один із запитів , які можуть запитувати певну інформацію про термінал, див. http://www.termsys.demon.co.uk/vtansi.htm )


1
Ця відповідь все ж може використовувати пояснення для тих, хто не так добре знайомий із внутрішніми питаннями (наприклад, чому \x1b[cбуло б сприятливо)
anx

не впевнений, що це сприятливо, я думаю, що це обґрунтоване обговорення: будь-який із "Status Device" termsysys.demon.co.uk/vtansi.htm працював би, якщо термінал підтримує його, і я не маю уявлення, що добре підтримується, але я здогадуюсь, що основним запитом статусу був би (працює навіть у голих костях Alacritty)
wump
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.