一.相关协议

时间是系统最基本也是最重要的部分之一,系统中的文件读写、传输等都是以系统时间为准,很多业务也要求服务器的系统时间保持一致,这就需要使用时间同步服务。目前主要有两种协议提供了时间同步服务:

  1. NTP/SNTP协议(RFC1305): 基于udp协议(123端口),可以估算数据包在网络上的延迟和计算机时间偏差,提供毫秒级的精度,是目前网络时间服务器使用的主流协议
  2. TIME协议 (RFC868) : 该协议比较简单,使用tcp/udp的37端口,服务会返回从1900年1月1日午夜到现在的秒数,精度低,使用较少

二.软件支持和应用场景

本文只介绍linux下软件支持:

  1. NTP协议 : ntpdate/ntp(d)
  2. TIME协议: rdate
  3. 手动同步 : date

使用那种软件同步时间要看应用的场景:

  1. 对时间要求不高时使用手动同步或者ntpdate+cronjob来同步时间即可
  2. 如果业务对时间非常敏感,不允许时间跃变,可以用ntpd平滑同步
  3. 在一些有防护的机房,默认丢弃所有进出的udp包,导致ntpdate/ntpd无法同步时间,这时就需要用TCP协议来同步时间

三.配置时间同步

3.1 ntpdate使用

ntpdate会马上更改时间,使用比较简单,安装ntpdate:

yum install ntpdate

只查询不同步时间:

ntpdate -q time.windows.com

同步时间:

ntpdate time.windows.com

可以配合crontab每天执行一次同步:

  1  5  *  *  * root /usr/sbin/ntpdate time.windows.com

如果同步出错,可以使用debug模式排查问题:

ntpdate -d time.windows.com

3.2 ntp使用

安装:

yum install ntp

贴一份ntp.conf配置,少量修改即可:

driftfile /var/lib/ntp/drift
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery

#允许 loopback的所有访问
restrict 127.0.0.1 
restrict -6 ::1

# 允许的局域网络段或ip
#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
restrict 10.0.0.0 mask 255.0.0.0 nomodify motrap
restrict 192.0.0.0 mask 255.0.0.0 nomodify motrap

#允许上层时间服务器修改本地时间
    restrict 0.centos.pool.ntp.org nomodify notrap noquery
restrict 1.centos.pool.ntp.org nomodify notrap noquery
restrict 2.centos.pool.ntp.org nomodify notrap noquery
restrict 3.centos.pool.ntp.org nomodify notrap noquery

# 公共NTP服务器,可以去http://www.pool.ntp.org找    
server 0.centos.pool.ntp.org perfer
server 1.centos.pool.ntp.org 
server 2.centos.pool.ntp.org 
server 3.centos.pool.ntp.org 

# 外部时间服务器不可用时,以本地时间作为时间服务
server  192.168.56.101     
fudge   192.168.56.101  stratum 10

includefile /etc/ntp/crypto/pw
keys /etc/ntp/keys

因为ntp会平滑的同步时间,如果本地时间和服务器时间相差太大,会导致非常久才会同步时间,或者根本不会平滑同步。所以建议使用ntp同步之前先ntpdate同步一下,不同步也可以,按照上面的配置,第一次启动时会自动同步时间。配置好就可以作为时间服务器为其他服务器提供时间同步服务

查看时间同步状态:

ntpstat

查看与上层服务器的连接状态:

ntpq -p

3.3 rdate 同步时间

ntpdate和ntp都只能用udp来同步时间,rdate支持用tcp或者udp同步时间,安装rdate:

yum install rdate

网上支持time协议的服务器不多,查看服务器返回时间:

rdate -p time.nist.gov

或者:

 nc time.nist.gov 13

使用tcp同步时间:

rdate -s time.nist.gov

使用udp同步时间:

rdate -u time.nist.gov

其他rdate服务器可以在http://tf.nist.gov/tf-cgi/servers.cgi 查看

3.4 手动同步时间

使用date命令手动同步,用法:

date -s  10:23:10
date -s 'Thu, 17 Dec 2015 10:23:10 GMT'

这种方法精度太差,可以借助网站的http头同步时间,我们先来看一下,http头的格式:

curl -s --head http://www.52os.net

返回为:

HTTP/1.1 200 OK
Date: Thu, 17 Dec 2015 10:23:30 GMT
Server: Mod_Security 2.5.9 enabled
X-Powered-By: PHP/5.3.29
X-Pingback: http://www.52os.net/action/xmlrpc
Vary: Accept-Encoding,User-Agent
Content-Type: text/html; charset=UTF-8

只要过滤出DATE中的时间即可,命令如下:

curl -s --head http://www.52os.net | grep ^Date: | sed 's/Date: //g'

返回为:

Thu, 17 Dec 2015 10:26:13 GMT 

这个格式date命令就能用了,和date命令整合一下,查询时间:

date -d "$(curl -s --head http://www.52os.net | grep ^Date: | sed 's/Date: //g')"

设置时间:

date -s "$(curl -s --head http://www.52os.net | grep ^Date: | sed 's/Date: //g')"

当然我的服务器时间不够精确,你可以把 www.52os.net 换成 google.com或者baidu.com,这样就可以保证时间的精度了。总的来说:tcp和手动同步的方式要建立连接,又没有误差计算,所以精度不如用ntp,这也是ntp流行的原因

3.5 写入硬件时间

linux的时间分为系统时间和硬件时间两种,以上各种方法同步的都是系统时间,服务器启动时会从硬件(BIOS)读取时间作为系统时间,所以也要同步一下硬件时间。
查看硬件时间:

hwclock -r 

对比下系统时间和硬件时间:

hwclock -r && date 

将系统时间写入硬件时间:

hwclock -w

参考文章:
http://blog.csdn.net/cymm_liu/article/details/10932181
http://linux.vbird.org/linux_server/0440ntp.php
http://superuser.com/questions/635020/how-to-know-current-time-from-internet-from-command-line-in-linux