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. markdown 计算器

    计算器 分四种运算(加减乘除).括号.去除最后括号.验证等式是否计算完成 bracket = re.compile(r'\([^()]+\)') # 找括号 multiplys = re.compil ...

  2. 登录linux,输入ls显示anaconda-ks.cfg cobbler.ks ....., 原因在于root@ ~ / 区别

    今天登录linux测试机,想要创建目录,ls的时候,找不到之前的的目录,才发现是目录不对的问题. 首先,先要弄清楚 [root@330c353813ea ~] 和 [root@330c353813ea ...

  3. 【C】一些字符串处理函数

    1.复制函数 我更愿意称之为”字符串覆盖函数” a. strcpy(str1,str2); 将字符串str2 覆盖到str1上 b. strncpy(str1,str2,n); 2.拼接函数 a. s ...

  4. fragment基础 fragment生命周期 兼容低版本

    fragment入门 ① 创建一个类继承Fragment 重写oncreateView方法 public class FirstFragment extends Fragment { @Overrid ...

  5. Kettle通用数据贴源作业设计

    本设计基于以下需求提出 1. 快速接入数据源表(贴源/落地) 2. 无须给单独表开发转换/作业 3. 动态生成数据源连接, 表字段等信息(预先保存在数据仓库中) 本设计所需条件 1. 数据源为关系型数 ...

  6. Quartz经典入门案列

    一.Quartz简介 Quartz是一个开放源码项目,专注于任务调度器,提供了极为广泛的特性如持久化任务,集群和分布式任务等.Spring对Quartz的集成与其对JDK Timer的集成在任务.触发 ...

  7. 我的第一个 Windows 窗口程序(1)

    一般来说,构建一个 Windows 程序可以分为如下几个步骤: 定义窗口类(WNDCLASS) 注册窗口类(RegisterClass) 创建窗口(CreateWindow) 更新显示窗口(Updat ...

  8. [2018.8.12]模拟赛B组

    T1 打表出奇迹,发现结论为\(E(a_n)=n+1\)即可. #include <iostream> #include <cstdio> #include <cctyp ...

  9. ASP.NET MVC5 :Attribute路由使用详解

    1.什么是Attribute路由?怎么样启用Attribute路由? 微软在 ASP.NET MVC5 中引入了一种新型路由:Attribute路由,顾名思义,Attribute路由是通过Attrib ...

  10. mybatis入门截图三

    ----------------------------------------------- <!-- 用户信息的综合查询 --> <select id="userlis ...