今天开会,又TM是一堆PPT。讲什么微服务架构,云原生最佳实践。我呸!最佳实践?连Systemd都没搞明白,玩个屁的云原生!一个个就知道抄概念,真要出了问题,抓瞎!
就说Systemd这玩意,启动管理是方便了不少,但是后面加的那些花里胡哨的功能,简直就是瞎JB优化!尤其是那些什么资源限制,自动重启,网络配置,没一个省心的!稍微配置不对,就给你挖个坑,让你跳进去爬都爬不出来。
就说我前几天遇到的一个破事。有个服务,用Systemd管理,设置了Restart=on-failure。正常情况下,服务挂了自动重启,看起来挺好。结果呢?这SB玩意,服务一挂,它疯狂重启,每次重启都失败,然后疯狂打印日志,直接把磁盘给干满了!你TM倒是给个重启次数限制啊!
最后排查,发现是代码里有个空指针异常,导致服务直接core dump。这TM是代码的问题,没错。但是Systemd你能不能聪明点?你TM要是检测到连续重启失败超过三次,就应该直接停止重启啊!非得把磁盘干满才罢休?
还有那些个什么LimitCPU、LimitMemory,设置起来倒是挺方便,但是你TM知道背后的实现原理吗?这玩意实际上就是cgroups!cgroups!你没听错,就是Linux内核里的cgroups!但是Systemd把这些东西封装的太好了,让你感觉好像很简单,点点鼠标就能搞定。但是一旦出了问题,你想debug,想深入理解,就TM懵逼了!
我当年刚开始玩Linux的时候,哪有这些破玩意!那时候启动脚本都是手写的,一行一行敲出来的。虽然麻烦,但是每一个细节都清清楚楚。现在倒好,年轻人一个个只会用Systemd,出了问题就只会重启重启再重启!
就拿配置来说,Systemd的unit文件,看着挺简洁,但是背后藏着一堆坑。比如这个Type=simple,Type=forking,Type=oneshot,你TM知道这些类型到底有什么区别吗?你TM知道Type=forking的服务,Systemd是怎么判断服务是否启动成功的吗?
告诉你,Type=forking的服务,Systemd会根据PID文件来判断服务是否启动成功。如果服务启动后没有创建PID文件,或者PID文件里的PID不是当前进程的PID,Systemd就会认为服务启动失败,然后就开始TM的重启!
所以,如果你用Type=forking,你的服务启动脚本一定要正确创建PID文件!否则,等着被Systemd坑死吧!
举个例子,下面是一个典型的Type=forking的unit文件:
[Unit]
Description=My Awesome Service
After=network.target
[Service]
Type=forking
PIDFile=/var/run/my-awesome-service.pid
ExecStart=/usr/local/bin/my-awesome-service start
ExecStop=/usr/local/bin/my-awesome-service stop
Restart=on-failure
[Install]
WantedBy=multi-user.target
看到了吗?PIDFile这行至关重要!如果你的/usr/local/bin/my-awesome-service start脚本没有正确创建/var/run/my-awesome-service.pid文件,Systemd就会认为服务启动失败,然后就开始疯狂重启!
还有那些个什么ExecStartPre,ExecStartPost,ExecStopPre,ExecStopPost,看着挺花哨,但是用不好就是给自己挖坑。比如,你可以在ExecStartPre里做一些初始化工作,但是如果ExecStartPre执行失败了,Systemd会直接停止启动服务,但是不会告诉你具体原因!你只能去看日志,一行一行排查,简直TM浪费时间!
所以,我TM说,这些新技术,新工具,用起来是方便,但是一定要理解背后的原理。不要只会用,不会修。否则,等着被这些破玩意坑死吧!
最后,再补充一句,Systemd的日志系统也是个坑。默认情况下,Systemd会将所有日志都写入到二进制日志文件里。你想查看日志,必须用journalctl命令。这TM简直反人类!我只想用tail -f /var/log/mylog.log来看日志不行吗?非得用journalctl,还要记住一堆参数,简直就是折磨!
所以,我一般都会把Systemd的日志配置成同时写入到文本文件里,方便我用传统的工具来查看日志。
修改/etc/systemd/journald.conf文件,设置:
Storage=persistent
SystemMaxFileSize=100M
ForwardToSyslog=yes
然后重启systemd-journald服务:
systemctl restart systemd-journald
这样,Systemd就会将日志同时写入到/var/log/syslog或者/var/log/messages里,方便你用tail、grep等命令来查看日志。
总之,Systemd这玩意,用好了是神器,用不好就是坑。年轻人,多学点底层原理,少抄点概念。否则,等着被这些破玩意坑死吧!