做统计图的网站,两个域名指向同一个网站,营销型网站源码,建站 seo课程一、前言 上篇介绍了时间同步的基本概念和常见的时间同步协议NTP、PTP#xff0c;本篇将详细介绍NTP的原理以及NTP在Linux上如何实现校时。
二、NTP原理介绍
1. 什么是NTP 网络时间协议#xff08;英语#xff1a;Network Time Protocol#xff0c;缩写#xff1a;NTP本篇将详细介绍NTP的原理以及NTP在Linux上如何实现校时。
二、NTP原理介绍
1. 什么是NTP 网络时间协议英语Network Time Protocol缩写NTP是在计算机系统之间通过分组交换进行时钟同步的一个网络协议位于OSI模型的应用层。用来使客户端和服务器之间进行时钟同步提供高精准度的时间校正。NTP服务器从权威时钟源例如原子钟、GPS接收精确的协调世界时UTC客户端再从服务器请求和接收时间。 NTP基于UDP报文进行传输使用的UDP端口号为123。
2. NTP协议发展历史 NTP是由美国Delaware大学David L .Mills教授设计的是最早用于网络中时钟同步的标准之一。NTP是从时间协议和ICMP时间戳报文演变而来当前协议为版本4NTPv4这是一个RFC 5905文档中的建议标准。它向下兼容指定于RFC 1305的版本3
3. NTP时钟层级 NTP允许客户端从服务器请求和接收时间而服务器又从权威时钟源例如原子钟、GPS接收精确的协调世界时UTC。 NTP以层级来组织模型结构层级中的每层被称为Stratum。通常将从权威时钟获得时钟同步的NTP服务器的层数设置为Stratum 1并将其作为主时间服务器为网络中其他的设备提供时钟同步。而Stratum 2则从Stratum 1获取时间Stratum 3从Stratum 2获取时间以此类推。时钟层数的取值范围为116取值越小时钟准确度越高。层数为115的时钟处于同步状态层数为16的时钟被认为是未同步的不能使用的。 4. NTP同步原理
NTP最典型的授时方式是Client/Server方式如下图所示。 客户端首先向服务端发送一个NTP请求报文其中包含了该报文离开客户端的时间戳t1;NTP请求报文到达NTP服务器此时NTP服务器的时刻为t2。当服务端接收到该报文时NTP服务器处理之后于t3时刻发出NTP应答报文。该应答报文中携带报文离开NTP客户端时的时间戳t1、到达NTP服务器时的时间戳t2、离开NTP服务器时的时间戳t3客户端在接收到响应报文时记录报文返回的时间戳t4。
客户端用上述4个时间戳参数就能够计算出2个关键参数
NTP报文从客户端到服务器的往返延迟delay。 客户端与服务端之间的时间差offset。
根据方程组 NTP客户端根据计算得到的offset来调整自己的时钟实现与NTP服务器的时钟同步。
三、内核对NTP校时的支持 在之前时钟源clocksource和timekeeper的文章中我们介绍到通常每个tick的定时中断周期do_timer会被调用一次. 在do_timer中调用update_wall_time函数完成xtime等时间的更新操作更新时间的核心操作就是读取关联clocksource的计数值累加到xtime等字段中每过一个tick中断xtime就增加1Hz对应的时间 而Ntp可以调整每个tick中断xtime增加的毫秒数让系统时间走快些或走慢些。
1. timekeeper中的ntp成员
ntp_tick记录了NTP周期的纳秒数
ntp_errorTP时间和当前实时时间之间的差值如果ntp_error大于0表示当前系统的实时时间慢于NTP时间相反如果小于0则表示快于NTP时间
ntp_error_shift存放了NTP的shift和时钟源设备shift之间的差值。NTP层也需要对纳秒数做shift的操作其值由宏NTP_SCALE_SHIFT定义
ntp_err_mult如果ntp_error大于0则为1否则都是0。
在tk_setup_internals函数中对上述变量进行了初始化 tk-ntp_error 0;tk-ntp_error_shift NTP_SCALE_SHIFT - clock-shift;tk-ntp_tick ntpinterval tk-ntp_error_shift;一开始ntp_error被设置为0也就是没有累积错误shift被设置为NTP层的shift和时钟源设备shift之间的差值ntp_tick其实最终被设置成了NTP_INTERVAL_LENGTHNTP_SCALE_SHIFT。
2. NTP调整内核时钟的系统调用 一般来讲调整时间有多种方式包括直接设置时间根据时间差offset调整时间(在当前时间上增加offset)以及调整时钟频率(根据时间跑的慢或者是快说明当前的时钟频率存在偏移)对于系统时钟来说就是每个cycle对应的ns数也就对应到mult和shift。 NTP可以使用adjtimex和ntp_adjtime函数来调整系统时间内核对这两个函数的支持并没有本质区别。adjtimex支持多种调节方式 Ntp校时可分为内核模式和ntp模式这两种模式。。在ntp.conf文件中可以配置使用哪种模式校时当两种模式都打开时只有内核模式起作用。Ntpd默认两种模式都打开的。
enable kernel
enable ntp
disable kernel
disable ntp NTP的系统调用ntp_adjtime和adjtime在内核模式中ntpd在用户态调用ntp_adjtime修改内核的频率。在ntp模式中ntpd在用户态调用adjtime修改内核的time_adjust变量。
2. NTP的全局变量tick_length 我们观察ntp_tick的使用发现在使用中timekeeping模块通过ntp_tick_length函数获取最新的ntp_tick并且根据获取到的ntp_tick判断是否要进行校时ntp_tick_length返回的是ntp.c中定义的tick_length全局变量如下
u64 ntp_tick_length(void)
{return tick_length;
}
那么tick_lenth又是如何计算得到的呢
在内核ntp.c文件second_overflow函数中可以看出tick_length等于tick_length_base加上time_adjust的和即tick_length的值由tick_length_base和time_adjust决定。Ntp服务正是通过修改tick_length_base和time_adjust的值来修改系统的tick_length让系统走快或走慢。
【对比一下几种改变系统时间速度的方式】
1、 adjtimex –t 命令通过修改tick_usec变量来间接修改tick_length_base变量的值。
2、 adjtimex –f 命令通过修改time_freq变量来间接修改tick_length_base变量的值。
3、 ntpd的ntp模式修改内核的time_adjust变量。
上述几种方式修改的内核变量tick_usec, time_freq, time_adjust它们加起来影响着tick_length变量的值每个tick的时长。内核timekeeping.c文件中的update_wall_time函数中会用tick_length变量不停地调整系统时间xtime让系统时间走快或走慢。L