赞
踩
自启动应用程序可以在/etc/rc.local文件中调用脚本来启动应用程序,另外也可以自行编写一个服务来启动应用程序。这两种方法其实都是一种方法即使用服务来启动一个应用程序。rc.local脚本本身也是被一个rc.local的服务来调用的。如下图,可以看出rc-local.servce服务调用/etc/rc.local脚本中的相关程序来启动应用。
- 编写服务配置
- 每一个服务以.service结尾,一般会分为3部分:[Unit]、[Service]和[Install]
- [Unit]:记录unit文件的通用信息。
-
- [Service]:记录Service的信息
-
- [Install]:安装信息。
-
- [Unit]
- 主要是对这个服务的说明,内容, 文档介绍以及对一些依赖服务定义
-
- Description : 服务的简单描述
- Documentation : 服务文档
- Requires:当前 Unit 依赖的其他 Unit,如果它们没有运行,当前 Unit 会启动失败
- Wants:与当前 Unit 需要的其他 Unit,如果它们没有运行,当前 Unit 不会启动失败
- BindsTo与当前 Unit 绑定的其他 Unit,如果它们退出,会导致当前 Unit 停止运行
- Before:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之后启动
- After:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之前启动
- Conflicts:这里指定的 Unit 不能与当前 Unit 同时运行
- Condition…:当前 Unit 运行必须满足的条件,否则不会运行
- Assert…:当前 Unit 运行必须满足的条件,否则会报启动失败
- 如
-
- [Unit]
- Description=Protect ARP list
- Wants=network-online.target
- After=network.target
- 其中network.target代表有网路,network-online.target代表一个连通着的网络。
- [service]
- 服务本体
-
- 在定义完了 Systemd 用来识别服务的单元后,我们来定义服务本体。基本的用法如下:
-
-
- Type:服务的类型,各种类型的区别如下所示
-
- simple:默认,这是最简单的服务类型。意思就是说启动的程序就是主体程序,这个程序要是退出那么一切皆休。
- forking:标准 Unix Daemon 使用的启动方式。启动程序后会调用 fork() 函数,把必要的通信频道都设置好之后父进程退出,留下守护精灵的子进程。(以 fork 方式从父进程创建子进程,创建后父进程会立即退出)
- oneshot:systemd中的Type=oneshot服务描述了这一选项适用于只执行一项任务、随后立即退出的服务。可能需要同时设置 RemainAfterExit=yes 使得 systemd 在服务进程退出之后仍然认为服务处于激活状态。
- dbus:这个程序启动时需要获取一块 DBus 空间,所以需要和 BusName= 一起用。只有它成功获得了 DBus 空间,依赖它的程序才会被启动。
- notify: 这个程序在启动完成后会通过 sd_notify 发送一个通知消息。所以还需要配合 NotifyAccess 来让 Systemd 接收消息,后者有三个级别:none,所有消息都忽略掉; main,只接受我们程序的主进程发过去的消息; all,我们程序的所有进程发过去的消息都算。NotifyAccess 要是不写的话默认是 main。(当前服务启动完毕,会通知Systemd,再继续往下执行)
- ExecStart
- 启动当前服务的命令
-
- ExecStartPre
- 启动当前服务之前执行的命令
-
- ExecStartPost
- 启动当前服务之后执行的命令
-
- ExecReload
- 重启当前服务时执行的命令
-
- ExecStop
- 停止当前服务时执行的命令
-
- ExecStopPost
- 停止当其服务之后执行的命令
-
- RestartSec
- 自动重启当前服务间隔的秒数
-
- Restart
- 定义何种情况 Systemd 会自动重启当前服务,可能的值包括always(总是重启)、on-success、on-failure、on-abnormal、on-abort、on-watchdog
-
- no(默认值):退出后不会重启;
- always:不管是什么退出原因,总是重启;
- on-success:只有正常退出时(退出状态码为0),才会重启;
- on-failure:非正常退出时(退出状态码非0),包括被信号终止和超时,才会重启;
- on-abnormal:只有被信号终止和超时,才会重启;
- on-abort:只有在收到没有捕捉到的信号终止时,才会重启;
- on-watchdog:超时退出,才会重启,如ssh服务设置为on-failure,表示任何意外的失败,就将重启sshd。如果sshd正常停止(比如执行systemctl stop命令),它就不会重启。
- TimeoutSec
- 定义 Systemd 停止当前服务之前等待的秒数
-
- RemainAfterExit
- 值为yes或no,表示进程退出以后,服务仍然保持执行。这样的话,一旦使用systemctl stop命令停止服务,ExecStop指定的命令就会执行
-
- 通常和type=oneshot配合使用
-
- Environment
- 指定环境变量
-
- EnvironmentFile
- 指定当前服务的环境参数文件,该文件的key=value键值对,可以用$key的形式,在当前配置文件中获取
-
- User
- 指定用户运行
-
- Group
- 指定用户组运行
-
- WorkingDirectory
- 进程工作目录,也就是说在执行前会先切换到这个目录
-
- [Install]
- 服务安装的相关设置,一般可设置为多用户的
-
- WantedBy:它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入/etc/systemd/system目录下面以 Target 名 + .wants后缀构成的子目录中
-
- RequiredBy:它的值是一个或多个 Target,当前 Unit 激活时,符号链接会放入/etc/systemd/system目录下面以 Target 名 + .required后缀构成的子目录中
-
- Alias:当前 Unit 可用于启动的别名(比如Master.service文件名字,正常 systemctl status Master.service,设置别名叫Alias=nm,那你就可以systemctl status nm.service 查看实际是Master.service的服务了)
-
- Also:当前 Unit 激活(enable)时,会被同时激活的其他 Unit
-
- Linux 缓和的执行进程关闭,然后重启。在对配置文件修改后需要重启进程时可发送此信号。
-
- *.target级别
- 0runlevel0.target,poweroff.target关闭系统。
- 1runlevel1.target,rescue.target进入救援模式。
- 2runlevel2.target,multi-user.target进入非图形界面的多用户方式。
- 3runlevel3.target,multi-user.target进入非图形界面的多用户方式。
- 4runlevel4.target,multi-user.target进入非图形界面的多用户方式。
- 5runlevel5.target,graphical.target进入图形界面的多用户方式。
- 6runlevel6.target,reboot.target重启系统。
-
- 如:WantedBy=multi-user.target 在 multi-user.target 启用时,我们的服务也就会被启用了。
-
- 完整实例
- [Unit]
-
- Description=Protect ARP list
-
- Wants=network-online.target
-
- After=network.target
-
- [Service]
-
- Type=oneshot
-
- RemainAfterExit=yes
-
- ExecStart=/sbin/arp -f /etc/ip-mac
-
- ExecReload=/sbin/arp -f /etc/ip-mac
-
- ExecStop=/sbin/arp -d -a
-
- [Install]
-
- WantedBy=multi-user.target
-
- eiota@firefly:~$ systemctl status rc-local
- ● rc-local.service - /etc/rc.local Compatibility
- Loaded: loaded (/lib/systemd/system/rc-local.service; enabled-runtime; vendor preset: enabled)
- Drop-In: /usr/lib/systemd/system/rc-local.service.d
- └─debian.conf
- Active: active (running) since Fri 2024-03-29 14:20:24 CST; 2 days ago
- Docs: man:systemd-rc-local-generator(8)
- Process: 516 ExecStart=/etc/rc.local start (code=exited, status=0/SUCCESS)
- Tasks: 104 (limit: 4661)
- Memory: 745.8M
- CGroup: /system.slice/rc-local.service
- ├─ 519 sudo ./app.sh
- ├─ 538 /bin/bash ./app.sh
- ├─ 555 sudo -S ./tysoftdog.sh
- ├─ 562 /bin/bash ./tysoftdog.sh
- ├─ 569 java -Dfile.encoding=utf-8 -jar /home/eiota/ansm/ansm-0.0.1-SNAPSHOT.war
- ├─ 1532 ./eiota_server
- ├─ 1606 sudo -S python3.8 main.py
- ├─ 1608 python3.8 main.py
- ├─312519 sleep 20
- └─312531 sleep 10
-
- Warning: some journal files were not opened due to insufficient permissions.
首先学习一下service文件的写法, service文件放在/lib/systemd/system目录下面,下面以docker.serice文件为示例:
-
- eiota@firefly:/lib/systemd/system$ cat docker.service
- [Unit]
- Description=Docker Application Container Engine
- Documentation=https://docs.docker.com
- After=network-online.target docker.socket firewalld.service containerd.service time-set.target
- Wants=network-online.target containerd.service
- Requires=docker.socket
-
- [Service]
- Type=notify
- # the default is not to use systemd for cgroups because the delegate issues still
- # exists and systemd currently does not support the cgroup feature set required
- # for containers run by docker
- ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
- ExecReload=/bin/kill -s HUP $MAINPID
- TimeoutStartSec=0
- RestartSec=2
- Restart=always
-
- # Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
- # Both the old, and new location are accepted by systemd 229 and up, so using the old location
- # to make them work for either version of systemd.
- StartLimitBurst=3
-
- # Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
- # Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
- # this option work for either version of systemd.
- StartLimitInterval=60s
-
- # Having non-zero Limit*s causes performance problems due to accounting overhead
- # in the kernel. We recommend using cgroups to do container-local accounting.
- LimitNPROC=infinity
- LimitCORE=infinity
-
- # Comment TasksMax if your systemd version does not support it.
- # Only systemd 226 and above support this option.
- TasksMax=infinity
-
- # set delegate yes so that systemd does not reset the cgroups of docker containers
- Delegate=yes
-
- # kill only the docker process, not all processes in the cgroup
- KillMode=process
- OOMScoreAdjust=-500
-
- [Install]
- WantedBy=multi-user.target
编写一个服务程序用于启动一个/home/eiota/test.py程序,服务文件的内容如下,放在/lib/systemd/system目录下。
- eiota@firefly:/lib/systemd/system$ cat zsm_test.service
- [Unit]
- Description=zsm test Service
- #在网络启动后
- After=network.target
-
- [Service]
- Type=simple
- ExecStart=/home/eiota/test.py
- #程序意外退出, 延时2秒自动重启
- RestartSec=2
- Restart=always
-
- [Install]
- #允许多个用户
- WantedBy=multi-user.target
编写好服务文件后需要执行sudo systemctl daemon-reload 重启加载新增的服务,
sudo systemctl enable zsm_test.service 使能服务,
sudo systemctl start zsm_test.service 启动服务。后面设备再开机就能实现服务的自动启动了。
sudo systemctl stop zsm_test.service 停止服务,
sudo systemctl disable zsm_test.service 禁止服务。后面设备再开机就不自动启动了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。