有用过 Linux 的同学应该对 Systemd 都不会太陌生,所以,在这篇文章中,我将着重于介绍我的 Go 应用程序,而忽略介绍 systemd 了。先来说一下缘由吧,为什么要用 systemd 来集成 Go 应用程序,不集成不行么?

讲道理,也可以,例如在 python 中我喜欢用 supervisor 来管理进程,因为 Supervisor 对 Python 的支持很好,甚至于自身就是用 Python 开发的。通过 Supervisor 我可以方便的指定日志位置,日志大小和划分,还可以让自己的代码与 Supervisor 友好得交互等等。在 Go 语言中,我想尝试一些不一样的,所以,就探索一些如何更好得让 Go 语言和 Systemd 进行配合,当然,我期待的最终效果不想比 Supervisor 差,所以本文就对我的整个尝试过程进行一个小结。

一个 404 的 Web 服务器

为了先来一个简单的入手程序,这里先用 Go 语言写一个简单的 404 服务器,这个 Web 服务器不处理任何请求,所以对于浏览器的任何请求都是响应 404,先上代码:

然后简单得编译一下:go build -o webserver 404.go,编译完应该是一个二进制文件在你的当前目录了,名字叫做:webserver,这时我们就可以为它写一个 Systemd 配置文件了:

位置放在:/usr/lib/systemd/system/webserver.service 内容可以抄一下下面的:

编辑完之后,我们让 Systemd 重新加载一下配置:

$ system daemon-reload
$ systemctl status webserver
➜  demo service webserver status
Redirecting to /bin/systemctl status webserver.service
● webserver.service - 404 web server
   Loaded: loaded (/usr/lib/systemd/system/webserver.service; disabled; vendor preset: disabled)
   Active: inactive (dead)

可以看到 Systemd 已经接管了程序,但是却还没有起来,我们试一下 start:

$ systemctl start webserver
Job for webserver.service failed because a timeout was exceeded. See "systemctl status webserver.service" and "journalctl -xe" for details.

然后我们就会发现情况似乎不对劲了。

和 Systemd 配合

我们调整一下代码,着重看我们的第 17 行:

然后再编译运行看看:

$ go build -o webserver 404.go
$ systemctl restart webserver
$ systemctl status webserver

这时我们看到的东西又不一样了:

这里 Systemd 已经和我们沟通好了,状态也已经变成 active 了。其实这里做了一件事情就是在程序准备进入守护态 的时候通知了一些 systemd,然后 systemd 就知道了。

Watch Dog

另外一件有意思的事情就是自动重启了,为了说明效果,我们再改动一下代码:

重点是我这里修改了一下 Line 18,这里是模拟一下代码出错了,然后宕机了,此时我们再重启一下服务看看:

$ systemctl restart webserver

看到这里我们可以理解,这是预料中发生的情况,那如果我们希望在自己的代码中如果发生出错能够自动重启的话可以怎么做呢?不妨加个 WatchDog 看看:

这里 Line 16-28 我加了个状态监听,用于判断 Web 服务器是否正常,正常的时候上报一下状态;同时在 Line 31 我设置了一个陷阱,如果调用的是 “/panic” api,然后这个 Web 服务器就会因为 log.Fatal 宕机,我们可以期待一下是否会被自动拉起。

小结

看到这里的同学可能会吐槽了,说好得期望不比 Supervisor 差呢?这么强大的 Systemd 就被你这么粗浅得玩一下?好吧,确实因为个人偷懒了,所以就写了这么两个小 Demo,不过后续我有时间的这个坑肯定会填回去的,请多关注。