-1

我在 ubuntu 中使用 Xen Hypervisor,并且我有一个 VM。当将虚拟机实时迁移到另一台主机时,虚拟机将在大约几毫秒到不超过几秒的范围内不可用(取决于环境)。我需要能够尽可能准确地确定那个短时间。所以我需要“以某种方式”检查 vm 每 100 毫秒说一次。并且我连续发现 vm UNAVAILABLE 的次数乘以 100,将是我的 vm 关闭的总毫秒数。

ping 不起作用,因为它不准确,并且在 vm 不可用的情况下,ping 命令等待并重试发送 ICMP 数据包,这破坏了确定服务器是否在确切检查时刻可用的目标。另外,我在这里问了一个问题,反馈是“不要使用 ping!”
所以不要使用 PING!

我需要在 python/perl/whathever 中编写我自己的一段代码来完成这项工作。我怎么能那样做?

4

2 回答 2

1

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

另外,我在这里问了一个问题,反馈是“不要使用 ping!” 所以不要使用 PING!

然而,您要求的是(基于 UDP 的)ping,而不是检查所需服务是否启动的方法。

于 2015-09-15T15:51:48.427 回答
0

这是一个改编自UDP 发现的 ZeroMQ UDP ping 函数,Python 中的模型 1通过禁用广播,仅 ping 一个 IP 地址,在第一次回复后返回,添加一个计数器以限制 ping 尝试的次数,并在消息接收期间添加额外的错误处理. 后者是因为我的网络中的一个主机强行关闭了导致 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 时 ping 成功。

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
于 2015-09-15T16:17:59.053 回答