02-nginx信号量

Posted 绿茵好莱坞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了02-nginx信号量相关的知识,希望对你有一定的参考价值。

刚才完了nginx的编译,nginx的编译还是挺简单的。控制nginx:重启、关闭。只有孤零零的一个二进制文件nginx

通过信号来控制它,Linux操作系统进程与进程之间通过信号来通信。荷兰的一位计算机科学家通过火车轨道的红绿灯产生灵感提出了信号这个概念。

nginx的官方command line的地址已被改为:https://www.nginx.com/resources/wiki/start/topics/tutorials/commandline/


Nginx信号量

nginx确实在运行,不过是子进程(worker process)在运行,主进程(master process)并没有在运行,看来上节启动nginx主进程(master process)还存在着问题。

注意主进程的文件不直接响应浏览器的请求,主进程是用来管理子进程的。子进程响应浏览器的请求,主进程负责影响子进程,或者是紧急地杀死子进程。所以子进程叫worker,才是真正的工作者。

主进程和子进程的关系

杀死子进程不能用很暴力的pkill -9,你要是在工作中特别是访问量很大的网站不能这么暴力来的。很多人正在下单子,但是你这个进程啪一下给人家关了,怎么办,钱也扣了。单子还没有写到服务器上。所以引入信号量

使用kill -INT杀死nginx子进程worker process,worker process的进程号是8889.然后重新执行./sbin/nginx启动nginx就成功了,上节的问题(nginx子进程占用了80端口)解决了。查看之后发现nginx主进程和子进程都启动了。


再杀死主进程12077,再查看发现nginx被关闭了


TERM或者是INT紧急地杀掉nginx进程,轻易不要这样用。QUIT优雅地关闭进程。如果说有人在下载但是没有下载完,你要是一下子给人关了,下载到一半或者是付钱付到一半怎么办。优雅是指某个worker正在工作先不杀你,某个worker空闲着就把先把你杀掉。等这个worker工作完了就杀掉,不要再接收新的请求了,最后这个主进程也消亡了。

要是晚上机器要停个五分钟休息一下,建议就使用优雅的关闭QUIT


HUP 如果使用了HUP这个信号量,将会开启新的worker 进程,工作子进程,新的工作进程会读新的配置文件,然后会优雅地关掉旧的子进程。旧进程间接地几秒钟之后就消失了,新进程全部得到的是新配置文件。HUP将会有一个很好的功能是,nginx下有一个很强大的功能,方便的功能,改完配置文件之后不需要重启主进程(apache就得要重启一下它的主进程)。在nginx下直接HUP一下,你新读取的配置就生效了。新写的配置就生效了。

测试一下

修改nginx的配置文件nginx.conf,增加一个索引文件ab.html.并且在ab.html上写些内容。

在ab.html上加些内容

你没有重启,也没有通过信号软重启。


下面使用信号量HUP软重启。

访问nginx的时候索引文件就变成了ab.html而不是index.html

修改配置文件nginx.conf影响的是索引文件究竟是html文件夹下的哪一个html文件先出来,是ab.html还是index.html。


再试一次

修改配置文件

script的小技巧:把链接赋给它自身。

修改index.html,增加一段script

修改ab.html,把那段script也改成页面不断地到一个根目录,要把自己刷新到根目录。

 刷新到根目录当前访问的不正是ab.html吗?修改了配置文件把它改成index.html但是一直没生效是因为没有重启。

修改了配置文件之后为什么不立即生效?你怎么过了好几秒钟才生效,为什么不立即生效啊?这就是我们所说的优雅。因为这个页面用JS自己刷新自己,刷新的速度是非常快的,导致它那个进程压根就没有结束,没有结束那它就得在那里运行着了。


再一次把nginx.conf改到ab.html,让它优雅地重启。这次重启达到的效果:重读最新的配置文件。所以并不会立即生效,因为我们的JS正在狂刷新,导致它这个nginx的进程压根就没有结束。

中间一直没断过线,已经变过来了。


HUP:你改了配置文件之后,重读配置文件,它就发挥作用了。


USER1。如果你是运维的话,你会经常碰到它。比如:新建了一个日志文件,旧的日志文件要打包存起来。在Linux中,一个文件对应一个节点叫做inode。inode才是在硬盘上/磁盘上那个文件真正的位置,至于那文件名只是表象罢了,就像猪八戒看到白骨精变的那个美女一样。你真正指向的是磁盘上的哪一块文件那就源源不断的对它写啊写,写日志。日志备份很容易,给它改一下名字就完了。这样不行,因为你在对日志文件给名字,但是这个文件一直被nginx进程打开,就算你改了名,它还是打开的那个文件描述符,还是指向这块磁盘空间,还是指向这块的磁盘文件。就算你改名字了,它还是往这块磁盘写。就算你把它删了,它还是往这个inode上写。所以应该这样做:

把旧的日志文件a重新改成a.bak保存这没错,同时还得再重新建立一个a文件,同时还得好声好气告诉nginx这里有一个新的日志文件a让它去读这一块,来读最新的日志文件。

所以在日志切割的时候

每秒的访问速度很快,访问nginx的速度很快,访问次数在不断的增加。


你更改你的,我给日志文件改个名字,比如说用日期来做备份。很奇怪,日志文件的名字已经被改了,但是它的文件大小还在不断地增大。

它的文件大小还在不断地增大。这是Linux文件系统的特殊之处。因为它真正指向磁盘上的那个东西是叫节点,至于名字是无所谓,你改了名字又如何呢?节点还是那个节点,这个进程还是冲着那个节点写,导致你改了名字还是往那个节点写。

新增一个日志文件:access.log之后

access.log的大小根本没有发生变化。真正指向磁盘的文件是用了inode节点,而不是说光靠一个文件名。现在你是把文件名改了,但是linux系统根本不买账,进程根本不买账。所以我就是刚才打开的进程一直往里面写。


要想备份日志文件,就得使用信号量USR1。

旧的配置文件access.log.0305已经不变了,写新的配置文件access.log上去了。开发还用的少一些,如果是运维,老板说这个日志每天晚上你得备份起来,并且第二天写新日志上,这个时候就得靠USR1了。


USR2。平滑地升级。比如说nginx用的是1.4,过几天用1.6了,1.6重新编译的话,把日志文件又复制到/usr/local/nginx下面去了。一复制呢,就得重新启动这个新进程。新进程一启动,旧进程怎么办,使用信号量USR2。这个新进程将会控制旧进程里面的东西,如果有访问旧进程的,这一次你访问完毕了你就结束吧,你旧的别想再有机会启动了,后来都是这个1.6的新版本在重新启动,响应新的请求。所以USR2和WINCH配合起来用于升级的时候用。


不用查进程号也可以kill的方法。其实说到底还是离不开进程号,只是变通一下罢了。

Linux内核是根据进程号管理的。不想老是查看进程号,可以查看它的pid文件,它的pid文件只是把进程号记录下来了。也可以把进程文件的进程号作为参数赋给kill


虚拟目录的配置:基于ip的虚拟主机,基于端口的虚拟主机,基于域名的虚拟主机。

以上是关于02-nginx信号量的主要内容,如果未能解决你的问题,请参考以下文章

FreeRTOS 信号量

信号量

freeRTOS中的信号量和互斥信号量的区别以及用法

linux进程间信号量的调试信号

Linux进程间通信 --- 信号量

System V 信号量使用相关函数