我在ubuntu中使用Xen Hypervisor,我有一台VM。当将vm实时迁移到另一个主机时,vm将在大约几毫秒到不超过几秒的顶部范围内不可用(取决于环境)。我需要能够尽可能准确地确定短时间。所以我需要'以某种方式'检查vm说每100毫秒。以及我连续找到vm UNAVAILABLE的次数乘以100,将是我的虚拟机停机时间的总毫秒数。
ping不起作用,因为它不准确,并且在vm不可用的情况下,ping命令等待并重试发送ICMP数据包,这破坏了目标,以确定服务器是否在该确认检查时可用。另外我在here中问了一个问题,反馈是“不要使用ping!” 所以不使用PING!
我需要在python / perl / whathever中编写我自己的一段代码才能完成这项工作。我怎么能这样做?
答案 0 :(得分: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而不是检查所需服务是否已启动的方法。
答案 1 :(得分:0)
这是一个ZeroMQ UDP ping功能,从UDP discovery, model 1 in Python改编,通过禁用广播,只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时才能成功。
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