我们在服务器上有长时间运行的进程。服务器时钟与 NTP 同步。RTC 设置为 UTC。本地时间设置为当前 DST 时区:
$ timedatectl
Local time: Thu 2021-12-02 08:41:01 CET
Universal time: Thu 2021-12-02 07:41:01 UTC
RTC time: Thu 2021-12-02 07:41:01
Time zone: Europe/Budapest (CET, +0100)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
我们想测试下次 DST 更改时会发生什么。(我们是否需要重新启动应用程序)。
我该如何模拟这种变化?由于我们使用的是 NTP,因此将日期设置为完全虚假的值是不可能的(我认为)。
答案1
最简单的答案是关闭 NTP。然后更改时钟,进行测试,然后再次打开 NTP。如果测试失败是可以接受的,并且应用程序看到 DST 切换(即使实际上没有发生)也是可以接受的,那么短暂关闭 NTP 也应该是可以接受的。
如果你没有第二台服务器来测试,那么有一个假时间可用于使进程以不同的时钟值启动的工具。您不能使用它使已经运行的进程进行时间旅行,但您可以可以停止服务;通过启动它faketime
;进行测试;然后正常重启该服务。
大多数情况下,下次夏令时变化时实际上不会发生任何事情。
NTP 始终提供 UTC 时间。您无需向 NTP 服务器索要“布达佩斯时间”(您也没有“欧洲”或“美国”NTP 服务器,它们会在不同月份切换为 DST),而是始终从每个服务器获取相同的 UTC 时间。
(可能有专门的 NTP 服务器提供 UT1 或 TAI,但它们也是全球性的,而不是基于时区的。)
Linux 内核时钟始终按照 UTC 时间运行(无论您使用哪种 RTC 模式)。不是已针对 DST 进行调整。当应用程序从内核获取当前时间时,它们始终会获取 UTC(以“Unix 纪元”表示),并且它们仅在需要时将时间戳转换为本地时间。Windows、BSD 等也是如此。
大多数应用程序使用“tzdata”时区数据库,其中包含日期范围及其偏移量的列表。您的时区不只是设置为固定的“+0100”或“+0200”偏移量 - 它设置为“欧洲/布达佩斯”,并且相同的/usr/share/zoneinfo/Europe/Budapest
tzdata 文件允许应用程序将任何时间戳转换为本地时间,并根据需要自动使用 DST 或非 DST 规则。(使用zdump -v Europe/Budapest
查看其内容。)
因此,通常唯一需要重新启动应用程序的情况是“tzdata”数据库更新时,例如您所在地区突然决定采用不同的 DST 规则。如果 tzinfo 文件发生变化,某些程序会自动重新读取该文件,而其他程序则不会。
(是的,如果内核时钟跳回,您需要重新启动一些应用程序 - 但由于内核时钟不受 DST 调整的影响,因此它唯一会跳回的情况是如果它在启动期间从 RTC 获得了错误的时间,例如如果它快了几个小时。您的 NTP 客户端会尝试避免在正常运行期间跳转,但它可能会在系统启动并首次同步时执行跳转。)