iT邦幫忙

2022 iThome 鐵人賽

DAY 30
0
Modern Web

Fastify 101系列 第 30

[Fastify] Day30 - Graceful Shutdown

  • 分享至 

  • xImage
  •  

大家好,我是 Yubin

在 Cloud Native 的世界,應用程式多數以 Container 的形式存在,輕量且啟動快速,但也可能常常會壞掉然後被重啟。
我們要如何在程式接收到結束的訊號的時候,可以優雅的關閉?

Graceful Shutdown

什麼是 Graceful Shutdown?

想像一個情境,你在打電動打到一半,突然你媽叫你關機不要再打了。
你會直接把電源切掉?還是先存檔再關掉?

如果你會先存檔再關機,那你就執行了 Graceful Shutdown。

可以參考:Graceful Shutdown and Hard Shutdown

Graceful Shutdown 並不是 Container 才需要注意的,任何程式的設計上都要考慮到如何正確的執行收尾的動作。

如果想要一個程式關閉,可以觸發程式設定好的結束方法,讓應用程式自己執行結束的動作。
也可以透過 OS 或其他方式指令工具對那個程式送出結束的訊號給應用程式。

注意,這邊是送出結束的訊號,並不是不管三七二十一就把那個程式的執行序刪掉。


在 Container 的世界,每個 Container 都很容易被關閉被重啟。
如果被關閉的時候沒有正確的釋放資源,那累積起來勢必會造成嚴重問題 (Connection 用完或 Memory Leak 等)。

那麼要如何實作?

實作的方式很簡單,只要去聽那些代表結束的訊號,聽到的時候不要馬上關閉,先停止接收新的 Request,並執行一系列的釋放資源或寫 log 或其他相應的動作就可以了。

@godaddy/terminus

更簡單的實作方式:透過 @godaddy/terminus

terminus 是 Godaddy 維護的 Graceful Shutdown 函式庫,可以幫我們偵測結束訊號,我們只需要定義收到事件後要做的工作。

透過 npm 進行安裝:

npm i @godaddy/terminus

在程式中,使用 createTerminus 來啟動,並帶入要做的動作設定。

import fastify, { FastifyInstance } from 'fastify'
import { createTerminus } from '@godaddy/terminus'

function onSignal() {
  console.log('server is starting cleanup')
  return Promise.all([
    // your clean logic, like closing database connections
  ])
}

async function onShutdown() {
  console.log('cleanup finished, server is shutting down')
}

const server: FastifyInstance = fastify()

createTerminus(server.server, {
    onShutdown,
    onSignal
})

createTerminus() 第一個參數是 NodeJS 的 Http Server,我們用的是 FastifyInstance,所以透過 .server 拿到 FastifyInstance 中的 RawServerDefault

接收到結束訊號後,會執行 onSignal(),可以定義清除資源的動作在這邊。

onSignal() 執行完會接著執行 onShutdown(),才會把 server 進行關閉。

上述程式執行起來後,可以利用 kill 指令把程式的 process 關閉,來觀察 App 收到結束訊號的反應。

會輸出以下文字:

server is starting cleanup
cleanup finished, server is shutting down
Terminated

注意使用 kill 指令不要加上 -9 的參數。
更多 terminus 的功能及使用可以參考官方 GitHub


本篇文章介紹了什麼是 Graceful Shutdown,以及用 terminus 這個非常熱門的套件來實作。

在 Fastify 生態系中也有人開發了 fastify-graceful-shutdown 這樣的 Plugin,只是 terminus 的功能相對完善,且彈性更高。

以上完整範例可以參考 GitHub: Fastify101


最後一篇剛好寫個 Graceful Shutdown,我也要 Shutdown 了。

感謝大家收看。


上一篇
[Fastify] Day29 - Deployment
系列文
Fastify 10130
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

1
Brandy
iT邦新手 2 級 ‧ 2022-10-15 10:07:22

恭喜完賽

1
HAO
iT邦研究生 2 級 ‧ 2022-10-15 10:15:09

恭喜完賽!

我要留言

立即登入留言