Messen Sie die Gesamtlatenz der SSH-Sitzung

15

Gibt es eine Möglichkeit, die Gesamtlatenz in einer getunnelten SSH-Sitzung zu messen / zu melden ?

Mein spezielles Setup ist:

  • Client (OS X + WLAN-Router + ADSL-Modem)
  • Gateway-SSH-Server, der dem Internet ausgesetzt ist
  • Internes SSH-Ziel, zu dem ich tunnele

Ich möchte die Latenz zwischen der Konsole auf meinem lokalen Computer und dem letzten Computer sehen, auf dem die Sitzung geöffnet ist.

Kugelfisch
quelle
Warum nicht SSH-Tunnel zum ersten Server und dann SSH-Konsole zum zweiten Server?
Bert

Antworten:

6

Ich habe versucht, dies selbst zu tun, und habe es mir ausgedacht. Wahrscheinlich gibt es einen einfacheren Weg, aber das habe ich mir ausgedacht.

Bereiten Sie zunächst Pipes vor, mit denen das Benchmarking-Programm über die SSH-Verbindung kommuniziert.

$ mkfifo /tmp/up /tmp/down

Stellen Sie dann im ControlMaster-Modus eine Verbindung her, ohne einen Remote-Befehl auszuführen. Auf diese Weise können wir uns interaktiv beim Host authentifizieren. Nachdem die Verbindung hergestellt wurde, "hängt" SSH hier im Vordergrund.

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

Führen Sie catin einem parallelen Terminal remote im Hintergrund aus. Es wird unser Echoserver sein, dessen Latenz wir messen werden. Ein- und Ausgänge sind mit FIFOs verbunden:

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

Und dann ein kleines Programm benchmarken (ein Byte an upFIFO senden , ein Byte vom downFIFO empfangen ):

$ 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

Das Maß zeigt offensichtlich die Round-Trip-Latenz. Wenn Sie den Test wiederholen müssen, führen Sie die letzten beiden Befehle ( sshund python) erneut aus.

Wenn etwas schief zu gehen scheint, verwenden Sie das SSH- -vFlag, um mehr Debugging-Ausgaben zu erhalten.

Nicht Verstehen
quelle
4

Ich habe einige von @ nicht-verstehen vorgeschlagene Schritte übersprungen:

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"'

Wo

python -m timeitFührt das timeitPython-Modul aus.

Die -s/--setupOption gibt an, timeitwelche Anweisung (en) vor jeder Wiederholung ausgeführt werden sollen.

subprocess.Popen(["ssh", "user@host", "cat"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=0)Kutter ssh- Ausführung catdateiähnliche Objekte als Kind / subprocess, seine IO - Streams zu Python Umleitung - auf dem Host. bufsize=0Stellt sicher, dass keine E / A gepuffert ist, was zu E / A-Wartezeiten führen kann.

Und für jede Schleife:
p.stdin.write(b"z")Schreibt ein einzelnes Byte an das Kind (wiederum durch ssh bis cat).
p.stdout.read(1)Liest ein einzelnes Byte vom Kind. Die Behauptung dahinter prüft, ob dieses Byte mit dem Byte übereinstimmt, das Sie geschrieben haben.

Läuft auf dasselbe hinaus, überspringt jedoch das Erstellen der Named Pipes ( mkfifo). Mir ist aufgefallen, dass jede Schleife umso schneller ist, je mehr Schleifen Sie ausführen. Steuern Sie es mit -n/--number:python -m timeit --number 50 ...

hzpc-joostk
quelle
3

Siehe das sshpingDienstprogramm: https://github.com/spook/sshping

Beispiel:

# 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
Onkel Spook
quelle
0

Meine Idee war, dafür Terminal-Abfragesequenzen zu verwenden. Der Vorteil ist, dass dies einfach auf dem Server ausgeführt werden kann. Der Nachteil ist, dass die Terminal-Latenz gemessen wird, nicht nur die Latenz der Verbindung (aber die Antwortzeit Ihres Terminals ist im Vergleich zu Netzwerkverzögerungen in der Regel vernachlässigbar) das ist auch das, was Sie mit meiner Gesamtlatenz

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

(Hierfür wird "Gerätecode-Abfrage" verwendet. Alle Terminals, die ich versucht habe, antworten darauf: xterm, alacritty, gnome-terminal. Ich kann dies unter MacOS nicht selbst ausprobieren. Wenn dies nicht der Fall ist, ist dies eine weitere Anforderung von YMMV Diese Abfrage einiger Informationen über das Terminal funktioniert möglicherweise (siehe http://www.termsys.demon.co.uk/vtansi.htm ).

wump
quelle
1
Diese Antwort könnte noch eine Erklärung für diejenigen gebrauchen, die nicht so vertraut mit tty Interna sind (z. B. warum \x1b[cwäre günstig)
Angst
Ich bin mir nicht sicher, ob es günstig ist. Ich denke, es ist eine gültige Diskussion: Jede der "Gerätestatus" -Begriffe unter termsys.demon.co.uk/vtansi.htm würde funktionieren, vorausgesetzt , das Terminal unterstützt sie und ich habe keine Ahnung, was gut unterstützt wird, aber Meine Vermutung ist, dass die grundlegende Statusabfrage wäre (funktioniert sogar bei Alacritty mit nackten Knochen)
wump