Zmierz całkowite opóźnienie sesji SSH

15

Czy istnieje sposób pomiaru / zgłaszania całkowitego opóźnienia w tunelowanej sesji SSH?

Moja szczególna konfiguracja to:

  • Klient (OS X + router Wi-Fi + modem ADSL)
  • Serwer SSH bramy narażony na działanie Internetu
  • Wewnętrzny cel SSH, do którego tuneluję

Chcę zobaczyć opóźnienie między konsolą na moim komputerze lokalnym a komputerem końcowym, na którym mam otwartą sesję.

rozdymka tygrysia
źródło
Dlaczego nie tunelować SSH do pierwszego serwera, a następnie konsoli SSH do drugiego serwera.
Bert

Odpowiedzi:

6

Próbowałem to zrobić sam i wymyśliłem to. Prawdopodobnie istnieje prostszy sposób, ale to właśnie wymyśliłem.

Najpierw przygotuj potoki, które będą używane do komunikacji programu porównawczego za pośrednictwem połączenia SSH.

$ mkfifo /tmp/up /tmp/down

Następnie nawiąż połączenie w trybie ControlMaster bez wykonywania polecenia zdalnego. Pozwala nam to na interaktywną identyfikację z hostem. Po ustanowieniu połączenia SSH po prostu „zawiesi się” na pierwszym planie.

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

W terminalu równoległym uruchom zdalnie catw tle. Będzie to nasz serwer echa, którego opóźnienie będziemy mierzyć. Wejścia i wyjścia są podłączone do FIFO:

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

A następnie przetestuj mały program (wyślij bajt do upFIFO, odbierz bajt od 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

Miara oczywiście pokazuje opóźnienie w obie strony. Jeśli chcesz powtórzyć eksperyment, ponownie uruchom ostatnie dwa polecenia ( sshi python).

Jeśli coś pójdzie nie tak, użyj -vflagi SSH, aby uzyskać więcej wyników debugowania.

Nicht Verstehen
źródło
4

Pominąłem kilka kroków sugerowanych przez @ 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"'

Gdzie

python -m timeitwykonuje timeitmoduł Python.

Ta -s/--setupopcja informuje, timeitktóre instrukcje należy wykonać przed każdym powtórzeniem.

subprocess.Popen(["ssh", "user@host", "cat"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=0)uruchamia się ssh- uruchamiając catna twoim hoście - jako podrzędny / podproces, przekierowując swoje strumienie IO do obiektów podobnych do plików Pythona. bufsize=0upewnia się, że żadne IO nie jest buforowane, co może powodować, że IO czeka.

I dla każdej pętli:
p.stdin.write(b"z")zapisuje jeden bajt do dziecka (z kolei przez ssh do cat).
p.stdout.read(1)czyta pojedynczy bajt od dziecka. Twierdzenie wokół niego sprawdza, czy ten bajt jest taki sam, jak napisany do niego.

Sprowadza się do tego samego, ale pomija tworzenie nazwanych potoków ( mkfifo). Zauważyłem, że im więcej uruchomisz pętli, tym szybciej będzie każda pętla. Kontroluj za pomocą -n/--number:python -m timeit --number 50 ...

hzpc-joostk
źródło
3

Zobacz sshpingnarzędzie: https://github.com/spook/sshping

Przykład:

# 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
Wujek Spook
źródło
0

Moim pomysłem było użycie do tego terminalnych zapytań; zaletą jest to, że można to po prostu uruchomić na serwerze, wadą jest to, że mierzy opóźnienie terminala, nie tylko opóźnienie połączenia (ale myślę, że zwykle czas odpowiedzi twojego terminalu będzie nieznaczny w porównaniu do opóźnień sieciowych) - może to nawet masz na myśli ogólne opóźnienie

#!/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)

(Używa "Zapytania o kod urządzenia", wszystkie terminale, na które próbowałem odpowiedzieć: xterm, alacritty, gnome-terminal. Nie mogę sam tego wypróbować na MacOS. Więc YMMV, jeśli nie, kolejna prośba które sprawdzają niektóre informacje o terminalu mogą działać, patrz http://www.termsys.demon.co.uk/vtansi.htm )

wump
źródło
1
Ta odpowiedź mogłaby nadal \x1b[czawierać wyjaśnienie dla osób, które nie są tak zaznajomione z wewnętrznymi elementami tty (np. Dlaczego miałby być korzystny)
anx
nie jestem pewien, czy jest to korzystne, myślę, że jest to ważna dyskusja: każdy z „Device Status” Termsys.demon.co.uk/vtansi.htm działałby, biorąc pod uwagę, że terminal go obsługuje i nie mam pojęcia, co jest dobrze obsługiwane, ale Domyślam się, że podstawowym zapytaniem o status byłoby (nawet działa w czystej postaci Alacritty)
wump