Golang 平滑关闭/重启与热编译技术

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

Golang 平滑关闭/重启与热编译技术

1 平滑关闭

本文所讨论的平滑关闭是指,HTTP服务、RPC服务、Socket长服务等各种网络服务的平滑关闭。

1.1 平滑关闭的步骤

  1. 关闭监听器listener,不再接收新的请求
  2. 关闭空闲连接,等待新建连接、活动连接的关闭(忽略被劫持的连接)
  3. 通过回调函数,处理一些自定义的收尾工作(如一些缓存数据的持久化等)
  4. 退出进程

1.2 关键点:跟踪所有连接的状态

跟踪所有连接的状态是做到平滑关闭的关键。

一个连接,通常有如下几种状态:

  • New 新建的连接
  • Active 活动中的连接
  • Idle 未断开的空闲连接
  • Hijacked 被其他网络服务劫持的连接
  • Closed 已关闭的连接

通常的做法是,使用一个map字典记录listener接收到的所有连接conn及其状态,并在conn发生状态改变时,修改其状态。

1.3 实现平滑关闭操作

首先,将关闭listener、关闭空闲conn、等待新建及活动连接的关闭、处理自定义收尾工作这几项功能封装为一个Shutdown函数。形式或许为:

func Shutdown(context.Context) error

其中,Context可以定义超时条件。

其次,我们可以通过给进程发生软中断信号(如Linux的kill命令,windows的Ctrl+C)来触发调用Shutdown函数,执行平滑关闭操作。

或者也可以通过API接口,在新的协程中调用该函数,可以达到同样效果。


2 平滑重启

平滑重启,又叫做平滑升级、优雅重启。实际上它包含两部分内容:

  • 平滑关闭老进程
  • 无停服切换至新进程

平滑关闭在上面第1章节已经讲述,因此该章节只讨论无停服切换新进程的问题。

严格意义的无停服切换新进程只在Linux阵营可以实现。Windows是不支持的,只能尽力缩短停服时间。

2.1 平滑重启步骤

Linux下的平滑重启步骤:

  1. 如需升级服务则用新的可执行文件替换老的可执行文件,如只需平滑重启则跳过这一步
  2. 通过信号或API调用平滑重启函数,完成操作:
    1. 使用当前进程的listener文件与相关环境变量、启动参数作为参数调用os.StartProcess函数,从而启动子进程
    	StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error)
    
    1. 平滑关闭当前进程
    2. 子进程在当前进程退出后,会被init进程领养,并继续提供服务

2.2 调用平滑重启函数

在Linux下,我们通常使用kill -USR2 [pid]来发送信号,调用平滑重启函数。

当然通过API服务,在新协程调用该函数,同样可行。

3 热编译

热编译是使用第三方工具来自动编译、运行服务的一种方式。一定程度上类似于平滑重启,比如windows下只能使用该方式模拟平滑重启,达到接近无停服的效果。

3.1 热编译的步骤

使用第三方工具的执行热编译的步骤:

  1. 编译目标项目
  2. 启动编译好的可执行文件
  3. 接收热编译信号
  4. 平滑关闭当前运行的服务进行
  5. 重复步骤1-4

转载于:https://my.oschina.net/henrylee2cn/blog/869059

你可能感兴趣的:(Golang 平滑关闭/重启与热编译技术)