你好!我最近开始运行更多的服务器( nginx 操场, dns 混乱, dns 查找),所以我一直在考虑监控。
最初我并不完全清楚如何监控这些网站,所以我想快速写下我是如何做到的。
我根本不会谈论如何监控 Big Serious Mission Critical 网站,只会谈论不重要的小型网站。
目标:在运营上花费大约 0 时间
我希望这些站点大部分都可以正常工作,但我也希望将大约 0% 的时间花在正在进行的操作上。
最初我对运行服务器非常谨慎,因为在我上一份工作中,我需要为一些关键服务进行24 ⁄ 7轮班值班轮换,在我看来,“负责服务器”意味着“凌晨 2 点起床修理服务器”和“有很多复杂的仪表板”。
所以有一段时间我只制作静态网站,这样我就不必考虑服务器了。
但最终我意识到我要编写的任何服务器都将是非常低的风险,如果它们偶尔停机 2 小时也没什么大不了的,我可以设置一些非常简单的监控来帮助它们保持运行。
没有监控很糟糕
起初我根本没有为我的服务器设置任何监控。这产生了极其可预测的结果——有时网站崩溃了,直到有人告诉我才发现!
第 1 步:正常运行时间检查器
第一步是设置正常运行时间检查器。那里有很多这样的,我现在使用的是updown.io和uptime robot 。我更喜欢 updown 的用户界面,但 uptime 机器人有更慷慨的免费层。
这些
- 检查网站是否已启动
- 如果它出现故障,它会通过电子邮件发送给我
我发现电子邮件通知对我来说是一个很好的水平,如果网站出现故障,我会很快发现但它不会唤醒我或任何事情。
第 2 步:端到端的健康检查
接下来,让我们谈谈“检查站点是否已启动”的实际含义。
起初,我只是将我的一个运行状况检查端点设置为一个无论如何都返回200 OK
的函数。
这很有用——它告诉我服务器已打开!
但不出所料,我遇到了问题,因为它没有检查 API 是否真的在工作——有时即使服务的其余部分实际上已经进入了糟糕的状态,健康检查也会成功。
所以我更新了它以实际发出一个真正的 API 请求并确保它成功。
我所有的服务都做很少的事情(nginx 游乐场只有 1 个端点),所以很容易设置一个运行状况检查,它实际上运行了服务应该执行的大多数操作。
这是 nginx 操场的端到端健康检查处理程序的样子。这是非常基本的:它只是发出另一个 POST 请求(对自己)并检查该请求是成功还是失败。
func healthHandler(w http.ResponseWriter, r *http.Request) { // make a request to localhost:8080 with `healthcheckJSON` as the body // if it works, return 200 // if it doesn't, return 500 client := http.Client{} resp, err := client.Post("http://localhost:8080/", "application/json", strings.NewReader(healthcheckJSON)) if err != nil { log.Println(err) w.WriteHeader(http.StatusInternalServerError) return } if resp.StatusCode != http.StatusOK { log.Println(resp.StatusCode) w.WriteHeader(http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) }
健康检查频率:每小时
现在我的大部分健康检查都是每小时进行一次,有些是每 30 分钟一次。
我每小时运行一次,因为 updown.io 的定价是每个健康检查,我正在监控 18 个不同的 URL,并且我希望将我的健康检查预算保持在每年 5 美元的最低限度。
花一个小时来发现其中一个网站出现故障对我来说似乎没问题——如果有问题,我无法保证无论如何我都会很快修复它。
如果可以更频繁地运行它们,我可能会每隔 5-10 分钟运行一次。
第三步:如果健康检查失败,自动重启
我的一些网站在 fly.io 上,fly 有一个非常标准的功能,我可以为服务配置 HTTP 健康检查,并在健康检查开始失败时重新启动服务。
“重新启动”是一个非常有用的策略来弥补我还没有解决的错误 – 有一段时间 nginx 游乐场有一个进程泄漏,其中nginx
进程没有被终止,所以服务器一直用完内存。
通过运行状况检查,结果是每天左右都会发生这种情况:
- 服务器内存不足
- 健康检查开始失败
- 它重新启动
- 一切都好起来了
- 几个小时后再次重复整个传奇
最终,我开始实际修复进程泄漏,但很高兴有一个解决方法可以在我拖延修复错误时保持运行。
这些用于决定是否重新启动服务的运行状况检查更频繁地运行:每 5 分钟左右。
这不是监控大服务的最佳方式
这可能很明显,我在一开始就已经说过了,但是“编写一个 HTTP 健康检查”并不是监控大型复杂服务的最佳方法。但我不会深入讨论,因为这不是这篇文章的主题。
到目前为止,它运行良好!
我最初在 3 个月前的四月写了这篇文章,但我一直等到现在才发布它以确保整个设置正常工作。
这带来了很大的不同——在我遇到一些非常愚蠢的停机问题之前,现在在过去的几个月里,网站的运行时间达到了 99.95%!
原文: https://jvns.ca/blog/2022/07/09/monitoring-small-web-services/