在物联网(IoT)设备中,时间同步至关重要,因为许多应用场景依赖于精准的时间戳来保证数据的准确性和协调性。
📝 NTP时间协议
NTP(Network Time Protocol,网络时间协议)是一种用于同步计算机系统之间时间的协议。NTP的主要作用是通过网络使分布在不同地域的计算机系统的时间保持一致。它能够通过精确的时间同步,确保在网络中运行的各种服务、应用程序和设备能够以统一的时间基准进行操作。
NTP的设计可以追溯到1980年代,它是目前互联网上使用最广泛的时间同步协议之一。通过NTP,计算机可以与网络中的时间服务器同步时间,从而实现精确的时钟同步。这对网络管理、日志记录、安全性分析等领域尤为重要。
网络时间协议NTP(Network Time Protocol)是TCP/IP协议族里面的一个应用层协议,用来使客户端和服务器之间进行时钟同步,提供高精准度的时间校正。NTP服务器从权威时钟源(例如原子钟、GPS)接收精确的协调世界时UTC,客户端再从服务器请求和接收时间。
NTP基于UDP报文进行传输,使用的UDP端口号为123。
NTP时间同步的原理与逻辑
NTP协议采用一种称为“时间戳交换”的机制来实现时间同步。具体来说,客户端设备向NTP服务器发送请求,服务器响应请求并附带当前时间戳。客户端根据请求发送时间、响应接收时间以及服务器提供的时间戳,计算出网络延迟并相应地调整本地时钟。这样,客户端设备能够不断调整自身时间,与服务器的时间保持一致。
NTP时间同步的核心原理基于分层的时间服务器架构。NTP服务器按照时间精确度划分为不同的层次,称为“Stratum”。最精确的时间源(例如GPS或原子钟)位于Stratum 0,直接连接这些时间源的服务器位于Stratum 1。其他设备则可以通过与更高层次(更低Stratum值)的NTP服务器同步来调整自己的时钟。

- 客户端首先向服务端发送一个NTP请求报文,其中包含了该报文离开客户端的时间戳t1;
- NTP请求报文到达NTP服务器,此时NTP服务器的时刻为t2。当服务端接收到该报文时,NTP服务器处理之后,于t3时刻发出NTP应答报文。该应答报文中携带报文离开NTP客户端时的时间戳t1、到达NTP服务器时的时间戳t2、离开NTP服务器时的时间戳t3;
- 客户端在接收到响应报文时,记录报文返回的时间戳t4。
客户端用上述4个时间戳参数就能够计算出2个关键参数:
- NTP报文从客户端到服务器的往返延迟delay。
- 客户端与服务端之间的时间差offset。
根据方程组:
可以解得时间差为:
NTP客户端根据计算得到的offset来调整自己的时钟,实现与NTP服务器的时钟同步。
pool.ntp.org 项目
pool.ntp.org 是一个为全球数百万客户端提供NTP服务的虚拟时间服务器集群。它由遍布世界各地的众多时间服务器组成,用户可以轻松地通过这个集群获取可靠的时间服务。使用 pool.ntp.org 的好处在于它的易用性和可靠性,用户只需简单配置即可享受全球范围内的时间同步服务。
使用ESP32实现NTP时间同步
在物联网应用中,时间同步尤为重要,因为许多物联网设备需要协调工作,例如传感器数据的时间戳记录、事件触发、日志分析等。如果设备之间的时间不一致,可能导致数据失真、事件错过、系统错误甚至安全漏洞。
使用Arduino编程语言,可以轻松地编写代码,通过 pool.ntp.org 同步时间。以下是一个简单的示例:
这个代码段连接到Wi-Fi网络并与NTP服务器同步时间,随后会在串口监视器上输出当前时间。如下图所示:


然而,在实际的商业应用中,不建议依赖pool.ntp.org进行大规模的时间同步,因为它是一个公共资源,无法保证服务质量和响应时间的稳定性。我们可以在ubuntu22.04系统中使用sntp命令行工具来验证pool.ntp.org的服务质量。
使用sntp命令行工具来验证pool.ntp.org的服务质量,首先需要apt安装sntp,执行指令
ssudo apt install sntp -y (不同Ubuntu版本安装的软件包可能有差异,请自行确认)
或者使用
sudo ntpdate -q ph.pool.ntp.org 来验证服务可用性
可以看到pool.ntp.org在一些国家地区,服务是不稳定的。
所以在一些对时间精度和可靠性要求较高的物联网应用中,可以搭建私有的NTP服务器或者使用MQTT协议在业务层面实现时间同步。
搭建私有的NTP服务器
为了获得更高的时间同步精度,可以在Linux服务器上自建局域网NTP服务器。
搭建一个NTP服务器并不复杂,以下是基本步骤:
1、安装NTP服务器软件:在Ubuntu22.04上使用
sudo apt update && sudo apt install ntp 安装软件。2、配置NTP服务器:安装完ntp软件后,
/etc/ntp.conf 文件里面会带有默认配置。如果需要修改上游服务,可以自行修改。
3、启动NTP服务:apt安装完ntp后,ntp服务默认会开启,如果没有启动,可以通过命令
sudo systemctl start ntp && sudo systemctl enable ntp 启动NTP服务,并设置为开机自启动。4、验证NTP服务器运行状态:使用
sudo systemctl status ntp 命令来检查 NTP 服务是否正常运行。
5、验证 NTP 服务器功能:使用
ntpdate 命令来验证同步时间,或者sntp命令。
这样,你就获得了一个自建NTP服务器。
使用MQTT协议进行时间同步
MQTT是一种轻量级的消息传递协议,常用于物联网设备之间的通信。通过在MQTT消息中传递时间戳,设备可以实现时间的同步。参考NTP的时间同步设计和涂鸦智能平台的时间同步设计,可以开发出适合特定应用场景的高精度时间同步协议。
比如通过 MQTT topic: iot/${deviceId}/ext/time/request 可以获取获取服务器时间,那么根据下面的计算,就可以获取到相对精准的时间了。

假设请求的耗时和响应的耗时相等,响应耗时是总体网络耗时的一半。可以参考如下图示:
- t4 − t1 = 总耗时
- t3 − t2 = 服务端系统耗时
- 总体网络耗时 = 总耗时 − 服务端耗时
- 响应耗时 = 总体网络耗时 ÷ 2=(总耗时 − 服务端耗时) ÷ 2 = (t4 − t1 − (t3 − t2)) ÷ 2 = (t4 − t1 − t3 + t2) ÷ 2
- 精准时间 = t3 + 响应耗时 = t3 + (t4 − t1 − t3 + t2) ÷ 2=(t4 − t1 + t3 + t2) ÷ 2
对于对时间要求没有需要特别精准的设备来说,直接取服务器返回的时间t3也是可以的,网络延迟时间一般都是毫秒级别的,普通场景下可以忽略。
📎 参考资料&拓展阅读
《网络时间协议》
《2038年问题》
《系统时间》
- 作者:Yibin
- 链接:https://yibin.dev/article/6b221b99-5ec1-406b-9dd2-c666a0ea887a
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章








