Mengukur latensi total sesi SSH


15

Apakah ada cara untuk mengukur / melaporkan latensi keseluruhan dalam sesi SSH tunneled?

Pengaturan khusus saya adalah:

  • Klien (OS X + router wifi + modem ADSL)
  • Gateway SSH server terpapar ke Internet
  • Target SSH internal yang saya tunneling

Saya tertarik melihat latensi antara konsol di komputer lokal saya dan mesin terakhir tempat sesi dibuka.


Mengapa SSH tidak terowongan ke server pertama, dan kemudian SSH konsol ke server kedua.
Bert

Jawaban:


6

Sedang mencoba melakukan ini sendiri dan datang dengan ini. Mungkin ada cara yang lebih sederhana, tetapi inilah yang saya temukan.

Pertama, siapkan pipa yang akan digunakan untuk membuat program pembandingan berkomunikasi melalui koneksi SSH.

$ mkfifo /tmp/up /tmp/down

Kemudian buat koneksi dalam mode ControlMaster tanpa menjalankan perintah jarak jauh. Ini memungkinkan kami untuk mengotentikasi dengan host secara interaktif. Setelah koneksi dibuat, SSH hanya akan "menggantung" di sini di latar depan.

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

Di terminal paralel, jalankan remote catdi latar belakang. Ini akan menjadi server gema kami yang latensi akan kami ukur. Input dan output terhubung ke FIFO:

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

Dan kemudian melakukan benchmark program kecil (mengirim byte ke upFIFO, menerima byte dari 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

Ukurannya jelas menunjukkan latensi bolak-balik. Jika Anda perlu mengulang percobaan, jalankan dua perintah terakhir ( sshdan python) lagi.

Jika ada yang tidak beres, gunakan -vtanda SSH untuk mendapatkan lebih banyak hasil debug.


4

Saya melewatkan beberapa langkah yang disarankan oleh @ 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"'

Dimana

python -m timeitmengeksekusi timeitmodul Python.

The -s/--setuppilihan memberitahu timeityang pernyataan (s) untuk menjalankan sebelum setiap ulangi.

subprocess.Popen(["ssh", "user@host", "cat"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=0)meluncurkan ssh- mengeksekusi catpada host Anda - sebagai anak / subproses, mengarahkan aliran IO-nya ke objek seperti file Python. bufsize=0memastikan tidak ada IO yang disangga, yang dapat menyebabkan IO menunggu.

Dan untuk setiap loop:
p.stdin.write(b"z")menulis satu byte ke anak (pada gilirannya melalui ssh ke cat).
p.stdout.read(1)membaca satu byte dari anak. Pernyataan di sekitarnya menguji apakah byte itu sama dengan yang Anda tulis.

Mendidih ke hal yang sama, tetapi melompat membuat pipa bernama ( mkfifo). Saya perhatikan bahwa semakin banyak loop yang Anda jalankan, semakin cepat setiap loopnya. Kontrol menggunakan -n/--number:python -m timeit --number 50 ...


3

Lihat sshpingutilitas: https://github.com/spook/sshping

Contoh:

# 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

Gagasan saya adalah menggunakan urutan kueri terminal untuk ini; keuntungannya adalah ini hanya dapat dijalankan di server, kerugiannya adalah ia mengukur latensi terminal, tidak hanya latensi koneksi (tetapi saya kira, biasanya, waktu respons terminal Anda akan diabaikan dibandingkan dengan keterlambatan jaringan) —mungkin ini bahkan yang Anda maksud dengan latensi keseluruhan

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

(Ini menggunakan "Device Code Query", semua terminal yang saya coba balas ini: xterm, alacritty, gnome-terminal. Saya sendiri tidak dapat mencoba ini pada MacOS. Jadi YMMV, jika yang ini tidak, yang lain dari permintaan yang menginterogasi beberapa informasi tentang terminal mungkin berfungsi, lihat http://www.termsys.demon.co.uk/vtansi.htm )


1
Jawaban ini masih dapat menggunakan beberapa penjelasan bagi mereka yang tidak terbiasa dengan tty internal (misalnya, mengapa \x1b[cakan menguntungkan)
anx

tidak yakin itu menguntungkan, saya pikir ini adalah diskusi yang valid: apa pun dari "Status Perangkat" termsys.demon.co.uk/vtansi.htm akan berfungsi, mengingat terminal mendukungnya, dan saya tidak tahu apa yang didukung dengan baik, tetapi saya duga adalah bahwa query statusnya dasar akan (bahkan bekerja di telanjang-tulang Alacritty)
wump
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.