我们在服务器上有长时间运行的进程。服务器时钟与 NTP 同步。RTC 设置为 UTC。Localtime 设置为当前 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。
最简单的答案是关闭 NTP。然后更改您的时钟,进行测试,然后重新打开 NTP。如果测试可能失败是可以接受的,并且即使实际上没有发生 DST 转换,应用程序看到 DST 转换也是可以接受的,那么短暂关闭 NTP 也是可以接受的。
如果你没有第二台服务器来测试东西——有一个faketime工具可以用来让进程以不同的时钟值开始。您不能使用它来使已经运行的进程进行时间旅行,但您可以停止服务;通过启动它
faketime
;做测试;然后正常重启服务。在大多数情况下,下一次 DST 更改实际上不会发生任何事情。
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 客户端会尝试在正常操作期间避免跳转,但它可能会在系统启动并第一次同步时这样做。)