puf*_*ish 24 networking ssh performance-monitoring latency
有没有办法测量/报告隧道 SSH 会话中的整体延迟?
我的具体设置是:
我有兴趣查看本地机器上的控制台与打开会话的最终机器之间的延迟。
Unc*_*ook 10
查看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
Run Code Online (Sandbox Code Playgroud)
试图自己做这件事并想出了这个。可能有一个更简单的方法,但这是我想出的。
首先,准备将用于使基准测试程序通过 SSH 连接进行通信的管道。
$ mkfifo /tmp/up /tmp/down
Run Code Online (Sandbox Code Playgroud)
然后在 ControlMaster 模式下建立连接,无需执行任何远程命令。这允许我们以交互方式与主机进行身份验证。建立连接后,SSH 将在前台“挂起”。
$ ssh $HOST -N -M -S /tmp/control
Run Code Online (Sandbox Code Playgroud)
在并行终端中,cat
在后台执行远程。这将是我们的回声服务器,我们将测量其延迟。输入和输出连接到 FIFO:
$ ssh $HOST -S /tmp/control cat </tmp/up >/tmp/down &
Run Code Online (Sandbox Code Playgroud)
然后对一个小程序进行基准测试(向up
FIFO发送一个字节,从down
FIFO接收一个字节):
$ 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
Run Code Online (Sandbox Code Playgroud)
该措施显然显示了往返延迟。如果您需要重复实验,请再次运行最后两个命令 (ssh
和python
)。
如果出现问题,请使用 SSH-v
标志获取更多调试输出。
我跳过了@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"'
Run Code Online (Sandbox Code Playgroud)
在哪里
python -m timeit
执行timeit
Python 模块。
该-s/--setup
选项告诉timeit
在每次重复之前要执行哪些语句。
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 ...
我的想法是为此使用终端查询序列;优点是它可以简单地在服务器上运行,缺点是它测量终端延迟,而不仅仅是连接的延迟(但我猜,通常,与网络延迟相比,你的终端的响应时间可以忽略不计)\xe2\x80\x94也许这就是你所说的整体延迟
\n#!/usr/bin/env python3\n# Measure terminal latency (round-trip time) using "Query device code" command\nfrom sys import stdin, stdout\nimport tty, termios, time\n\noldtty = termios.tcgetattr(stdin)\ntry:\n tty.setcbreak(stdout)\n\n runs = 10\n results = []\n for _ in range(runs):\n stdout.write("\\x1b[c")\n stdout.flush()\n t1 = time.time()\n ch = stdin.read(1)\n assert(ch == \'\\x1b\')\n t2 = time.time()\n while stdin.read(1) != \'c\': # swallow rest of report\n continue\n latency = (t2 - t1) * 1000\n print(\'%.1fms\' % (latency))\n results.append(latency)\n\n print()\n print(\'avg: %.1fms min: %.1fms max: %.1fms\' % (\n sum(results) / runs,\n min(results),\n max(results)))\nfinally:\n termios.tcsetattr(stdin, termios.TCSADRAIN, oldtty)\n
Run Code Online (Sandbox Code Playgroud)\n(这使用“设备代码查询”,我尝试过的所有终端都会对此做出响应:xterm、alacritty、gnome-terminal。我自己无法在 MacOS 上尝试这个。所以 YMMV,如果这个没有,另一个询问有关终端的某些信息的请求可能有效,请参阅http://web.archive.org/web/20190624214929/http://www.termsys.demon.co.uk/vtansi.htm)
\n