http server优雅启停原理及验证
问题背景
在 http应用程序重启时,如果直接
kill -9
使程序退出,然后再启动,会存在的问题:- 旧的请求未处理完,如果服务端进程直接退出,会造成客户端连接中断(收到
RST
) - 新请求打过来,服务还没重启完毕,造成
connection refused
- 旧的请求未处理完,如果服务端进程直接退出,会造成客户端连接中断(收到
优雅重启整体思路
1.捕获到优雅重启的信号比如SIGUSR2
2. 启动新的子进程,新子进程接管监听端口
3. 新子进程处理新请求,旧进程处理完旧请求退出优雅重启代码思路
1.新的bin文件覆盖旧的bin文件
2.在程序中,通过拦截
signal
,并针对signal
做出相应处理,若是获取到SIGUSR2信号会触发优雅重启3. 进程收到SIGUSR2信号后,将服务监听的socket文件描述符传递给子进程(因为端口不可以重复监听,所以采用把监听端口的文件描述符传递给子进程,子进程里从文件描述符实现对端口的监听)
4. 子进程监听父进程的socket,这个时候父进程和子进程都可以接收请求
5. 子进程启动成功之后,父进程停止接收新的连接,等待旧连接处理完成
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优雅启停原理及验证的更多相关文章
- Nginx(一)安装及启停
目录 1 nginx安装 2 nginx启停 我发现很多博客排版杂乱,表达不清,读者看了往往云里雾里.我此前的博客也是如此,我自己很不满意.今起,每一篇博客都会用心写,此前的博客我也会尽力修改.至少要 ...
- redis安装、配置、启停
Redis is an open source (BSD licensed), in-memory data structure store, used as database, cache and ...
- MySQL 启停过程了解一二
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. GreatSQL是MySQL的国产分支版本,使用上与MySQL一致. 前言 你知道MySQL启停都做了些什么吗? 启动的时 ...
- Oracle BIEE启停脚本
作为BI的开发人员,经常启停BI服务在所难免,启动的过程又比较长,命令需要不同目录切换,简直烦死人呢, 特意整理了linux中的启动脚本,将以下脚本存成biee.sh,后面的过程就相当简单了, 启动: ...
- 编写Redis启停服务脚本
脚本内容如下; fi esac exit$RETVAL 下载脚本:艺搜下载 将下载下来的脚本放在/etc/init.d/目录下 更改脚本权限 chmod 777 /etc/init.d/red ...
- Mysql启停以及恢复备份恢复数据库
1.mysql启停 进入cmd 输入如下命令 net stop mysql(自己起的mysql名称) -------停 net strat mysql ---------------------- ...
- [原创].NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略
原文:[原创].NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略 .NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略 前言:之前的讨论一直关注在怎么从D ...
- 04. 启停redis服务
启动 查看redis.conf文件,可以通过general中的说明,配置通过systemd来启停redis和查看redis状态(作者没有采用,而是使用service管理,service配置参考< ...
- nginx 启停命令
nginx 启停配置 #!/bin/sh # # nginx Startup script for nginx # # chkconfig: - 85 15 # processname: nginx ...
随机推荐
- C#缓存
最近在学习缓存的知识,博客园中的 缓存资料 觉得信息不错值得学习
- listview 控件
private void Form1_Load(object sender, EventArgs e) { //设置该listview关联的imagelist listView1.LargeImage ...
- 6.Renderer Window
渲染是实时的,所见即所得.同时还可以输出一些统计信息. Pixel Snoop:获取颜色值,同时把该值复制到剪贴板,主要用户是获取颜色值 Wireframe:开启后可以查看3D节点图形骨架 Stati ...
- hdu3572Task Schedule 最大流,判断满流 优化的SAP算法
PS:多校联赛的题目质量还是挺高的.建图不会啊,看了题解才会的. 参考博客:http://blog.csdn.net/luyuncheng/article/details/7944417 看了上面博客 ...
- outlook导入配置文件
公司入.离职人员越来越多,所以产生了一个自动化配置邮件的想法 查看了一下资料,outlook有导入配置文件的方法可用. 利用otc工具,打开office2010的安装文件夹,执行setup.exe / ...
- 04--C语言文件操作函数大全(超详细)
fopen(打开文件)相关函数 open,fclose表头文件 #include<stdio.h>定义函数 FILE * fopen(const char * path,const cha ...
- 实现数组类(C++ 拷贝构造函数、拷贝函数)要判断赋值左右对象不相等,坑惨了
#include <iostream> using namespace std; class ArrayIndexOutOfBoundsException{ // 异常类 public: ...
- vs code格式化代码快捷键
windows:shift+alt+F ubuntu: ctrl+shift+i
- WIN7无法保存打印机设置错误0x000006d9处理办法(转载)
办公电脑安装了GHOST版WIN7操作系统,在设置打印机共享时,报(错误0x000006d9),无法设置打印机共享, 查看微软官方文档:说是停止或禁用了Windows防火墙服务,必须启用 Window ...
- Tjoi2019 甲苯先生和大中锋的字符串 后缀自动机_差分
tjoi胆子好大,直接出了两道送分题...... 都 9102 年了,还有省选出模板题QAQ...... Code: #include <bits/stdc++.h> #define se ...