基于 systemd 创建 Linux service 启动顺序和检测故障重启

摘要:
后台团队设计了一个基于Armian的LoRa网关,该网关要求主程序包在转发器通电后运行然而,Armian通电并启动后,请使用systemctlstatusprime_gateway.service视图发现服务已停止工作:rime_gateway.serverRimeLoRaWANGatewayLoadedActive:failedsinMon2020-04-2006:51:46UTC;29sagoProcess:11112ExecStart=/home/prome/packet_transferor/lora_pkt_fwd/start_gateway.shMainPID:11112Apr2006:51:46orangepizerosystemd[1]:rime_gateway.service:ServiceRestartSec=100mspired,schedulerestart。2006年4月:1:46oragepizerossystemd[1]:lime_gateway-service:Scheduledrestartjob,restartcountrisat5.Apr2006:51:46orangepizerosystemd[1]:已停止TimeLoRaWANGateway。Apr2006:41:46oragepizerossystemd[1]:rime_gateway.service:开始请求重复对话。Apr206:51:46Orangepizeros systemd[1]:rime_gateway。服务:失败,结果为“退出代码”。2006年4月:11:46 orangepizerosystemd[1]:无法启动RimeLoRaWAN网关。上述语句表明服务重新启动过快,系统退出并重新启动。使用journalctl-urime_Gateway.service检查日志,系统每100ms重启五次失败。
背景

团队基于 Armbian 设计了一个 LoRa 网关,它要求上电后开始运行主程序 packet_forwarder (它实现 LoRa<-(转)->UDP 与服务器通信)。
这本来是一个简单的需求,将其设计成一个 service 加载到 systemd 中就可以完成,该 rime_gateway.service 代码如下:

[Unit]
Description=Rime LoRaWAN Gateway

[Service]
WorkingDirectory=/home/rime/packet_forwarder/lora_pkt_fwd
ExecStart=/home/rime/packet_forwarder/lora_pkt_fwd/start_gateway.sh
Restart=always

[Install]
WantedBy=multi-user.target

语法解释请参考 Systemd 入门教程:命令篇

不稳定的服务

当使用 systemctl start rime_gateway.service 手动启动时,它工作得很好。

然而,当 Armbian 上电自启动后,使用 systemctl status rime_gateway.service 查看发现该服务已经停止工作:

rime_gateway.service - Rime LoRaWAN Gateway
   Loaded: loaded (/lib/systemd/system/rime_gateway.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Mon 2020-04-20 06:51:46 UTC; 29s ago
  Process: 1112 ExecStart=/home/rime/packet_forwarder/lora_pkt_fwd/start_gateway.sh (code=exited, status=1/FAILURE)
 Main PID: 1112 (code=exited, status=1/FAILURE)

Apr 20 06:51:46 orangepizero systemd[1]: rime_gateway.service: Service RestartSec=100ms expired, scheduling restart.
Apr 20 06:51:46 orangepizero systemd[1]: rime_gateway.service: Scheduled restart job, restart counter is at 5.
Apr 20 06:51:46 orangepizero systemd[1]: Stopped Rime LoRaWAN Gateway.
Apr 20 06:51:46 orangepizero systemd[1]: rime_gateway.service: Start request repeated too quickly.
Apr 20 06:51:46 orangepizero systemd[1]: rime_gateway.service: Failed with result 'exit-code'.
Apr 20 06:51:46 orangepizero systemd[1]: Failed to start Rime LoRaWAN Gateway.

上面的语句显示服务重启太快,系统退出重启。

使用 journalctl -u rime_gateway.service 查看日志,系统以 100ms 间隔 5 次重启都失败。

-- Logs begin at Mon 2020-04-20 06:51:31 UTC, end at Mon 2020-04-20 06:55:01 UTC. --
Apr 20 06:51:40 orangepizero systemd[1]: Started Rime LoRaWAN Gateway.
Apr 20 06:51:40 orangepizero start_gateway.sh[572]: Reset start_gateway.sh
Apr 20 06:51:41 orangepizero start_gateway.sh[572]: Starting start_gateway.sh
Apr 20 06:51:41 orangepizero systemd[1]: rime_gateway.service: Main process exited, code=exited, status=1/FAILURE
Apr 20 06:51:41 orangepizero systemd[1]: rime_gateway.service: Failed with result 'exit-code'.
Apr 20 06:51:41 orangepizero systemd[1]: rime_gateway.service: Service RestartSec=100ms expired, scheduling restart.
Apr 20 06:51:41 orangepizero systemd[1]: rime_gateway.service: Scheduled restart job, restart counter is at 1.

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

Apr 20 06:51:45 orangepizero start_gateway.sh[1112]: Reset start_gateway.sh
Apr 20 06:51:46 orangepizero start_gateway.sh[1112]: Starting start_gateway.sh
Apr 20 06:51:46 orangepizero systemd[1]: rime_gateway.service: Main process exited, code=exited, status=1/FAILURE
Apr 20 06:51:46 orangepizero systemd[1]: rime_gateway.service: Failed with result 'exit-code'.
Apr 20 06:51:46 orangepizero systemd[1]: rime_gateway.service: Service RestartSec=100ms expired, scheduling restart.
Apr 20 06:51:46 orangepizero systemd[1]: rime_gateway.service: Scheduled restart job, restart counter is at 5.
Apr 20 06:51:46 orangepizero systemd[1]: Stopped Rime LoRaWAN Gateway.
Apr 20 06:51:46 orangepizero systemd[1]: rime_gateway.service: Start request repeated too quickly.
Apr 20 06:51:46 orangepizero systemd[1]: rime_gateway.service: Failed with result 'exit-code'.
Apr 20 06:51:46 orangepizero systemd[1]: Failed to start Rime LoRaWAN Gateway.

查看网关日志,发现失败的原因是网络没有建立成功 tail -f /tmp/start_gateway.sh.log

ERROR: [up] connect returned Network is unreachable
修改启动顺序

很明显,该服务依赖于网络的建立,因此,首先添加如下语句

After=network.target

这个启动顺序生效了吗?为此,我们导出并查看了启动顺序

systemd-analyze plot > boot.svg

使用 chrome 浏览器打开 boot.svg 发现:先启动 network.target,后启动 rime_gateway.service

基于 systemd 创建 Linux service 启动顺序和检测故障重启第1张

更多启动顺序请参考 Linux systemd启动守护进程,service启动顺序分析及调整service启动顺序

检测故障重启

为了让服务更健壮,检测到失败退出时自动重启。为此,添加了如下的代码。

systemd 将尝试永久重启服务

StartLimitIntervalSec=0

每隔 1 秒重启服务是个好主意,以避免在出现问题时对服务器施加太大压力。

RestartSec=1

更多自动重启请参考 使用systemd创建Linux服务

稳定的服务

最终的 rime_gateway.service 代码如下所示

[Unit]
Description=Rime LoRaWAN Gateway
After=network.target
StartLimitIntervalSec=0

[Service]
WorkingDirectory=/home/rime/packet_forwarder/lora_pkt_fwd
ExecStart=/home/rime/packet_forwarder/lora_pkt_fwd/start_gateway.sh
Restart=always
RestartSec=1

[Install]
WantedBy=multi-user.target

使用 systemctl status rime_gateway.service 和 journalctl -u rime_gateway.service 查看日志,服务正常启动。

在异常的情况下,先拔出网线,再重启 Armbian,发现 systemd 以每隔 1 秒间隔启动服务,直到网络恢复正常为止(本案例重启 78 次)。

-- Logs begin at Mon 2020-04-20 07:32:09 UTC, end at Mon 2020-04-20 07:35:12 UTC. --
Apr 20 07:32:19 orangepizero systemd[1]: Started Rime LoRaWAN Gateway.
Apr 20 07:32:20 orangepizero start_gateway.sh[839]: Reset start_gateway.sh
Apr 20 07:32:20 orangepizero start_gateway.sh[839]: Starting start_gateway.sh
Apr 20 07:32:20 orangepizero systemd[1]: rime_gateway.service: Main process exited, code=exited, status=1/FAILURE
Apr 20 07:32:20 orangepizero systemd[1]: rime_gateway.service: Failed with result 'exit-code'.
Apr 20 07:32:21 orangepizero systemd[1]: rime_gateway.service: Service RestartSec=1s expired, scheduling restart.
Apr 20 07:32:21 orangepizero systemd[1]: rime_gateway.service: Scheduled restart job, restart counter is at 1.
Apr 20 07:32:21 orangepizero systemd[1]: Stopped Rime LoRaWAN Gateway.
Apr 20 07:32:21 orangepizero systemd[1]: Started Rime LoRaWAN Gateway.
Apr 20 07:32:22 orangepizero start_gateway.sh[991]: Reset start_gateway.sh
Apr 20 07:32:22 orangepizero start_gateway.sh[991]: Starting start_gateway.sh

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

Apr 20 07:34:54 orangepizero systemd[1]: rime_gateway.service: Main process exited, code=exited, status=1/FAILURE
Apr 20 07:34:54 orangepizero systemd[1]: rime_gateway.service: Failed with result 'exit-code'.
Apr 20 07:34:55 orangepizero systemd[1]: rime_gateway.service: Service RestartSec=1s expired, scheduling restart.
Apr 20 07:34:55 orangepizero systemd[1]: rime_gateway.service: Scheduled restart job, restart counter is at 78.
Apr 20 07:34:55 orangepizero systemd[1]: Stopped Rime LoRaWAN Gateway.
Apr 20 07:34:55 orangepizero systemd[1]: Started Rime LoRaWAN Gateway.
Apr 20 07:34:55 orangepizero start_gateway.sh[2644]: Reset start_gateway.sh
Apr 20 07:34:56 orangepizero start_gateway.sh[2644]: Starting start_gateway.sh

免责声明:文章转载自《基于 systemd 创建 Linux service 启动顺序和检测故障重启》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇AMDLoader数据模块加载器oracle用户创建及权限设置(转)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

linux 查看系统资源使用信息的一些命令集合

linux上的进程查看及管理工具: pstree,ps,pidof,pgrep,top,htop,glances,pmap,vmstat,dstat,kill,pkill,job,bg,fg,nohup,nice,renice,killall。。。 linux开机时,会启动第一个进程,由这个进程去启动别的进程,这个第一个进程在centos5,6,7上实现的...

docker.service启动失败:Unit not found的原因及解决办法

原因1:docker.socket 最初在启动docker时遇到问题,是因为docker.socket引起的,虽然记不清问题是表现为Unit not found还是执行systemctl start docker.service命令时hang住了,但是也一并记录在这里。 问题描述 我是从Docker 1.10.3升级到1.13.1版本,通过rpm包安装的。...

cetos7 systemd 详解

  CentOS7/RHEL7 systemd详解 目录1. 为什么是systemd(1) 关于Linux服务管理(2) SysV init的优缺点(3) UpStart的改进(4) systemd的诞生(5)为什么systemd能做到启动很快2. SysV init介绍(1) 什么是SystemV(2)SysV init的运行级别(3)SysV in...

Kubernetes2-K8s的集群部署

一、简介   1、架构参考               Kubernetes1-K8s的简单介绍    2、实例架构     192.168.216.51 master  etcd     192.168.216.53 node1     192.168.216.54 node1   3、拓扑   4、软件版本 [root@master ~]# cat...

systemd启动过程(转)

理解Linux启动过程 在我们打开Linux电脑的电源后第一个启动的进程就是init。分配给init进程的PID是1。它是系统其他所有进程的父进程。当一台Linux电脑启动后,处理器会先在系统存储中查找BIOS,之后BIOS会检测系统资源然后找到第一个引导设备,通常为硬盘,然后会查找硬盘的主引导记录(MBR),然后加载到内存中并把控制权交给它,以后的启动过...

Centos7下service配置知识

一、开机启动 对于那些支持 Systemd 的软件,安装的时候,会自动在/usr/lib/systemd/system目录添加一个配置文件。 如果你想让该软件开机启动,就执行下面的命令(以httpd.service为例)。 $ sudo systemctl enable httpd 上面的命令相当于在/etc/systemd/system目录添加一个符号链...