How to validate local VM clock with NTP on Windows Azure?
NTP (Network Time Protocol) is basically the de-facto standard to adjust setup server clocks. I have already raised a question about the expectations in terms of native clo开发者_开发技巧ck accuracy on Windows Azure. Here comes a slightly different one: how I can validate the current clock reliability with NTP? The catch is that UDP is not available on Windows Azure (only TCP), and it seems there is no TCP implementation available of NTP (although the discussion is nearly one decade old).
Any take?
Assuming that UDP outgoing packets are still blocked by Azure (I'm surprised/disappointed this is still the case!) then maybe you could drop down to a TCP service with less resolution such as TIME or DAYTIME - see descriptions of both on http://www.nist.gov/pml/div688/grp40/its.cfm - you would obviously need to measure the length of time your network call took in order to be sure the answer coming back is sufficiently accurate for you.
Joannes and Stuart: You are correct that Windows Azure roles (Web, Worker, and VM Roles) do not support hosting of UDP endpoints currently. However, NTP support is already included by default on Windows Azure role VMs, currently configured by default to synch the clock against server time.windows.com once a week (evidence here - search for "time service").
You can tweak a registry setting in a Startup Task if a weekly sync is not frequent enough.
HTH!
I'm a bit surprised by your answer about udp while i'm actually connect to NTP server from my azure web role to serve our JS client synchronization. This is working fine...
Note the azure web role time is a lot different thant the NTP one ( actually 30s ahead !! ). However, the NTP time is nearly the same as my local machine synchronized with time.microsoft.com
{"network":"2013-07-16T18:18:25.9558581Z","server":"2013-07-16T18:18:52.5415999Z"}
Here the code i use :
static uint SwapEndianness(ulong x)
{
return (uint)(((x & 0x000000ff) << 24) +
((x & 0x0000ff00) << 8) +
((x & 0x00ff0000) >> 8) +
((x & 0xff000000) >> 24));
}
static DateTime Update(string server)
{
// NTP message size - 16 bytes of the digest (RFC 2030)
var ntpData = new byte[48];
//Setting the Leap Indicator, Version Number and Mode values
ntpData[0] = 0x1B; //LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode)
var addresses = Dns.GetHostEntry(server).AddressList;
//The UDP port number assigned to NTP is 123
var ipEndPoint = new IPEndPoint(addresses[0], NTPPort);
//NTP uses UDP
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Connect(ipEndPoint);
socket.Send(ntpData);
DateTime l_now = DateTime.UtcNow;
socket.Receive(ntpData);
socket.Close();
//Offset to get to the "Transmit Timestamp" field (time at which the reply
//departed the server for the client, in 64-bit timestamp format."
const byte serverReplyTime = 40;
//Get the seconds part
ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);
//Get the seconds fraction
ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4);
//Convert From big-endian to little-endian
intPart = SwapEndianness(intPart);
fractPart = SwapEndianness(fractPart);
var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
//**UTC** time
var l_networkTime = (new DateTime(_epocBaseTicks, DateTimeKind.Utc)).AddMilliseconds((long)milliseconds);
_networkTimeDelta = l_networkTime.Ticks - l_now.Ticks ;
return l_networkTime;
}
Hope this help.
精彩评论