最近在看 Prometheus 的源代码,发现它自带了优雅的关闭方式,这和我以前博文讲到的热更新十分相似。
如何优雅关闭
使用 kill 命令
因为 Prometheus 是一个 Unix 二进制程序,我们可以向 Prometheus 进程发送 SIGTERM
关闭信号。
使用
pgrep-f prometheus
找到运行的 Prometheus 进程号使用
kill-TERM1234
来关闭
PS: 这里 1234
指进程号。
使用 HTTP 接口
Prometheus 提供了 HTTP 关闭接口,但在使用之前,需要通过 --web.enable-lifecycle
参数开启 lifecycle
功能,然后你就可以使用 HTTP 请求来关闭程序了,例如:
curl -X POST http://localhost:9090/-/quit
此时 HTTP 接口会返回:
Requesting termination... Goodbye!
优雅关闭做了什么
当我们使用以上两种方法来关闭 Prometheus 的时候,在它的 log 中可以看到如下信息:
level=warn ts=2018-06-26T03:37:35.209100753Z caller=main.go:381 msg="Received termination request via web service, exiting gracefully..."
level=info ts=2018-06-26T03:37:35.212894277Z caller=main.go:402 msg="Stopping scrape discovery manager..."
level=info ts=2018-06-26T03:37:35.212937719Z caller=main.go:416 msg="Stopping notify discovery manager..."
level=info ts=2018-06-26T03:37:35.212963663Z caller=main.go:438 msg="Stopping scrape manager..."
level=info ts=2018-06-26T03:37:35.212975269Z caller=main.go:398 msg="Scrape discovery manager stopped"
level=info ts=2018-06-26T03:37:35.213029699Z caller=main.go:412 msg="Notify discovery manager stopped"
level=info ts=2018-06-26T03:37:35.21332349Z caller=main.go:432 msg="Scrape manager stopped"
level=info ts=2018-06-26T03:37:35.237387659Z caller=manager.go:464 component="rule manager" msg="Stopping rule manager..."
level=info ts=2018-06-26T03:37:35.238240277Z caller=manager.go:470 component="rule manager" msg="Rule manager stopped"
level=info ts=2018-06-26T03:37:35.238625599Z caller=notifier.go:512 component=notifier msg="Stopping notification manager..."
level=info ts=2018-06-26T03:37:35.238693489Z caller=main.go:588 msg="Notifier manager stopped"
level=info ts=2018-06-26T03:37:35.238723167Z caller=main.go:599 msg="See you next time!"
可以发现在程序终止之前它依次关闭了如下服务:
scrape discovery manager
notify discovery manager
scrape manager
rule manager
notification manager
fanoutStorage
优雅关闭的好处
虽然优雅关闭 Prometheus 耗时较长,但这个等待是值得的。
因为它在关闭的同时做了很多依赖服务的清理工作,其中最主要的就是 fanoutStorage
,如果它没有正常关闭,很有可能破坏 TSDB 正在落盘的数据,从而导致一些莫名的 bug,以至于再也无法启动 Prometheus 了。
突然想到一点,通常我们会使用 supervisord
来管理 Prometheus,那 supervisord
默认的 stop 命令发送的是什么进程关闭信号呢?
查看了文档,确认 supervisord 的 stopsignal
默认配置为 TERM
,恰好满足 Prometheus 的优雅关闭方式,从而避免了对其进行额外的配置操作。
如果你对内容感兴趣,欢迎扫码关注我们 Prometheus 实战知识星球:





