linux下使用TCP和UDP协议同步时间
一.相关协议
时间是系统最基本也是最重要的部分之一,系统中的文件读写、传输等都是以系统时间为准,很多业务也要求服务器的系统时间保持一致,这就需要使用时间同步服务。目前主要有两种协议提供了时间同步服务:
- NTP/SNTP协议(RFC1305): 基于udp协议(123端口),可以估算数据包在网络上的延迟和计算机时间偏差,提供毫秒级的精度,是目前网络时间服务器使用的主流协议
- TIME协议 (RFC868) : 该协议比较简单,使用tcp/udp的37端口,服务会返回从1900年1月1日午夜到现在的秒数,精度低,使用较少
二.软件支持和应用场景
本文只介绍linux下软件支持:
- NTP协议 : ntpdate/ntp(d)
- TIME协议: rdate
- 手动同步 : date
使用那种软件同步时间要看应用的场景:
- 对时间要求不高时使用手动同步或者ntpdate+cronjob来同步时间即可
- 如果业务对时间非常敏感,不允许时间跃变,可以用ntpd平滑同步
- 在一些有防护的机房,默认丢弃所有进出的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.nixops.me
返回为:
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.nixops.me/action/xmlrpc
Vary: Accept-Encoding,User-Agent
Content-Type: text/html; charset=UTF-8
只要过滤出DATE中的时间即可,命令如下:
curl -s --head http://www.nixops.me | grep ^Date: | sed 's/Date: //g'
返回为:
Thu, 17 Dec 2015 10:26:13 GMT
这个格式date命令就能用了,和date命令整合一下,查询时间:
date -d "$(curl -s --head http://www.nixops.me | grep ^Date: | sed 's/Date: //g')"
设置时间:
date -s "$(curl -s --head http://www.nixops.me | grep ^Date: | sed 's/Date: //g')"
当然我的服务器时间不够精确,你可以把 www.nixops.me 换成 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