Answers:
自己尝试做这个,并提出了这个建议。也许有一种更简单的方法,但这就是我想出的。
首先,准备管道,这些管道将用于使基准测试程序通过SSH连接进行通信。
$ mkfifo /tmp/up /tmp/down
然后在ControlMaster模式下建立连接,而无需执行任何远程命令。这使我们可以与主机进行交互身份验证。建立连接后,SSH只会在此处“挂起”。
$ ssh $HOST -N -M -S /tmp/control
在并行终端中,cat
在后台执行远程。这将是我们的回声服务器,我们将测量其延迟。输入和输出连接到FIFO:
$ ssh $HOST -S /tmp/control cat </tmp/up >/tmp/down &
然后对一个小程序进行基准测试(向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
该度量显然显示了往返延迟。如果您需要重复实验,请再次运行最后两个命令(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"'
哪里
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 ...
查看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
我的想法是为此使用终端查询序列。优点是它可以简单地在服务器上运行,缺点是它可以测量终端延迟,不仅可以测量连接延迟(但我想,通常来说,与网络延迟相比,终端的响应时间可以忽略不计)–也许这甚至就是您所说的整体延迟
#!/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)
(这使用“设备代码查询”,我尝试过的所有终端都对此进行响应:xterm,alacritty,gnome-terminal。我无法自己在MacOS上进行尝试。因此,YMMV,如果没有,则另一个请求询问有关终端的某些信息可能会起作用,请参阅http://www.termsys.demon.co.uk/vtansi.htm)
\x1b[c
会比较满意),该答案仍可以使用一些解释