k8s-graceful-shutdown:该库提供了使用 Kubernetes 实现 Graceful Shutdown(优雅退出) Node.js App 的资源。

问题描述

在 kubernetes 中运行微服务时。我们需要处理 kubernetes 发出的终止信号。这样做的正确方法是:

  1. 监听 SIGINT, SIGTERM
  2. 收到信号后,将服务置于不健康模式(/health 路由应返回状态码 4xx5xx
  3. 在关闭之前添加宽限期,以允许 kubernetes 将您的应用程序从负载均衡器中移除
  4. 关闭服务器和所有打开的连接
  5. 关闭

该库使上述过程变得容易。只需注册您的 graceful shutdown hook(优雅退出的钩子)并添加宽限期即可。

请注意,您的宽限期必须小于 kubernetes 中定义的宽限期!

使用 Express 框架的示例

例如,使用Express框架:

import { Response, Request } from 'express'
import express from 'express'
import { addGracefulShutdownHook, getHealthHandler, shutdown } from '@neurocode.io/k8s-graceful-shutdown' const app = express()
app.disable('x-powered-by')
const port = process.env.PORT || 3000
const server = app.listen(port, () => console.log(`App is running on http://localhost:${port}`)) // 修补 NodeJS 服务器关闭功能,使其具有正确的关闭功能,因为您可能期望为您关闭 keep-alive connections(保持活动的连接)!
// 在这里阅读更多信息 https://github.com/nodejs/node/issues/2642
server.close = shutdown(server) const healthy = (req: Request, res: Response) => {
res.send('everything is great')
} const notHealthy = (req: Request, res: Response) => {
res.status(503).send('oh no, something bad happened!')
} const healthTest = async () => {
// 这是可选的
// 你可以用它来进行健康检查
return true
} const healthCheck = getHealthHandler({ healthy, notHealthy, test: healthTest })
app.get('/health', healthCheck) const sleep = (time: number) => new Promise((resolve) => setTimeout(resolve, time)) const asyncOperation = async () => sleep(3000).then(() => console.log('Async op done')) const closeServers = async () => {
await asyncOperation() // 可以是任何异步操作,例如 mongo db 关闭,或发送 slack 消息;)
server.close()
} const gracePeriodSec = 5*1000
addGracefulShutdownHook(gracePeriodSec, closeServers) server.addListener('close', () => console.log('shutdown after graceful period'))
  • 上面所示的这个简单的应用程序,添加了一个5秒的优雅关闭周期,在此之后,钩子(在关闭功能的帮助下负责关闭服务器)被触发。在发送 SIGINTSIGTERM 信号时,用户可以看到5秒的宽限期,之后发生了3秒的等待异步操作,然后才会显示 “shutdown after graceful period” 的消息,表示关闭服务器。

  • 该应用程序还展示了 “getHealthHandler” 的功能。在请求 localhost:3000/health 时,healthTest 将返回 true,并显示 'everything is great' 消息,表明 health 检查为正常。用户可以将 healthTest 改为返回 false,然后看到消息变为 'oh no, something bad happened!' 这表明了一种不健康的状态。

如果您使用 Koa 框架,请查看 demos/ 文件夹。 我们有一个 Koa 示例,其功能与上述应用类似。Koa 应用程序使用具有 healthnotHealthy 处理程序的 fn(ctx) 支持的 getHealthContextHandler,而不是将 healthnotHealthy 处理程序作为 fn(req, res)getHealthHandler

它是如何工作的?

正常关闭工作流程的工作方式示例:

  1. KubernetesPod 发送 SIGTERM 信号。手动缩小 Pod 或在滚动部署期间自动缩小 Pod 时会发生这种情况
  2. 该库接收 SIGTERM 信号并调用您的 notHealthy 处理程序。您的处理程序应返回 400500http 状态代码(抛出错误?),这表明该 pod 不再接收任何流量。注意此步骤是可选的(请检查下一步)
  3. 库等待指定的 grace time 以启动应用程序的关闭。宽限时间应在 520 秒之间。 kubernetes 端点控制器需要宽限时间才能从有效端点列表中删除 Pod,进而从服务中删除 Pod(从 iptables 所有节点中获取 podip 地址)。
  4. KubernetesService 中删除 Pod
  5. 该库调用您所有已注册的关闭 hook
  6. 在配置的宽限期之后,应用程序将使用我们的关机机制正确地关机,你可能期望默认工作,但在 NodeJS http server, expressKoa 不是

互相交流学习

我的微信:

Node.js & Kubernetes Graceful Shutdown的更多相关文章

  1. Node.js 集群

    稳定性: 2 - 不稳定 单个 Node 实例运行在一个线程中.为了更好的利用多核系统的能力,可以启动 Node 集群来处理负载. 在集群模块里很容易就能创建一个共享所有服务器接口的进程. var c ...

  2. Node.js使用PM2的集群将变得更加容易

    介绍 众所周知,Node.js运行在Chrome的JavaScript运行时平台上,我们把该平台优雅地称之为V8引擎.不论是V8引擎,还是之后的Node.js,都是以单线程的方式运行的,因此,在多核心 ...

  3. 使用PM2将Node.js的集群变得更加容易

    介绍 众所周知,Node.js运行在Chrome的JavaScript运行时平台上,我们把该平台优雅地称之为V8引擎.不论是V8引擎,还是之后的Node.js,都是以单线程的方式运行的,因此,在多核心 ...

  4. node.js使用汇总贴

    金天:学习一个新东西,就要持有拥抱的心态,如果固守在自己先前的概念体系,就会有举步维艰的感觉..NET程序员初用node.js最需要适应的就是异步开发,以及弱类型语言难以避免的拼写错误与弱小的语法提示 ...

  5. 微软开放技术发布针对 Mac 和 Linux 的更新版 Azure Node.JS SDK 和命令行工具

    发布于 2013-12-04 作者 Eduard Koller 这次为我们使用Linux 的朋友带来了更多关于部署云上虚拟机的消息.今天,微软开放技术有限公司 (MS Open Tech),想与大家分 ...

  6. 当Node.js遇见Docker

    Node.js Best Practices - How to Become a Better Developer in 2017提到的几点,我们Fundebug深有同感: 使用ES6 使用Promi ...

  7. node.js后台快速搭建在阿里云(二)(pm2和nginx篇)

    前期准备 阿里云服务器 node.js pm2 express nginx linux(推荐教程:鸟哥的私房菜) 简介 嗯……我只是个前端而已 在第一部分说完了express篇. 后面继续项目的部署, ...

  8. 树莓派.使用Node.js控制GPIO

    树莓派上的40个GPIO是最好玩的东西 它们可以被C,/C++, Python, Java等语言直接控制 现在就来看看怎么用Node.js做到同样的事情 在试验之前, 请先安装好Node.js, 具体 ...

  9. node.js cluster模式启用方式

    众所周知,Node.js运行在Chrome的JavaScript运行时平台上,我们把该平台优雅地称之为V8引擎.不论是V8引擎,还是之后的Node.js,都是以单线程的方式运行的,因此,在多核心处理器 ...

随机推荐

  1. springMVC-6-restful_CRUD

    1.大体框架 POJO层代码 Employee @Data public class Employee { private Integer id; private String lastName; p ...

  2. C# CheckedListBox控件的用法总结

    1. 添加项目 checkedListBox1.Items.Add("一级"); checkedListBox1.Items.Add("二级"); checke ...

  3. python的模拟算法--打印任务

    模拟算法:打印任务 Queue来实现 队列(queue)是一种有次序的数据集合,其特征是新数据项的添加总发生在一端(通常称为"尾rear"端)而现存数据项的移除总发生在另一端(通常 ...

  4. python的web框架知识点

    一个完整的web应用:服务器收到来自浏览器的一个请求,服务器将请求内容的网页返回给浏览器,让浏览器显示出来.[而浏览器与服务器之前的传输协议是HTTP] HTTP是一个基于TCP/IP通信协议来传递数 ...

  5. 实战 | Hive 数据倾斜问题定位排查及解决

    Hive 数据倾斜怎么发现,怎么定位,怎么解决 多数介绍数据倾斜的文章都是以大篇幅的理论为主,并没有给出具体的数据倾斜案例.当工作中遇到了倾斜问题,这些理论很难直接应用,导致我们面对倾斜时还是不知所措 ...

  6. 『go成长之路』 defer 作用、典型用法以及多个defer调用顺序,附加defer避坑点,拿来吧你

    预习内容 defer 的作用有哪些? 多个 defer 的执行顺序是怎样的? defer,return,函数返回值 三者之间的执行顺序 defer的作用 go中的defer是延迟函数,一般是用于释放资 ...

  7. SVG和Canvas的区别?

    什么是SVG? SVG(可缩放矢量图形)编辑可缩放矢量图形是基于可扩展标记语言(标准通用标记语言的子集),用于描述二维矢量图形的一种图形格式.它由万维网联盟制定,是一个开放标准. 什么是 Canvas ...

  8. Docker for windows安装与使用

    1.安装Docker for windows之前,需要将系统的hyper-v功能打开 2.下载Docker for windows进行安装 访问url:https://docs.docker.com/ ...

  9. Spring MVC+javamail实现邮件发送

    Spring MVC+javamail实现邮件发送 开启邮箱的POP3/SMTP服务(这里以QQ邮箱举例) 设置 --> 账户 -- > 开启POP3/STMP服务,然后得到一个授权码. ...

  10. Tomcat进程意外退出的问题分析

    http://ifeve.com/why-kill-2-cannot-stop-tomcat/?tdsourcetag=s_pctim_aiomsg tail后关掉客户端 正常执行shutdown.s ...