壹、平滑进级步骤

Nginx平滑晋级源码分析,nginx源码

一、平滑晋级步骤

一、重命名在此之前的sbin/nginx文件,将新的nginx文件放到sbin/目录下

#mv ./sbin/nginx ./sbin/nginx.old

#cp ~/nginx ./sbin/

二、向正在运行的nginx发送US君越贰时域信号运行新的nginx,这年新老nginx都会抽出请求,看这三个经过能抢到锁,抢到锁的worker进度能够accpet新请求

#kill -USR2  `cat nginx.pid`

3、观望新的nginx运转正确后,向旧nginx发复信号 甘休旧nginx的周转

#kill -QUIT `cat nginx.pid.oldbin`

 

 

2、源码分析

一,nginx运行时 设置非非确定性信号监听函数,监听实信号

src/core/nginx.c  

澳门金沙国际 1

368行 ngx_init_signals函数 设置要监听的非非确定性信号,和实信号的管理函数

 

src/core/nginx.c  

澳门金沙国际 2

2九一-293行 频限信号为sig->signo,对应的管理函数为sig->handler

 

sig的定义如下

澳门金沙国际 3

QUIT和US昂Cora二的实信号处理函数都为 ngx_signal_handler

相应的流水生产线图为

澳门金沙国际 4

 

 

二、master进度通过sigsuspend挂起在时域信号监听处

澳门金沙国际 5

 

3,向master进程id发送USR2信号

ngx_signal_handler处理USR2信号

src/os/unix/ngx_process.c

澳门金沙国际 6

372行  设置了ngx_change_binary=1

 

master进程接收到时限信号,从挂起状态回涨,继续施行

src/os/unix/ngx_process.c

澳门金沙国际 7

Nginx平滑进级源码分析。277行 ngx_exec_new_binary通过fork运维新的nginx bin文件

 

src/core/nginx.c

澳门金沙国际 8

589行 ngx_set_evviroment 设置新nginx bin的情形变量

640行 ngx_rename_file
通过rename函数将nginx.pid文件重命名称为nginx.pid.oldbin

651行 ngx_execute 运营新的bin文件

鉴于nginx老master进度fork出的新nginxmaster过程,他们能够监听同1个端口,所以新nginx和老nginx能够同时监听端口,具体何人实行看哪三个worker子进度抢到了锁,能够accpet新连接 

 

src/os/unix/ngx_process.c

澳门金沙国际 9

src/os/unix/ngx_process.c

澳门金沙国际 10

src/os/unix/ngx_process.c

 

相应的流程图如下

 

澳门金沙国际 11

 

4、向老的nginx进度发送QUIT复信号,从容关闭

master进程收到QUIT实信号后,将ngx_quit置为1

澳门金沙国际 12

master进度接收到实信号,从挂起状态恢复生机,继续实行

澳门金沙国际 13

209行 ngx_signal_worket_processes 向worker进度发送
NGX_SHUTDOWN_SIGNAL(QUIT)信号

215行 ngx_close_socket 主进度关闭监听的socket

 

src/os/unix/ngx_process_cycle.c

澳门金沙国际 14

50四行 通过kill函数向装有worker进程发送实信号

 

伍、worker进度收到NGX_SHUTDOWN_SIGNAL(QUIT)信号

src/os/unix/ngx_process.c 

澳门金沙国际 15

360行 worker进程将ngx_quit置为1

澳门金沙国际 16

worker进程收到连续信号后从epoll_wait中提示从ngx_process_events_and_timers函数中恢复生机,

710-714行 发现ngx_quit=1后将ngx_quit恢复为0,ngx_exiting置为1,

713行 通过ngx_close_listening_sockets关闭管理的socket

60九行
下一遍巡回开掘ngx_exiting=一后,管理队列中的已有事件和过期事件,开掘未有要拍卖的事件了,就通过ngx_worker_process_exit退出worker进程

 

src/os/unix/ngx_process_cycle.c

澳门金沙国际 17

十24行 调用种种模块的exit_process方法

1067行 销毁内部存储器池

相应的流程图如下

澳门金沙国际 18 

 

陆、子进度退出后,作为父进度的master进度会收到SIGCHLD时限信号

src/os/unix/ngx_process.c

澳门金沙国际 19

3八七行 父进度收到SIGCHLD后将ngx_reap置为1,

43七行
发掘实信号是SIGCHLD后进行ngx_process_get_status函数判别worker子进度是例行退出,仍旧不行退出

 

src/os/unix/ngx_process.c

澳门金沙国际 20

4九肆-49玖行 假使发掘worker子进程假使是常规退出的,会将exited置为1

 

master进度接收到时域信号,从挂起状态苏醒,继续实行

澳门金沙国际 21

176行
发现ngx_reap=1后,ngx_reap_children函数判别是或不是必要重启worker进度

假诺worker是因为接到了quit时限信号寻常退出的,全部worker进度退出时,live=0

18三行 live=0 并且吸收接纳了ngx_quit信号
 通过ngx_master_process_exit关闭master进程

 

src/os/unix/ngx_process_cycle.c

澳门金沙国际 22

61五头要worker于今才是因为始料不如退出的,并且能够重启,则调用ngx_spawn_process重新启航一个worker子进度

64贰 假如有worker进度还在运作则live=11旦整个的worker子进度都早已脱离则live=0

 

src/os/unix/ngx_process_cycle.c

澳门金沙国际 23

656行 ngx_delete_pidfile 删除pid文件

666行 ngx_close_listening_sockets 关闭监听端口

6八五行 销毁内部存款和储蓄器池

686行 退出

相应的流程图如下

澳门金沙国际 24

 

 

 

 

 

 

PS:推荐一个好爱人的微信公众号,三个每一天都在考虑或然在思量路上的万众号营业青娥~澳门金沙国际 25

 

一、平滑进级步骤
1、重命名从前的sbin/nginx文件,将新的nginx文件放到sbin/目录下 #mv
./sbin/nginx ./sbin/nginx…

初探nginx架构##\

Taobao团队的nginx教材
nginx版本1.12

  1. nginx与外界,nginx的master与worker之间都以透过功率信号相连接的。

事例:从容的重启
master接受到功率信号后,重新加载配置,用新陈设fork新的worker出来。
master向老的worker发送非时域信号,老的worker收到时域信号后,不再接受拍卖新的连年。
老的worker处理完现成连接后,从容退出。

这般,利用模拟信号就实现了不中断服务的再次加载配置。
相关代码:[20170512更新]
1)ngx_process.c:signals全局数组,line
3玖,定义了颇具的复信号名(nginx自定名和系统频域信号名的呼应)
2)ngx_config.h:NGX_RECONFIGURE_SIGNAL 被定义为SIGHUP
3)ngx_process.c:ngx_signal_handler,全数的时域信号管理函数都被归到三个能量信号管理函数中,用switch管理,对于worker进程,SIGHUP被忽略了,对于主进程,它把一个大局的变量(类型sig_atomic_t,待扩展)ngx_reconfigure设置成了1。
4)ngx_process_cycle.c(os/unix):3)提到的ngx_reconfigure被安装成一之后,主循环有3个断定,调用了ngx_start_worker_processes。重新确立了多少个种类为JUST_RESPAWN的worker,那么些是新worker。然后向全部进度发送NGX_SHUTDOWN_SIGNAL(定义为SIGQUIT)

1、重命名以前的sbin/nginx文件,将新的nginx文件放到sbin/目录下

5)3中ngx_signal_handler中worker部分,对NGX_SHUTDOWN_SIGNAL的拍卖是置全局变量ngx_quit

一;前边提到的worker_process_cycle中对这几个进行了决断,关闭监听套接字,关闭空闲连接,然后退出进度。(关于SIGCHLD的追踪待扩充)
陆)子进度退出会有SIGCHLD随机信号触发,ngx_signal_handler会设置ngx_reap =
1并且waitpid等到退出子进度的pid,线性遍历数组找到子进程的调节块,设置.exited
= 1;主进度会去reap .exited=1的子进度。

敲定:SIGHUP触发主进度的RECONFIGURE动作==>主进度建构新worker==>向装有老worker发送SIGQUIT信号==>收到>SIGQUIT的老worker扫尾退出==>主进度去收割老worker的尸体。热重启达成。

  1. nginx保障各个worker等可能率接受管理请求的秘籍
    nginx未有用叁个线程接收然后分发到各样线程中去的做法。master进度初始化listenfd,然后fork出worker进程,worker进程持有listenfd,在注册读事件前抢八个大局的accept_mutex互斥锁,抢到互斥锁的不得了进度,向epoll注册读事件,所以接受连接那件事,都以worker在做。
    也就那样做一定会有不公道的事情发生:ngx_accept_disabled变量,它定义为worker所能承受的最地拉那接数 *
    八分之一 –
    空闲连接数,当空闲连接数小于最奥斯汀接数的百分之十二时,ngx_accept_disabled大于零,此时的worker就不会去抢锁了,转而改为每一遍抢锁的时候,会将ngx_accept_disabled减一,直至该变量小于0。
    连锁代码:
    ngx_event.c:try_lock_accept_mutex()去获得锁,然后拿走锁的历程去注册accept事件。

美团面试问到:即便您自身规划服务器,设计为多进度照旧二十八线程?
答案大致料定是多进程,正是因为经过CRASH了,其余的经过还不受影响,只影响局地服务,线程借使CRASH了
一切进度就都没了。

#mv ./sbin/nginx ./sbin/nginx.old

#cp ~/nginx ./sbin/

二、向正在运作的nginx发送US普拉多二实信号运营新的nginx,这年新老nginx都会吸收接纳请求,看那个历程能抢到锁,抢到锁的worker进度能够accpet新请求

#kill -USR2  `cat nginx.pid`

三、观看新的nginx运转正确后,向旧nginx发连续信号截至旧nginx的运行

#kill -QUIT `cat nginx.pid.oldbin`

 

 

2、源码分析

一,nginx运转时
设置非能量信号监听函数,监听复信号

src/core/nginx.c  

澳门金沙国际 26

368行 ngx_init_signals函数 设置要监听的时限信号,和复信号的管理函数

 

src/core/nginx.c  

澳门金沙国际 27

2九1-293行 信号为sig->signo,对应的管理函数为sig->handler

 

sig的定义如下

澳门金沙国际 28

QUIT和US大切诺基二的实信号管理函数都为 ngx_signal_澳门金沙国际 ,handler

相应的流水生产线图为

澳门金沙国际 29

 

 

二、master进程通过sigsuspend挂起在确定性信号监听处

澳门金沙国际 30

 

3,向master进程id发送USR2信号

ngx_signal_handler处理USR2信号

src/os/unix/ngx_process.c

澳门金沙国际 31

372行  设置了ngx_change_binary=1

 

master进程接收到随机信号,从挂起状态上升,继续实行

src/os/unix/ngx_process.c

澳门金沙国际 32

277行 ngx_exec_new_binary通过fork运营新的nginx bin文件

 

src/core/nginx.c

澳门金沙国际 33

589行 ngx_set_evviroment 设置新nginx bin的情况变量

640行 ngx_rename_file
通过rename函数将nginx.pid文件重命名称为nginx.pid.oldbin

651行 ngx_execute 运营新的bin文件

鉴于nginx老master过程fork出的新nginxmaster进程,他们能够监听同二个端口,所以新nginx和老nginx能够同时监听端口,具体什么人试行看哪三个worker子进度抢到了锁,能够accpet新连接 

 

src/os/unix/ngx_process.c

澳门金沙国际 34

src/os/unix/ngx_process.c

澳门金沙国际 35

src/os/unix/ngx_process.c

 

相应的流程图如下

 

澳门金沙国际 36

 

四、向老的nginx过程发送QUIT时域信号,从容关闭

master过程收到QUIT随机信号后,将ngx_quit置为1

澳门金沙国际 37

master进度接收到能量信号,从挂起状态复苏,继续施行

澳门金沙国际 38

209行 ngx_signal_worket_processes 向worker进度发送
NGX_SHUTDOWN_SIGNAL(QUIT)信号

215行 ngx_close_socket 主进度关闭监听的socket

 

src/os/unix/ngx_process_cycle.c

澳门金沙国际 39

50四行 通过kill函数向全数worker进度发送功率信号

 

伍、worker进程收到NGX_SHUTDOWN_SIGNAL(QUIT)信号

src/os/unix/ngx_process.c 

澳门金沙国际 40

360行 worker进程将ngx_quit置为1

澳门金沙国际 41

worker进度收到功率信号后从epoll_wait中唤醒从ngx_process_events_and_timers函数中平复,

710-714行 发现ngx_quit=1后将ngx_quit恢复为0,ngx_exiting置为1,

713行 通过ngx_close_listening_sockets关闭管理的socket

609行
下一遍巡回发掘ngx_exiting=壹后,管理队列中的已有事件和过期事件,开采并未有要拍卖的风浪了,就通过ngx_worker_process_exit退出worker进程

 

src/os/unix/ngx_process_cycle.c

澳门金沙国际 42

10二4行 调用各类模块的exit_process方法

十67行 销毁内部存储器池

相应的流程图如下

澳门金沙国际 43 

 

陆、子进度退出后,作为父进度的master进程会收到SIGCHLD时域信号

src/os/unix/ngx_process.c

澳门金沙国际 44

3八七行 父进程收到SIGCHLD后将ngx_reap置为1,

437行
发掘功率信号是SIGCHLD后举行ngx_process_get_status函数判定worker子进程是符合规律退出,还是那个退出

 

src/os/unix/ngx_process.c

澳门金沙国际 45

4玖4-49玖行 借使发现worker子进度即便是例行退出的,会将exited置为壹

 

master进度接收到信号,从挂起状态复苏,继续推行

澳门金沙国际 46

176行
发现ngx_reap=1后,ngx_reap_children函数剖断是或不是须求重启worker进程

如果worker是因为接到了quit功率信号平常退出的,全部worker进度退出时,live=0

1八三行 live=0 并且吸纳了ngx_quit信号
 通过ngx_master_process_exit关闭master进程

 

src/os/unix/ngx_process_cycle.c

澳门金沙国际 47

61九一旦worker现今才是因为始料不比退出的,并且能够重启,则调用ngx_spawn_process重新开动三个worker子进度

64二 假诺有worker进程还在运维则live=一万一全数的worker子进度都早已退出则live=0

 

src/os/unix/ngx_process_cycle.c

澳门金沙国际 48

656行 ngx_delete_pidfile 删除pid文件

666行 ngx_close_listening_sockets 关闭监听端口

6八伍行 销毁内部存储器池

686行 退出

相应的流程图如下

澳门金沙国际 49

 

相关文章