С Веб-трафиком это больше распространено. Существует ли конкретный сценарий, которым Вы обеспокоены? У меня нет SNATs, отражают весь мой DNATs.
Сценарии я забочусь о..
Из того, что я понимаю, эмпирическое правило состоит в том, чтобы избежать его, если это возможно. Но с современными реализациями и динамической маршрутизацией я полагаю, что эта перспектива становится более устаревшей.
Моя идея состояла в том, чтобы использовать терминальные последовательности запроса для этого; преимущество состоит в том, что это может просто быть выполнено на сервере, недостаток - то, что он измеряет терминальную задержку, не только задержку соединения (но и я предполагаю, обычно, время отклика Вашего терминала будет незначительно по сравнению с сетевыми задержками), —, возможно, это даже, что Вы имеете в виду с полный задержка
#!/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, живость, терминал гнома. Я не могу самостоятельно попробовать это на MacOS. Так YMMV, если этот не делает, другой из запросов, которые опрашивают некоторую информацию о терминале, мог бы работать, видеть http://www.termsys.demon.co.uk/vtansi.htm )
Пытался сделать это сам и придумал вот что. Возможно, есть более простой способ, но это то, что я придумал.
Во-первых, подготовьте каналы, которые будут использоваться, чтобы программа тестирования обменивалась данными через соединение 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 &
А затем протестируйте небольшую программу (отправьте байт в вверх
FIFO, получите байт из вниз
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
, чтобы получить больше отладочных данных.
راجع الأداة المساعدة 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
I пропустил некоторые шаги, предложенные @ 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
выполняет модуль Python timeit
.
Параметр -s / - setup
сообщает timeit
, какие операторы выполнять перед каждым повтором.
subprocess.Popen (["ssh", "user @ host", "cat"], stdin = subprocess.PIPE, stdout = subprocess.PIPE, bufsize = 0)
запускает ssh
- выполнение cat
на вашем хосте - в качестве дочернего / подпроцесса, перенаправляя его потоки ввода-вывода на файлы, подобные объектам Python. bufsize = 0
гарантирует, что никакой ввод-вывод не буферизуется, что может вызвать ожидание ввода-вывода.
И для каждого цикла:
p.stdin.write (b "z")
записывает одиночный byte к дочернему элементу (в свою очередь через ssh к cat
).
p.stdout.read (1)
считывает один байт из дочернего элемента. Утверждение вокруг него проверяет, совпадает ли этот байт с тем, который вы ему записали.
Сводится к тому же самому,но пропускает создание именованных каналов ( mkfifo
). Я заметил, что чем больше циклов вы выполняете, тем быстрее каждый цикл. Управляйте им с помощью -n / - number
: python -m timeit --number 50 ...