在Linux平台上获取系统时间的方法有很多,比如使用time()函数、gettimeofday()函数和localtime()函数等,大部分函数本质上都是通过系统调用来获取时间的。但是使用系统调用时,有一个问题需要特别关注,就是系统调用开销的问题。
Nginx服务器程序在获取系统时间时,本质上使用的是gettimeofday函数,该函数是C语言库提供的函数,从严格意义上来讲,该函数不也是系统调用,但它是对系统调用sys_gettimeofday()的封装,因此一般也就认为它是一个系统调用了。
大家都知道,Linux平台上程序函数调用可以分为库调用和系统调用两大类,这里不过多的解释这两种机制的不同,主要是明确系统调用与库调用相比,时间成本是相当巨大的。程序执行一次系统调用将至少经过一下步骤:
在Linux平台上使用C语言进行程序设计时,为了精确获取系统时间,我们经常会使用gettimeofday()这个函数。该函数的原型为:
调用该函数后,当前的时间将用timeval结构体返回,时间可以精确到微秒。当地时区的信息则放在timezone结构体中。timeval结构体的定义为:
gettimeofday()函数在执行过程中,一般情况下实际上是调用了另一个函数sys_gettimeofday(),该函数才是名副其实的系统调用,通过该调用就可以获取保存在系统内核中的时间信息。在实际程序设计中是不提倡频繁使用gettimeofday()函数的。
vsyscall方式在内存中创建了一个内核态的共享页面,它的数据由内核来维护,但这块区域用户态也有权限访问,通过这样的机制,不经过系统中断和陷入内核也能获取一些内核信息。x86_64体系上使用vsyscall方式实现了gettimeofday()的功能,这样系统开销比普通的系统调用要小的多。
Nginx服务器重视程序的高效运行,Nginx程序采取缓存时间的方法来减少对gettimeofday()的调用,并且每个工作进程会自行维护时间缓存。Nginx的时间缓存一般会赋值给一下四种变量,更新缓存时是同步更新的。
Nginx服务器更新时间缓存的两个函数是ngx_time_update()和ngx_time_sigsafe_update(),具体的实现的源码都在/nginx/src/core/ngx_time.c中可以找到。我们分别来分析一下它们的源码。
1.ngx_time_update()
该函数是Nginx服务器时间管理的核心函数。更新时间缓存的过程实际上是一个写缓存的过程,Nginx服务器为了解决信号处理过程中更新时间缓存产生的数据一致性的问题,需要使用原子变量ngx_time_lock进行写加锁。
2.ngx_time_update()的调用
该函数的调用时机主要有三个:一是在Nginx服务器主进程捕捉、处理完一个信号返回的时候。二是在缓存索引管理进程中调用该函数,用于标记缓存数据的时间属性。三是在Nginx服务器工作进程中在进行事件处理时调用了该函数。主要是第三种情况对该函数的调用频率较高。
epoll_wait()函数用于等待事件的产生,执行epoll_wait()函数返回后会调用ngx_time_update()函数更新时间缓存。当epoll机制通知有事件到达或者epoll机制超时退出时,Nginx服务器程序就会更新一次缓存时间。然后调用各个事件对应的处理函数处理事件。
指令timer_resolution用于设置执行两次缓存时间更新工作之间的间隔时间。该参数设置的越大,则对系统调用gettimeofday()的使用频率就越低,但缓存时间的精度也就越低。该指令的语法结构为:
其中的Interval参数就是更新时间间隔,默认值为100ms。该指令只能在Nginx配置文件的全局块中进行设置。
系统时间不是当前时间:
系统时间不是当前时间。网上说用命令ntpdate pool.ntp.org校准,发现校准后date读取的时间和标准时间相差16个小时。后来找到了靠谱的校准方法,特记录一下。
yum install -y ntpdate
ntpdate ntp.api.bz
或者
ntpdate -u ntp.api.bz
-u参数说明:指定使用无特权的端口发送数据包。 当在一个对特权端口的输入流量进行阻拦的防火墙后是很有益的, 并希望在防火墙之外和主机同步。防火墙是一个系统或者计算机,它控制从外网对专用网的访问。
NTP服务器-推(转自己网络,但亲测可用) 210. 72 .145.44 (网上说是国家授时中心服务器,但是实际测试不可用)
date命令的常见参数的用法:
date -s "2014-12-25 15:15:15"
date +%Y 以四位数字格式打印年份 eg: 2018
date +%y 以二位数字格式打印年份 eg: 18
date +%m 月份
date +%d 日期
date +%H 小时
date +%M 分钟
date +%S 秒
date +%w 星期,如果结果显示0,则表示周日
注意:
date后面要有空格
字母区分大小写
date -d "-1 day" +%d 前一天的日期
date -d "-1 hour" +%H 前一小时
date -d "-1 min" +%M 前一分钟
centos查看设置系统时区
cat /etc/sysconfig/clock
cat /etc/ chaodiquan.com /clock
hwclock 查看系统bios时间
查看硬件时钟用命令:
hwclock --show 或者 hwclock -r
hwclock -w //将系统时钟写入硬件时钟
硬件时钟与系统时钟同步:
# hwclock --hctosys
或者
# clock --hctosys
注意:date命令只操作系统时间,hwclock操作硬件时钟,因此在date 修改时间后 最好用hwclock 同步一下,以免系统非正常关机造成时间不同步。clock和hwlock命令等效。上面的hwclock都可以替换为clock。
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)