PHP microtime() 漂移,外部 NTP 服务 [英] PHP microtime() drift, External NTP service

查看:33
本文介绍了PHP microtime() 漂移,外部 NTP 服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的云托管服务器上的问题寻找解决方案,其中 microtime(true) 返回结果;在几分钟之内的通话之间非常准确,但在一两天内漂移近一秒.我正在使用此结果在异步连接的客户端之间进行同步,并且如果可能的话,我需要精度在 <~10 毫秒内准确到 NIST.

I am looking for a solution for an issue on my cloud-hosted server where the result returned from microtime(true); is very accurate between calls within a few minutes of each other, but drifts by nearly a second over the course of a day or two. I'm using this result to synchronize between asynchronously connected clients and I need the precision to be accurate to NIST by within <~10ms or so if at all possible.

我知道这可能被认为是题外话,但目前我能想到的最佳选择是定期轮询一些外部服务并以毫秒为单位获取当前的 NIST 时间.不幸的是,我似乎找不到提供这项服务的人.如果我需要,我将自己设置第二台具有可靠时间响应的服务器并对其进行 ping 操作,但似乎必须有人解决这个简单的需求.有人知道吗?

I know this could be considered off-topic, but the current best option I can think of is to regularly poll some external service and obtain the current NIST time in milliseconds. Unfortunately I can't seem to find anyone offering this service. If I need to I'll just set up a second server with reliable time response myself and ping that, but it seems like there has to be someone out there addressing this simple need. Anybody know of something?

推荐答案

我找到了以下服务:

http://currentmillis.com/api/millis-since-unix-epoch.php

请记住,对于寻找类似解决方案的任何人,网络延迟和一般不可预测的因素肯定会使返回值偏离真实时间.无论您使用它做什么,您都必须将这些影响考虑在内!

Just keep in mind for anyone looking for a similar solution that network latency and general unpredictable factors will definitely skew the returned value away from the true time. You must factor these effects into whatever you're using it for!

更新:

使用上述服务几天后,很明显我需要比当前托管的连接更高的可靠性.我的解决方案是构建一个基于 PHP 的客户端,通过与附近 NTP 服务器的直接套接字连接来实现.在一次典型的呼叫中,我的往返时间大约为 7 到 15 毫秒.

After utilizing the above service for a couple of days, it was clear that I needed a little bit more reliability than was possible through the connection it's currently being hosted on. My solution was to build a PHP-based client, implemented via a direct socket connection to a nearby NTP server. I've been getting round-trip times ranging from roughly 7 to 15 ms on a typical call.

您的结果可能会有所不同,具体取决于您自己的服务器以及您选择的 NTP 提供商.您可以在此处找到第 2 层服务器,也可以使用 一般池.正如其他帖子中提到的,不要连续轮询这些提供商,而是限制您的通话并根据通话时间进行调整.

Your results may vary, depending on your own server as well as your choice of NTP provider. You can find stratum 2 servers here, as well as using the general pool. As mentioned in these other posts, do NOT continuously poll these providers, but throttle your calls and adjust according to call time.

这是我的客户端"代码:

Here's my code for the 'client':

function RemoteNTP($Host) {
    $Sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);  // Create socket
    socket_connect($Sock, $Host, 123);  // Connect over port 123 for NTP
    $Str = "\010" . str_repeat("\0", 47);  // Create string for binary transmission
    $Trip -= round(microtime(true)*1000);  // Grab time of call
    socket_send($Sock, $Str, strlen($Str), 0);  // Send transmission
    socket_recv($Sock, $Response, 48, MSG_WAITALL);  // Receive formatted response
    $Trip += round(microtime(true)*1000);  // Adjust call time variable
    socket_close($Sock);  // Close socket
    $Data = unpack('N12', $Response);  // Format as an array we can work from
    $Secs = $Data[11]-2208988800;  // Convert to secs since 1970, from 1900 for NTP
    $Frac = $Data[12]/4294967296;  // Fraction of sec, out of 2^32 (32 bits)
    $Time = ($Secs*1000)+round($Frac*1000);  // Combine for full ms value
    $Time += round($Trip/2);  // Measure and adjust this for better accuracy
    return $Time;  // Returns number of milliseconds passed since 1970-01-01
}

可以这样调用:

$Ntp = GetRemoteNTP('0.pool.ntp.org');

根据正在进行的检查来调整 $Trip 的修饰符,以确定每次调用的出站和返回时间的实际值,您将获得更准确的行程时间.(我实际上详细跟踪我的,但想以模块化的方式发布它,并将跟踪机制的选择留给实现者.)通过在靠近服务器的 NTP 提供程序上进行磨练,您将提高可靠性,但是如果使用池时,您可能还想通过将 # 的 0-4 预先添加到主机 URL 并为每个请求循环来循环"您对池服务器的调用.

You'll get more accurate trip times by tweaking the modifier for $Trip based on ongoing checks to determine the actual values for the out and back times for each call. (I actually track mine in detail but wanted to post this in a modular way and leave the choice of tracking mechanisms open to the implementer.) You'll improve reliability by honing in on a NTP provider in close proximity to your server, but if utilizing the pool you may also want to 'round-robin' your calls to the pool servers by prepending the #'s 0-4 to the host url and cycling for each request.

还请记住,这应该被视为最后的解决方案.NTP 框架经过精心设计,是一个强大而全面的系统,用于维护非常准确的系统时间.这是一种低级的、自我纠正的机制,比这样的自制黑客做得好得多.由于我的具体情况,我采用了这里使用的方法;系统时钟中可能有更好的替代方案可供您使用,通过 nptd 自动调整.

Also keep in mind that this should be seen as a last-resort kind of solution. The NTP framework has been carefully designed to be a robust and comprehensive system for maintaining very accurate system time. It is a low-level, self-correcting mechanism that will do a much better job than a home-brewed hack like this. I resort to the method used here due to my specific circumstances; there is likely a better alternative available to you in the system clock, auto-adjusted via nptd.

这篇关于PHP microtime() 漂移,外部 NTP 服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆