วัดเวลาแฝงทั้งหมดของเซสชัน SSH


15

มีวิธีในการวัด / รายงานเวลาหน่วงโดยรวมในเซสชัน SSH ที่อุโมงค์หรือไม่

การตั้งค่าเฉพาะของฉันคือ:

  • ไคลเอนต์ (OS X + เราเตอร์ไร้สาย + โมเด็ม ADSL)
  • เซิร์ฟเวอร์ Gateway SSH เปิดเผยกับอินเทอร์เน็ต
  • เป้าหมาย SSH ภายในที่ฉันกำลังขุด

ฉันสนใจที่จะเห็นความล่าช้าระหว่างคอนโซลในเครื่องของฉันกับเครื่องสุดท้ายที่ฉันเปิดเซสชัน


ทำไมไม่ใช่ SSH tunnel ไปยังเซิร์ฟเวอร์แรกจากนั้นคอนโซล SSH ไปยังเซิร์ฟเวอร์ที่สอง
Bert

คำตอบ:


6

พยายามทำสิ่งนี้ด้วยตนเองและคิดสิ่งนี้ขึ้นมา อาจมีวิธีที่ง่ายกว่า แต่นี่คือสิ่งที่ฉันมาด้วย

ก่อนอื่นให้เตรียมท่อที่จะใช้เพื่อให้โปรแกรมการเปรียบเทียบทำการสื่อสารผ่านการเชื่อมต่อ SSH

$ mkfifo /tmp/up /tmp/down

จากนั้นสร้างการเชื่อมต่อในโหมด ControlMaster โดยไม่ต้องดำเนินการคำสั่งระยะไกลใด ๆ สิ่งนี้ช่วยให้เราสามารถตรวจสอบกับโฮสต์แบบโต้ตอบ หลังจากสร้างการเชื่อมต่อแล้ว SSH จะ "หยุด" ที่นี่ในเบื้องหน้า

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

ในเทอร์มินัลแบบขนานให้เรียกใช้รีโมตcatในพื้นหลัง มันจะเป็นเซิร์ฟเวอร์ echo ของเราซึ่งเราจะทำการวัดความหน่วง อินพุตและเอาต์พุตเชื่อมต่อกับ 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ซึ่งคำสั่ง (s) ที่จะดำเนินการก่อนที่จะทำซ้ำ

subprocess.Popen(["ssh", "user@host", "cat"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=0)เรียกใช้งานssh- ดำเนินการcatกับโฮสต์ของคุณ - ในฐานะลูก / กระบวนการย่อยเปลี่ยนเส้นทางสตรีม IO ไปยังวัตถุที่เหมือนไฟล์ Python bufsize=0ทำให้แน่ใจว่าไม่มีบัฟเฟอร์ของ IO ซึ่งอาจทำให้ IO รออยู่

และสำหรับแต่ละลูป:
p.stdin.write(b"z")เขียนหนึ่งไบต์ไปที่ลูก (หันผ่าน ssh ไป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)

(นี่ใช้ "Device Code Query" เทอร์มินัลทั้งหมดที่ฉันพยายามตอบกลับนี้: xterm, alacritty, gnome-terminal ฉันไม่สามารถลองสิ่งนี้บน MacOS ได้ดังนั้น YMMV ถ้าสิ่งนี้ไม่ได้ สอบปากคำข้อมูลบางอย่างเกี่ยวกับสถานีอาจทำงานดูhttp://www.termsys.demon.co.uk/vtansi.htm )


1
คำตอบนี้ยังคงสามารถใช้คำอธิบายบางอย่างสำหรับผู้ที่ไม่คุ้นเคยกับ tty internals (เช่นทำไม\x1b[cจะเป็นที่นิยม)
5257

ไม่แน่ใจว่าเป็นที่น่าพอใจฉันคิดว่ามันเป็นการสนทนาที่ถูกต้อง: ใด ๆ จาก "สถานะอุปกรณ์" เงื่อนไข termys.demon.co.uk/vtansi.htmจะใช้งานได้เนื่องจากเทอร์มินัลรองรับและฉันไม่รู้ว่าสนับสนุนอะไรดี แต่ ฉันเดาว่าแบบสอบถามสถานะพื้นฐานจะเป็น (แม้จะทำงานในกระดูกเปลือย Alacritty)
Wump
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.