以前我跑应用都是通过 Supervisord 来运行,其实,一直用下来,发现还是很好用的,没啥毛病。随着尝试了一些 Systemd 的功能之后,让我对他们之间的关系有了一些思考,既然这两货对我来说做得事情都差不多,那么究竟差别在哪?所以今天虽然不是很有空,但是我还是决定来闲扯一番。
首先,先来聊聊 Systemd,一开始我以为 Systemd 是一个第三方应用,没有太在意,公司在用这个所以也就愣愣得跟着用了;直到有一天好奇心驱使我认真得去查了一下,不得了啊,居然是钦定的系统管理软件。所谓的钦定系统管理软件的意思就是 systemd 的 PID 是 1,可能你觉得 PID 是 1 没啥了不起,但是,我想告诉你,pid 是 1 的意思就是内核初始化的最后一步就是启动 init 进程,而这个进程的 PID 就是 1,也就是你看到的 systemd。换言之,systemd 是系统运行的第一个进程。
可能玩 Docker 比较多的同学会有一个感触,那就是如果你通过类似于:
$ docker run -d --name test some-images /bin/bash -c "ping baidu.com"
执行 Docker 的时候,ping 命令的 pid 居然是 1,这当然和 Docker 的实现有关,但是,如果你把这个 PID 为 1 的进程 kill 掉,你会发现 Docker 会 Stop 掉这个 Container。OK,这就是我认为 Systemd 比 Supervisord 强的一个地方,那就是 Supervisord 可能会自己挂掉,从而导致管理的其他进程也挂掉,但是 Systemd 就不一样了,如果 Systemd 挂掉了,那就不是应用进程挂掉这么简单了,这说明系统也已经挂掉了,这完全不是一个级别的。
当然,这也不是说 Systemd 就完胜 Supervisord 啦,至少就我个人感受来说,如果不加其他组件的情况下,至少 Systemd 的日志系统是很弱鸡的,对于系统级别的日志我知道的就只有两个地方查看,分别是 systemctl status
和 journalctl -xu
。systemctl
能看到的不多,就最近的十几行记录,如果要想看更多的记录就得靠 journalctl
了;相比之下,Supervisord 至少在这方面的表现还是比较抢眼的,至少 stdout 和 stderr 的输出可以分开打到不同的文件中。
同时我的使用感受还有一个是 Supervisord 比较爽的就是支持分组,例如不同开发小组,每个开发小组都有若干个应用,Supervisord 可以根据小组来重启这个小组的多个应用,只需要将这些应用都配置好在同一个小组中即可,这在我的体验中,Systemd 不能简单做的。
当然,从业界的使用来说,比较多的人是选择 Systemd 的,虽然也有不少人在喷 Systemd,我觉得喷得很有意思,所以就摘抄一些:
- 代码质量不高,每个版本新功能前期 bug 很多,需要迭代几个版本之后才稳定,这对于 init 进程完全不可接受啊
- 频繁变更设计和接口,不考虑向后兼容
- systemd极端地奉行“只考虑Linux”,不接受任何改进非Linux系统兼容性的patch。
好吧,你要这么喷我也很无奈不是。
Final
ok,前面闲聊了这么多,后面就直接了当得给出双方的能力得了:
- Systemd
- 稳定可靠
- 支持 Before/After 依赖机制
- 支持 Notify 机制
- 支持基于 cgroup 的资源限制
- Supervisord
- 支持通过 priority 配置进程启动顺序
- 日志友好方便查阅
- 跨平台使用
- 扩展开发友好