2015-09-15 19 views
-1

我在Ubuntu中使用Xen Hypervisor,並且我有一個虛擬機。在將vm實時遷移到另一臺主機時,vm將從幾毫秒到幾秒不等(取決於環境)不可用。我需要能夠儘可能準確地確定短時間。所以我需要「不知何故」每隔100毫秒檢查一次vm。以及我連續發現vm UNAVAILABLE的次數乘以100將是我虛擬機下降的總毫秒數。使用充當UDP回聲的程序確定服務器可用性

ping不起作用,因爲它不準確,並且在vm不可用的情況下,ping命令會等待並重試發送ICMP數據包,這會破壞確定服務器是否在該精確檢查時刻可用的目標。另外我在here問了一個問題,反饋是「不要使用ping!」
so 不使用PING!

我需要在python/perl/whathever中編寫我自己的一段代碼來完成這項工作。我怎麼能這樣做?

+0

可能會設置短暫超時?那麼結果會更快 –

+0

@勞倫斯·本森和確切的命令是什麼? – Ali

+0

也許不是檢查虛擬機,而是讓虛擬機發送一些關於它的存在的確認。就像是從虛擬機發送到運行服務器實例的其他機器的SYN數據包,可能會接受連接,記錄它們並丟棄它們。 http://www.secdev.org/projects/scapy/doc/usage.html#tcp-port-scanning –

回答

1

ping doesn't work since it's not being accurate and in case of vm being unavailable, ping command waits and retries sending ICMP packets

這是默認值,但您可以告訴它只發送一個。

$ 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 

Plus I asked a question in here and the feedback was "don't use ping!" so NO USING PING!

然而,你問一個(基於UDP)平,而不是檢查,如果需要的服務是向上的一種手段。

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的情況下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