nginx中很多地方都需要用到时间戳信息,但是如果每一次都直接调用系统函数来获取,虽然可以保证时间的精确性,但是却会严重降低系统的性能。考虑到Nginx中很多地方用到的时间戳并不需要十分精确,从系统性能方面考虑,nginx采用缓存时间戳的方法来处理。
1. 相关变量的定义
这里对于每一种时间
的缓存都用一个数组来实现。之所以用数组,是因为我们在调用ngx_time_update()这一函数过程中,很有可能在中间的某个时刻别的模块正在使用我们所缓存的时间。这就可能会出现,我们更新某个时间时,可能只更新了一部分,比如更新了秒
部分,但是却还没有来得及更新毫秒
部分,这时候就被别的模块所使用,则显然是存在问题的。这里采用一个足够大的数组,确保其他模块在使用时只会用到我们更新完成的,而对于正在更新的则不会被引用到。
-
slot: 用于记录当前我们需要更新那个槽的时间
-
ngx_time_lock: 更新时间时加的互斥锁,防止同时调用ngx_time_update()函数造成混乱
-
ngx_current_msec: 缓存的当前时间的毫秒数。注意这个时间由于表示范围的关系,一般只作为程序内部的一个相对精确的时间区间
(time diff)来使用
-
ngx_cached_time: 当前nginx缓存的最新时间
-
ngx_cached_err_log_time: 当前nginx缓存的error log格式的时间
-
ngx_cached_http_time: 当前nginx缓存的http 格式的时间
-
ngx_cached_http_log_time: 当期nginx缓存的http log格式的时间
-
ngx_cached_http_log_iso8601: 当前nginx缓存的http log iso8601格式的时间
-
ngx_cached_syslog_time: 当前nginx缓存的syslog格式的时间
-
cached_gmtoff: 用于缓存当前本地时间与GMT的时差(以分钟
为单位)。这里之所以要缓存,是因为localtime() 与 localtime_r()函数都不是异步信号安全( Async-Signal-Safe)的,因此我们在通过信号更新时间时就不能调用这两个函数,此种情况下如果要将utc时间转换成gmt的话,就要用到本变量。
如下是为了实现上面各缓存时间的数组:
static ngx_time_t cached_time[NGX_TIME_SLOTS];
static u_char cached_err_log_time[NGX_TIME_SLOTS]
[sizeof("1970/09/28 12:00:00")];
static u_char cached_http_time[NGX_TIME_SLOTS]
[sizeof("Mon, 28 Sep 1970 06:00:00 GMT")];
static u_char cached_http_log_time[NGX_TIME_SLOTS]
[sizeof("28/Sep/1970:12:00:00 +0600")];
static u_char cached_http_log_iso8601[NGX_TIME_SLOTS]
[sizeof("1970-09-28T12:00:00+06:00")];
static u_char cached_syslog_time[NGX_TIME_SLOTS]
[sizeof("Sep 28 12:00:00")];
-
week: 星期的字符串表示
-
months: 月份的字符串表示
2. 函数
本函数主要是初始化各种时间字符串表示形式的长度。接着调用ngx_time_update()更新各变量到最新时间。
3. 函数ngx_time_update()
此获取当前最新时间,然后更新数组中的值。下面简要分析一下函数的实现流程:
4. 函数ngx_time_sigsafe_update()
本函数主要是处理通过信号
来更新缓存时间。注意,此处只会更新ngx_cached_err_log_time与ngx_cached_syslog_time这两个精度要求相对较低的缓存。
5. 函数ngx_http_time()
本函数用于将时间t
格式化成http格式
6. 函数ngx_http_cookie_time()
本函数用于将时间t
格式化成cookie格式
7. 函数ngx_gmtime()
本函数用于将time_t
格式表示的时间转换成ngx_tm_t
格式。
8. 函数ngx_next_time()
本函数用于计算相对于当前本地时间
when秒后的时间。
[参看]
-
TM结构体详解
-
nginx的时间管理
-
nginx + lua环境下时间戳更新不及时的问题
-
深入剖析nginx时间缓存
-
理解 Memory barrier(内存屏障)