1. 问题背景

    在 http应用程序重启时,如果直接 kill -9 使程序退出,然后再启动,会存在的问题:

    1. 旧的请求未处理完,如果服务端进程直接退出,会造成客户端连接中断(收到 RST
    2. 新请求打过来,服务还没重启完毕,造成 connection refused
  2. 优雅重启整体思路

    1.捕获到优雅重启的信号比如SIGUSR2
                    2. 启动新的子进程,新子进程接管监听端口
                    3. 新子进程处理新请求,旧进程处理完旧请求退出

  3. 优雅重启代码思路

    1.新的bin文件覆盖旧的bin文件

    2.在程序中,通过拦截 signal,并针对 signal 做出相应处理,若是获取到SIGUSR2信号会触发优雅重启

    3. 进程收到SIGUSR2信号后,将服务监听的socket文件描述符传递给子进程(因为端口不可以重复监听,所以采用把监听端口的文件描述符传递给子进程,子进程里从文件描述符实现对端口的监听)

    4. 子进程监听父进程的socket,这个时候父进程和子进程都可以接收请求

    5. 子进程启动成功之后,父进程停止接收新的连接,等待旧连接处理完成

  4. http优雅关闭原理

    http请求的过程会建立TCP连接,http server的关闭本质上是TCP连接的关闭,TCP连接的关闭过程有两种:
           1. 一种是强制关闭:强制关闭时不能再接收数据,如果当前接收缓存中仍有未取出数据或者以后再有数据到达,则TCP会向发送端发送RST包,将连接重置,如图1所示
           2. 另一种是优雅关闭 :优雅关闭时如果缓存中有数据未发出则将其发出去,并且收到所有数据的ACK之后,发送FIN包,开始关闭过程,如图2所示
           RST知识补充: RST标示复位、用来异常的关闭连接
                                  a: 发送RST包关闭连接时,不必等缓冲区的包都发出去,直接就丢弃缓冲区中的包,发送RST
                                  b:接收端收到RST包后,也不必发送ACK包来确认

golang代码中主要利用sync包的waitGroup实现协程的同步,每一个等待的协程进行waitgroup.add(1),每完成一个协程进行waitgroup.Done(),利用waitgroup.wait()进行堵塞,直到所有的协程都完成为止

5.验证方法

1. 强制关闭时: 利用tcpdump进行抓包(tcpdump -i eth0 host $host and tcp port $port),结果如下图,前3行是tcp连接的三次握手过程,第4行向服务端发送177的字节,第5行服务端直接发送RST给客户端,与预期结果一致

2. 优雅关闭时:利用tcpdump进行抓包结果如下,关闭之前的请求发送ACK之后,发送FIN进行关闭

3. 普通重启时:重启期间有短暂的http server 中断,利用curl  host:port/keepalive 验证http服务,以及tcpdump抓包验证,如下图,

4. 优雅重启: kill -SIGUSR2 $pid 进行优雅重启, 新进程接管老进程的监听端口,http服务没有出现异常, 以及tcpdump抓包数据中tcp连接没有异常

其它:

常用信号量

http server优雅启停原理及验证的更多相关文章

  1. Nginx(一)安装及启停

    目录 1 nginx安装 2 nginx启停 我发现很多博客排版杂乱,表达不清,读者看了往往云里雾里.我此前的博客也是如此,我自己很不满意.今起,每一篇博客都会用心写,此前的博客我也会尽力修改.至少要 ...

  2. redis安装、配置、启停

    Redis is an open source (BSD licensed), in-memory data structure store, used as database, cache and ...

  3. MySQL 启停过程了解一二

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. GreatSQL是MySQL的国产分支版本,使用上与MySQL一致. 前言 你知道MySQL启停都做了些什么吗? 启动的时 ...

  4. Oracle BIEE启停脚本

    作为BI的开发人员,经常启停BI服务在所难免,启动的过程又比较长,命令需要不同目录切换,简直烦死人呢, 特意整理了linux中的启动脚本,将以下脚本存成biee.sh,后面的过程就相当简单了, 启动: ...

  5. 编写Redis启停服务脚本

    脚本内容如下; fi   esac   exit$RETVAL 下载脚本:艺搜下载 将下载下来的脚本放在/etc/init.d/目录下 更改脚本权限 chmod 777 /etc/init.d/red ...

  6. Mysql启停以及恢复备份恢复数据库

    1.mysql启停 进入cmd 输入如下命令 net stop mysql(自己起的mysql名称) -------停 net strat mysql   ---------------------- ...

  7. [原创].NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略

    原文:[原创].NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略 .NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略 前言:之前的讨论一直关注在怎么从D ...

  8. 04. 启停redis服务

    启动 查看redis.conf文件,可以通过general中的说明,配置通过systemd来启停redis和查看redis状态(作者没有采用,而是使用service管理,service配置参考< ...

  9. nginx 启停命令

    nginx 启停配置 #!/bin/sh # # nginx Startup script for nginx # # chkconfig: - 85 15 # processname: nginx ...

随机推荐

  1. C#中大批量导入数据SqlBulkCopy

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  2. 全能VIP音乐在线解析

    浏览器安装暴力猴扩展即可使用 // ==UserScript== // @name 全能VIP音乐在线解析 // @version 0.0.10 // @homepage https://greasy ...

  3. javascript学习中自己对作用域和作用域链理解

    在javascript学习中作用域和作用域链还是相对难理解些,下面我关于javascript作用域和作用域链做一下详细介绍,给各位初学者答疑解惑. 首先我们介绍一下什么是作用域?  从字面上理解就是起 ...

  4. IIS网站调用FFMPEG执行截图命令失败的原因(暂时记录)

    之前有个功能是用户上传视频后,网站对其进行截图处理.功能采用FFMPEG操作,在本机新建一个小程序进行调试时是没有问题的. 可功能原封不动挪到项目里,截图竟然失败了,于是开始排查. 期初以为是参数设置 ...

  5. 三维点集拟合:平面拟合、RANSAC、ICP算法

    ACM算法分类:http://www.kuqin.com/algorithm/20080229/4071.html 一: 拟合一个平面:使用SVD分解,代码里面去找吧 空间平面方程的一般表达式为: A ...

  6. VTK读取序列化图像

    vtk获取内存中图像数据 原文链接:http://blog.csdn.net/zmy3376365/article/details/7717721 内存中有段图片数据  ,使用VTK来读入,然后就可以 ...

  7. offset() 方法 文档偏移量

    以前看视频学习听到这个offset()感觉很陌生,没有用过,马上记到笔记里了,今天翻起笔记再次看到,都已经忘记是怎么用的了,所以来到这里狠狠的记下来: offset() 方法返回得或设置元素相对于文档 ...

  8. H5动效的常见制作手法

    众所周知,一个元素,动往往比静更吸引眼球: 一套操作界面,合适的动态交互反馈能给用户带来更好的操作体验: 一个H5运营宣传页,炫酷的动画特效定能助力传播和品牌打造. 近两年,小到loading动画,表 ...

  9. 优动漫PAINT如何打开图形文件

    优动漫PAINT也就是我们常说的clip studio paint(CSP)的中文版本,在优动漫PAINT软件中打开文件的方式有很多,您可以直接拖拽至优动漫PAINT界面或者文档窗口,也可以执行文件菜 ...

  10. PHP迭代器的内部执行过程

    下面我们来了解如何实现一个自定义的迭代器,然后再开始慢慢理解迭代器的内部工作原理.先来看一个官方的例子: class myIterator implements Iterator { private ...