antony@notes:~/kubernetes$ cat "實作-K8s-網站應用-Graceful-shutdown.md"
實作 K8s 網站應用 Graceful shutdown
實作 K8s 網站應用 Graceful shutdown
[TOC]
1. 前情提要
可以試想現在有一台電腦直接被按下關機鍵,上面的程式會無法正確跑完、使用者也無法正確的完成執行到一半的動作。
而關掉 HTTP Server 也是同理,處理到一半的 HTTP 請求會直接失敗,處理不好的話會讓使用者有不好的體驗或是甚至在資料庫留下處理一半的資料。
那該如何優雅地關閉服務?
2. 先備知識
2.1. 什麼是 Graceful Shutdown?
優雅的關閉就是要確保網站服務在完成現有操作的同時安全終止,而不是突然停止並可能導致任務未完成。
在任何應用程式中,所謂「優雅關閉」(Graceful Shutdown)通常要滿足三個基本條件:
- 關閉進入口:先停止接收新的請求或訊息來源,例如來自 HTTP、訊息佇列(pub/sub)等;但對於連到資料庫或快取系統的「對外連線」,可以先保持不關閉。
- 等待目前正在處理的請求完成:讓已經在處理中的請求有機會執行完;如果某些請求拖太久,也要回應一個適當的錯誤訊息(讓使用者知道中斷原因)。
- 釋放重要資源:像是釋放資料庫連線、解除檔案鎖定、關閉網路監聽器等。這個階段也會做一些最後的清理工作,避免資源洩漏或程式異常退出。
- 釋放的意思是把原本占用的資源歸還給系統,讓其他程式可以使用。
- 「Database connections(資料庫連線)」是應用程式和資料庫之間的一條持續通訊通道,讓你的程式可以讀寫資料庫裡的資料(像是查詢、寫入、更新等)。
- 「File lock(檔案鎖)」是一種防止多個程式同時存取同一個檔案而導致資料錯亂或損壞的機制。
- 「Network listeners(網路監聽器)」是指應用程式中負責等待外部連線請求的元件。簡單來說,它就像一個「守門員」,在某個 IP 和 Port 上「聽」有沒有人要來連線。
2.2. Kubernetes 如何終止 Pod?
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination
2.3. 認識 Kubernetes 的 Container Lifecycle Hooks:PreStop
https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/
3. 開始動手實作
3.1. 使用 Go 語言實作支援 Graceful Shutdown 的 HTTP 伺服器
3.2. 將應用程式 Container 化(Containerize the App)
3.3. 設定 K8s Pod 啟用 PreStop hook
參考文章 :
- https://chentsulin.medium.com/graceful-shutdown-%E7%9B%A1-server-%E6%9C%80%E5%BE%8C%E7%9A%84%E7%BE%A9%E5%8B%99-%E4%BB%A5-node-js-%E8%88%87-kubernetes-%E7%82%BA%E4%BE%8B-cb7f519389ea
- https://dev.to/yanev/a-deep-dive-into-graceful-shutdown-in-go-484a
- https://victoriametrics.com/blog/go-graceful-shutdown/