[code.nginx] Nginx的时间管理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[code.nginx] Nginx的时间管理相关的知识,希望对你有一定的参考价值。
参考技术A在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配置文件的全局块中进行设置。
Nginx的管理以及升级操作
Nginx的管理以及升级操作
如果Nginx启动了,可以使用nginx的命令来进行管理
- 查看进程:ps -ef | grep nginx
- 平滑启动:nginx -s reload–>不停止nginx的情况下,无痕重启;
- 或者是:kill -HUP 单引号(cat /var/run/nginx.pid)
- nginx.pid就是nginx启动的进程号;
- 这个pid的位置取决于你源码安装指定的位置,yum安装默认就是那;
- 平滑启动的意思是在不停止nginx的情况下,重启nginx,重新加载配置文件,启动新的工作线程,完美停止旧的工作线程。
- 完美停止nginx
- kill -QUIT 单引号(cat /var/run/nginx.pid)
- 如果是想快速停止nginx
- kill -TERM 单引号(cat /var/run/nginx.pid)
- kill -INT 单引号(cat /var/run/nginx.pid)
- 如果想要完美停止工作进程–>这个主要用于平滑升级
- kill -WINCH nginx.pid
- 强行停止nginx
- pkill -9 nginx
- 检查nginx的配置文件是否正确:
- nginx -t
- 停止nginx:
- nginx -s stop
- pkill nginx
- 查看nginx的配置信息
- nginx -V
#查看nginx进程
[root@Test0 ~]# ps -elf |grep nginx
1 S root 9482 1 0 80 0 - 11492 sigsus 12:12 ? 00:00:00 nginx: master process nginx
5 S nginx 9483 9482 0 80 0 - 11606 ep_pol 12:12 ? 00:00:00 nginx: worker process
.........
#平滑启动nginx
#注意这个9482是上面的命令提示出来的nginx的pid号
[root@Test0 ~]# kill -HUP 9482
#或者直接nginx -s reload
[root@Test0 ~]# nginx -s reload
#停止nginx
[root@Test0 ~]# nginx -s stop
#或者使用
[root@Test0 ~]# kill -TERM 9616
#或者
[root@Test0 ~]# kill -INT 9623
#强制停止nginx
[root@Test0 ~]# pkill -9 nginx
#查看nginx的信息
[root@Test0 ~]# nginx -V
nginx version: LJW/nginx
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
.........
#检查nginx的配置文件语法-->显示ok代表没有问题
[root@Test0 ~]# nginx -t
nginx: the configuration file /usr/local/nginx//conf/nginx.conf syntax is ok
Nginx的升/降级操作
- nginx运行了一段时间,有可能需要把版本升级或者是降级操作;那么我们现场也得需要掌握如何升级/降级nginx
- nginx的升级和降级都可以分为四个步骤
- 软件准备
- 预编译
- 编译、
- 配置
–>准备工作如下:
#首先确定一下nginx的版本-->由于一开始的时候我们修改过源代码;导致没能看到nginx的版本-->但是我开始的时候我记得就是nginx-1.16版本
[root@Test0 ~]# nginx -V
nginx version: LJW/nginx
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
................
#首先我们准备一下nginx的1.17版本
[root@Test0 ~]# cd /usr/local/src/
[root@Test0 src]# ls nginx-1.17.10.tar.gz
nginx-1.17.10.tar.gz
#再看一下nginx是在启动状态
[root@Test0 src]# ps -ef | grep nginx
–>预编译、编译
#解压nginx-1.17的源码包-->记住要进入到nginx的源码包目录-->预编译需要哦
[root@Test0 src]# tar -xf nginx-1.17.10.tar.gz
[root@Test0 src]# cd nginx-1.17.10
#预编译-->因为是升级操作-->原来我们是怎么编译的,后面也得怎么编译
#先看看原来编译的参数
[root@Test0 nginx-1.17.10]# nginx -V
...............
configure arguments: --prefix=/usr/local/nginx/ --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module
#确认好了之后就开始预编译
[root@Test0 nginx-1.17.10]# ./configure --prefix=/usr/local/nginx/ --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module
#编译-->注意千万别安装
[root@Test0 nginx-1.17.10]# make
#到这里位置基本完成
–>最后是执行升级/降级操作
- 备份就版本的nginx执行文件
- 替换新版本的nginx执行文件
- 测试一段时间后退出旧版本
#备份旧版本的nginx可执行文件
[root@Test0 nginx-1.17.10]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
#替换新的nginx执行文件
[root@Test0 nginx-1.17.10]# cp objs/nginx /usr/local/nginx/sbin/
#测试一下是否正常
[root@Test0 nginx-1.17.10]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx//conf/nginx.conf syntax is ok
#启动nginx
[root@Test0 nginx-1.17.10]# nginx -s reload
#查一下nginx信息
[root@Test0 nginx-1.17.10]# nginx -V
nginx version: nginx/1.17.10 #-->这里已经看到升级成功
............
以上是关于[code.nginx] Nginx的时间管理的主要内容,如果未能解决你的问题,请参考以下文章