# 快速校准时间

在云计算环境，KVM Guest运行的操作系统在某些情况下比较容易出现时钟偏移，例如，如果qemu热升级，可能会短时间suspend住虚拟机，这会导致guest os恢复运行以后，时钟出现偏移。如果时钟偏移较大，由于ntpd服务是步进方式修正时间，所以修正过程可能会非常缓慢。

## 使用ntpdate快速校准时间

在操作系统首次启动的时候，有些发行版采用 `ntpdate` 命令快速矫正时间，然后继续启动 `ntpd` 服务确保服务器的时钟时钟准确。

我们在处理服务器时钟偏移矫正时，也可以采用类似方法。

> 需要注意：很多应用程序依赖正确的时钟，例如交易应用、加密通讯应用，当时钟差异较大，会导致会话失败；而且，如果时钟突然大幅变化，也会导致业务异常，甚至导致错乱的交易记录。所以，`ntpd`服务矫正时间是建议采用渐进步进方式校准，而不是大幅度修改系统时间。

* 检查 `/etc/ntp.conf` 配置，获取当前服务器的时钟服务器列表

```bash
cat /etc/ntp.conf | grep server
```

* 停止ntpd服务 - ntpdate和ntpd使用相同的socks，所以不能同时运行

```bash
systemctl stop ntpd
```

* 使用`ntpdate`命令矫正时间，这里使用的 `<ntp_server_ip>` 是从 `/etc/ntp.conf` 配置中查询出来的服务器地址

```bash
ntpdate <ntp_server_ip>
```

> `ntpdate` 命令支持多个ntp服务器，也就是可以同时提供多个ntp服务器地址，会自动选择最为准确的时间服务器进行同步，例如:

```bash
ntpdate 192.168.6.1 192.168.6.2 192.168.6.3
```

显示输出：

```
Mon May 24 20:59:13 CST 2021
24 May 21:00:07 ntpdate[467955]: step time server 192.168.6.1 offset 47.550589 sec
Mon May 24 21:00:07 CST 2021
```

* 以下命令将校准时间写入本地时间（可选）：

```bash
hwclock -w --localtime
```

* 以下命令恢复ntpd服务运行:

```bash
systemctl start ntpd
```

## (推荐)使用ntpdate快速校准时间

我使用上述 `ntpdate` 方法校准服务器时间，我的同事向我提了一个问题：

最好不要通过查询 `/etc/ntp.conf` 而是通过一条命令就能更新时钟。因为每个机房都有自己的时钟服务器，要分析配置文件找本地机房时钟服务器逻辑复杂不好维护脚本。最好通过一个全局域名（`dns view`）之类的，一个域名（或ip）就能够更新时钟。

这个问题促使我查询并学习了一些有关NTP的资料，发现原来 `ntpd` 服务其实是提供了直接校准时间的命令参数的，只是我们平时都是配置了ntpd服务持续维持正确时间，而忽视了这个功能参数。

通常情况下 `ntpd` 对于时钟的校准是缓慢步进方式的，所以对于时钟差异较大的时间调整非常缓慢。此外，如果是服务器启动时的主机时钟(由计算机内集成的`time-of-year` 芯片，也称为TOY芯片，维持关闭时期的时间)和ntp服务器时间差异超过`1000s`，则ntpd认为出现非常错误，ntpd会自动退出并发出紧急消息。

不过，ntpd也提供了一个快速校准时钟的参数 `-g` ，这个参数会忽略TOY芯片时间，并且直接将时钟设置为ntp服务器时间。注意，一旦时钟设置，大于1000s的时钟差异错误依然会让ntpd退出。

为了能够快速正确校准时钟，同时让ntpd服务在校准时钟之后立即退出(方便我们再次以daemon方式运行ntpd)，我们通常会结合 `-q`参数来使用 `-g`参数，也就是 `ntpd -gq`，这样通过ntpd命令校准时间后自然退出，我们就可以在正确的时钟情况下，重新启动 ntpd服务来维护主机时钟。

举例：

* 首先我们停止ntpd服务，然后将时间调整错误值

```bash
systemctl stop ntpd
date
```

* 使用 `date` 命令检查当前正确时间

```
Tue May 25 14:22:29 CST 2021
```

* 使用 `date -s` 命令设置一个错误时间

```
date -s "2 May 2021 1:1:1"
```

此时显示系统时间被调整成错误时间:

```
Sun May  2 01:01:01 CST 2021
```

* 执行时钟校准命令 - 这个命令不需要指定ntp服务器，服务器配置是从 `/etc/ntp.conf` 配置中读取的

```bash
ntpd -gq
```

此时可以看到`ntpd`服务启动并设置时间，然后自然退出:

```
 2 May 01:01:13 ntpd[15472]: ntpd 4.2.8p10@1.3728-o Thu May 18 14:01:20 UTC 2017 (1): Starting
 2 May 01:01:13 ntpd[15472]: Command line: ntpd -gq
 2 May 01:01:13 ntpd[15472]: proto: precision = 0.112 usec (-23)
 2 May 01:01:13 ntpd[15472]: switching logging to file /var/log/ntp.log
 2 May 01:01:13 ntpd[15472]: Listen and drop on 0 v6wildcard [::]:123
 2 May 01:01:13 ntpd[15472]: Listen and drop on 1 v4wildcard 0.0.0.0:123
 2 May 01:01:13 ntpd[15472]: Listen normally on 2 lo 127.0.0.1:123
 2 May 01:01:13 ntpd[15472]: Listen normally on 3 eth0 192.168.6.201:123
 2 May 01:01:13 ntpd[15472]: Listening on routing socket on fd #20 for interface updates
25 May 14:24:15 ntpd[15472]: ntpd: time set +2035372.774127 s
ntpd: time set +2035372.774127s
```

* 再次 `date` 检查时间就可以看到正确时钟

```
Tue May 25 14:24:22 CST 2021
```

* 然后我们就可以启动ntpd服务以便维护好系统准确时间

```
systemctl start ntpd
```

## 参考

* [Red Hat Enterprise Linux 6 Deployment Guide: 2.2.2. NETWORK TIME PROTOCOL SETUP](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/sect-date_and_time_configuration-command_line_configuration-network_time_protocol)
* [Linux Set Date and Time From a Command Prompt](https://www.cyberciti.biz/faq/howto-set-date-time-from-linux-command-prompt/)
* [How to force a clock update using ntp?](https://askubuntu.com/questions/254826/how-to-force-a-clock-update-using-ntp)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://huataihuang.gitbook.io/cloud-atlas-draft/service/ntp/correct_time_with_gap.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
