设为首页 收藏本站
查看: 557|回复: 0

[经验分享] nginx多进程模型之热代码平滑升级

[复制链接]

尚未签到

发表于 2016-12-26 09:20:43 | 显示全部楼层 |阅读模式
  平滑升级的主要过程包括一下步骤:
  1. 新代码make执行完后,这里不用在make install 了,接下来重名/sbin/nginx为nginx.old
  # mv /usr/local/nginx/sbin/nginx/usr/local/nginx/sbin/nginx.old
  2. 复制编译后objs目录下的nginx文件到nginx的安装目录sbin/下
  # cp objs/nginx /usr/local/nginx/sbin/
  3. 让nginx把nginx.pid文件修改成nginx.pid.oldbin,随即启动nginx,实现不间断
  # kill -USR2 `cat/usr/local/nginx/nginx.pid`
  # kill -QUIT `cat/usr/local/nginx/nginx.pid.oldbin`
  当然,官方上有个更加详细的过程,包括了取消升级、新旧代码同时保留等操作,这里我们主要看上述给出简单升级的实现。
  http://wiki.nginx.org/ChsCommandLine
  这里我们主要看步骤3:
  nginx里面讲USR2信号定义成NGX_CHANGEBIN_SIGNAL。
  #define NGX_CHANGEBIN_SIGNAL USR2
  它的处理函数,跟其他的一样信号一样,使用了ngx_signal_handler。这个函数在配置热加载的那篇文章里已经接触过了,我们在执行kill -USR2 `cat /usr/local/nginx/nginx.pid`时,master进程会得到信号,因为pid文件中记录了master进程的pid。

// ngx_process这个变量记录了接收到信号的进程类型,这里很明显是master process(因为通过master的pid发出的信号)
switch (ngx_process) {
case NGX_PROCESS_MASTER:
case NGX_PROCESS_SINGLE:
switch (signo) {

case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
/* 这里给出了详细的注释,更通俗一点来讲,就是说,进程现在是一个
* master(新的master进程),但是当他的父进程old master还在运行的话,
* 这时收到了USR2信号,我们就忽略它,不然就成了新master里又要生成
* master。。。另外一种情况就是,old master已经开始了生成新master的过程
* 中,这时如果又有USR2信号到来,那么也要忽略掉。。。(不知道够不够通俗=.=)
*/
if (getppid() > 1 || ngx_new_binary > 0) {
/*
* Ignore the signal in the new binary if its parent is
* not the init process, i.e. the old binary's process
* is still running.  Or ignore the signal in the old binary's
* process if the new binary's process is already running.
*/
action = ", ignoring";
ignore = 1;
break;
}
// 最重要的操作在这里,通过将ngx_change_binary置为1,来告诉master
// 应该去启动一个新的实例了,也就是说,master里面在检测到这个变量为// 1时,就会做新nginx实例的生成工作了
ngx_change_binary = 1;
action = ", changing binary";
break;…
}
}

  新实例的产生在ngx_master_process_cycle函数里处理,这个函数大家应该很熟悉,它主要是在一个for循环里来监控各种信号和状态,来控制系统和工作进程。

for ( ;; ) {

//上面已经提过,USR2的信号处理里面,会将ngx_change_binary置为1,这样在master循环里,就可以做处理了。
if(ngx_change_binary) {
ngx_change_binary = 0;
ngx_new_binary = ngx_exec_new_binary(cycle,ngx_argv);
}

}

  在函数ngx_exec_new_binary里面,主要的工作就是将listen的fd,放到环境变量中,格式为:NGINX=fd1;fd2;fd3……(这个后面讲!),然后将nginx.pid改成为nginx.pid.oldbin,最后就是通过ngx_execute,其实就是execve来启动新实例。。。
  这里有个地方要提一下,就是上面提到的listen fd,它被放到了环境变量中,目的就是在新实例启动的过程中,通过ngx_add_inherited_sockets来拿到之前的listen fd,重新使用,之所以要这样,是因为新的实例是通过fork+execve来产生,不是跟简单fork之后子进程那样直接就可以拿到这个父进程的listen fd来用。
  在步骤3中,我们通过发送QUIT信号将旧的进程来关闭。涉及的流程如下:

// 收到SIGCHLD,意味着子进程(即worker 进程),会将ngx_reap置1,这样在master中可以
// 检测到这个变量的值,让后重启子进程。。。
if (ngx_reap) {
ngx_reap = 0;
live = ngx_reap_children(cycle);
}
// live为1表示有子进程在运行,为0代表,所有子进程都退出了,这是如果有退出之类的// 信号,那么就直接exit退出了。
if (!live && (ngx_terminate ||ngx_quit)) {
ngx_master_process_exit(cycle);
}

// 正式处理QUIT信号
if (ngx_quit) {
//通知worker进程,处理完自己的事务之后自动退出。
ngx_signal_worker_processes(cycle,ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
// 之后的处理就是关闭listenfd,不在监听连接。

}

  这里简单说下worker进程在接收到父进程通知的NGX_SHUTDOWN_SIGNAL会,将ngx_quit置1,当然对于ngx_quit的处理,在worker和master是不一样的,需要区分,这也就是ngx_process类型的作用啦。后面worker进程会停止关闭继承的listenfd,同时accpet新连接的行为也消失了,然后呢,进程会等到已经”hold”的连接全部处理之后再退出,做到善始善终!

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-319459-1-1.html 上篇帖子: Windows下Nginx+PHP5的安装与配置方法 下篇帖子: Nginx源代码分析
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表