Определите доступность сервера с помощью программы, действующей как эхо-сигнал UDP

Я использую Xen Hypervisor в Ubuntu и у меня есть виртуальная машина. При виртуальной миграции виртуальной машины на другой хост виртуальная машина будет недоступна в диапазоне от нескольких миллисекунд до максимум нескольких секунд (в зависимости от среды). Я должен быть в состоянии определить это короткое время как можно точнее. поэтому мне нужно "как-то" проверять vm скажем каждые 100 миллисекунд. и число раз, когда я нахожу vm UNAVAILABLE непрерывно, умноженное на 100, будет общим миллисекундами, в течение которых мой vm был недоступен.

ping не работает, так как он не точный, и в случае, если vm недоступен, команда ping ожидает и повторяет отправку ICMP-пакетов, и это портит цель выяснить, доступен ли сервер в этом EXACT CHECKING MOMENT. Плюс я задал вопрос здесь, и ответ был "не используйте пинг!"
так что не используйте пинг!

Мне нужно написать свой собственный кусок кода в python/perl/whathever, который мог бы сделать работу. Как я мог это сделать?

2 ответа

ping не работает, так как он не точный и в случае, если vm недоступен, команда ping ожидает и повторяет отправку пакетов ICMP

Это по умолчанию, но вы можете сказать, чтобы отправить только один.

$ ping -q -c 1 9.9.9.9 >/dev/null

$ echo $?
1

$ ping -q -c 1 8.8.8.8 >/dev/null

$ echo $?
0

Так

while ! ping -q -c 1 -W 1 x.x.x.x >/dev/null ; do true ; done

Плюс я задал вопрос здесь, и ответ был "не используйте пинг!" так что не используйте пинг!

Тем не менее, вы запросили пинг (на основе UDP) вместо средства проверки работоспособности необходимой службы.

Вот функция ping UDP ZeroMQ, адаптированная из обнаружения UDP, модель 1 в Python, отключив широковещательную рассылку, пропинговав только один IP-адрес, вернувшись после первого ответа, добавив счетчик для ограничения числа попыток пинга и добавив дополнительную обработку ошибок во время получения сообщения., Последнее было сделано, так как один хост в моей сети принудительно закрыл соединение, вызывая socket.error: [Errno 10054]. Он был протестирован и найден для работы с Python 2.7.10 и 3.4.3.

from __future__ import print_function
import os
import socket
import sys
import time
import zmq

def udpping(ip):
    PING_PORT_NUMBER = 9999
    PING_MSG_SIZE = 1
    PING_INTERVAL = 1 # once per second, sets minimum initial timeout

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    # uncomment the line below for broadcast to 255.255.255.255
    # sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    sock.bind(('', PING_PORT_NUMBER))
    poller = zmq.Poller()
    poller.register(sock, zmq.POLLIN)
    ping_at = time.time()

    limit = 5 # only limit ping attempts will be made
    count = 0
    while True:
        count += 1
        timeout = ping_at - time.time()
        if timeout < 0:
            timeout = 0
        try:
            events = dict(poller.poll(1000* timeout))
        except KeyboardInterrupt:
            return (1,None,None)
        try:
            if sock.fileno() in events:
                msg, addrinfo = sock.recvfrom(PING_MSG_SIZE)
                return (2,"found %s:%d" % addrinfo,None)
        except socket.error as e:
            return (3,'error during msg receive:',e)
        if time.time() >= ping_at:
            # the line below is for broadcasting
            # sock.sendto(b'!', 0, ("255.255.255.255", PING_PORT_NUMBER))
            sock.sendto(b'!', 0, (ip, PING_PORT_NUMBER))
            ping_at = time.time() + PING_INTERVAL
        if count == limit:
            return (4,limit,None)

ip = '192.168.159.21'
c,m,e = udpping(ip)

Ниже показана обработка вывода. Для бинарного решения пинг успешен, только если c == 2.

if c == 1:
    print('ping attempt stopped by KeyboardInterrupt')
elif c == 2:
    print(m)
elif c == 3:
    print(m,e)
elif c == 4:
    print('no response from',ip,'after',m,'attempts')

# prints 'found 192.168.159.21:9999' immediately in my net
Другие вопросы по тегам