文章目录
为什么要将程序配置成服务?
我们在linux系统下启动一个程序,一般用一条命令,或者执行一个脚本就行了,那么,为什么还要将程序配置成服务?这样做有什么好处?
1. 自动启动
配置成服务后,程序将在系统启动时自动启动,无需手动操作。这样可以确保程序在系统重启后能够自动运行,避免因为人为疏忽或其他原因导致程序未能启动。
2. 后台运行
配置成服务后,程序将以后台进程的方式运行,不会占用终端或用户会话。这样可以确保程序在后台持续运行,即使用户注销或关闭终端。
3. 定时重启
通过配置服务,可以设置服务在异常退出时自动重启。这样可以提高程序的稳定性,确保在出现问题时能够及时恢复运行。
4. 简化管理
配置成服务后,可以使用系统工具(如
systemctl
)来管理服务,如启动、停止、重启、查看状态等。这样可以方便地管理和监控程序的运行状态。
5. 整合系统
配置成服务后,程序可以与系统的其他服务和组件进行整合。例如,可以设置服务的依赖关系,确保在其他服务启动之前先启动该服务;还可以将服务与日志记录、监控系统等集成,方便管理和故障排查。
6. 自动日志
配置成服务后,系统会自动搜集服务的日志信息,甭管你是c++程序,还是java程序,还是python程序,还是shell脚本,都可以搜集,可以用以下命令查看:
journalctl -u 服务名 --no-pager
版本支持
在不同的Ubuntu版本中,配置开机自启服务的方式可能会有所不同。以下是几个常见的Ubuntu版本和它们支持的开机自启服务类型。本文主要讲解Ubuntu 16.10及更高版本,使用
systemd
作为init系统的服务开机自启方式。
1. Ubuntu 14.04及更早版本:使用
upstart
作为默认的init系统
可以创建一个
.conf
文件来配置开机自启服务,然后将它放在
/etc/init/
目录下。
/etc/rc.local
旧版本
rc.local
是一种在Ubuntu中配置开机自启服务的方式,它属于早期版本的init系统。具体来说,
rc.local
是在Ubuntu 14.04及更早版本中使用的方式,使用的是
upstart
作为默认的init系统。
rc.local
是一个脚本文件,位于
/etc/rc.local
。你可以在该文件中添加要在系统启动时执行的命令或脚本。这些命令或脚本将在系统启动时自动执行。
以下是使用
rc.local
配置开机自启服务的步骤:
- 打开
rc.local
文件:sudonano /etc/rc.local
- 在文件中添加你要执行的命令或脚本。例如,如果要启动一个名为
my_service
的服务,可以添加以下内容:/path/to/your/service
注意,命令或脚本必须是可执行的。 - 保存并关闭文件。
- 确保
rc.local
文件具有可执行权限:sudochmod +x /etc/rc.local
- 重启系统,服务将在系统启动时自动执行。
需要注意的是,
rc.local
方式在较新的Ubuntu版本中已经不再推荐使用,因为它是基于旧的
upstart
系统。对于使用
systemd
作为init系统的较新版本的Ubuntu,建议使用
systemd
的方式来配置开机自启服务。
新版本
在一些较新的Ubuntu版本中,如Ubuntu 16.04及更高版本,
rc.local
文件默认是被禁用的,因为这些版本使用
systemd
作为默认的init系统。
systemd
不会自动执行
rc.local
文件中的内容。
为了在这些版本中使用
rc.local
文件,可以通过配置
rc-local.service
来实现。
rc-local.service
是一个
systemd
服务单元,用于在系统启动时执行
rc.local
文件中的内容。
以下是配置
rc-local.service
的步骤:
- 创建
rc-local.service
文件:sudonano /etc/systemd/system/rc-local.service
- 在文件中添加以下内容:
[Unit]Description=/etc/rc.local CompatibilityConditionPathExists=/etc/rc.local[Service]ExecStart=/etc/rc.local startType=forkingTimeoutSec=0RemainAfterExit=yes[Install]WantedBy=multi-user.target
- 创建
rc.local
文件:sudonano /etc/rc.local
- 在
rc.local
文件中添加要执行的命令或脚本。 - 保存并关闭文件。
- 设置
rc.local
文件的权限:sudochmod +x /etc/rc.local
- 启用
rc-local.service
:sudo systemctl enable rc-local.service
- 启动
rc-local.service
:sudo systemctl start rc-local.service
rc.local
文件中的内容将在系统启动时自动执行。
对于较新的Ubuntu版本,使用
rc.local
和
rc-local.service
的方式可能不是最佳实践。推荐使用
systemd
的方式来配置开机自启服务,以便与当前的init系统保持一致。
2. Ubuntu 15.04到16.04版本:默认使用
systemd
作为init系统,但仍然兼容
upstart
可以使用
upstart
的方式来配置开机自启服务,或者使用
systemd
的方式。
3. Ubuntu 16.10及更高版本:默认使用
systemd
作为init系统
可以使用
systemd
的方式来配置开机自启服务。
总结
systemd
是目前主流的init系统,大多数Ubuntu版本都支持使用
systemd
来配置开机自启服务。但是,对于旧版本的Ubuntu,可能需要使用
upstart
来配置开机自启服务。
开机自启服务原理
以使用systemd作为系统初始化的管理器为例。systemd是一个Linux系统和服务管理器,它负责启动、停止和管理系统中的各种服务。
当系统启动时,systemd会读取
/etc/systemd/system/
目录下的服务配置文件,并根据配置文件中的指令来启动相应的服务。配置文件中的
ExecStart
字段指定了要执行的命令或脚本,
WorkingDirectory
字段指定了命令或脚本的工作目录。
通过使用
systemctl enable
命令,我们告诉systemd将该服务配置文件链接到系统的默认目标(default target),使得该服务在系统启动时自动启动。
当系统启动时,systemd会按照配置文件中的指令来启动服务。如果服务成功启动,systemd会将服务的状态标记为"active"。如果服务启动失败,systemd会将服务的状态标记为"failed"。
通过使用
systemctl start
命令,我们可以手动启动服务。而使用
systemctl stop
命令可以停止服务。
通过使用
systemctl disable
命令,我们可以禁用服务,使得该服务在系统启动时不会自动启动。
总结:使用systemd来管理服务的启动和停止,通过配置服务配置文件并将其链接到系统的默认目标,使得服务在系统启动时自动启动。
配置步骤
以
systemd
作为init系统的服务开机自启方式为例。下面是配置开机自启服务的步骤:
1. 创建配置文件
创建一个服务配置文件,以
.service
为后缀,比如
my_service.service
。
2. 编辑配置文件
使用文本编辑器打开该文件,并添加以下内容:
[Unit]Description=My Service
After=network.target
[Service]ExecStart=/path/to/your/script.sh
WorkingDirectory=/path/to/your/working/directory
[Install]WantedBy=default.target
在上面的配置中,需要替换
/path/to/your/script.sh
为你要在开机时运行的脚本的路径,
/path/to/your/working/directory
为脚本的工作目录。
3. 拷贝配置文件
将该服务配置文件移动到
/etc/systemd/system/
目录下:
sudomv my_service.service /etc/systemd/system/
4. 启用服务
使用以下命令启用服务:
sudo systemctl enable my_service
5. 启动服务
使用以下命令启动服务:
sudo systemctl start my_service
现在,该服务将会在每次开机时自动启动。
6. 停止服务
如果需要停止服务,可以使用以下命令:
sudo systemctl stop my_service
7. 禁用服务
如果需要禁用服务,可以使用以下命令:
sudo systemctl disable my_service
配置项解释
配置父项
在systemd中,配置文件通常使用
.service
扩展名,并且使用
INI格式
。一个
.service
文件可以包含以下三个配置项:
[Unit]
:这个配置项定义了服务的基本属性,如服务的描述、依赖关系、启动顺序等。在这个配置项中,可以设置服务的名称、描述、依赖关系、启动顺序等。[Service]
:这个配置项定义了服务的具体执行方式,如服务的启动命令、环境变量、工作目录等。在这个配置项中,可以设置服务的启动命令、环境变量、工作目录等。[Install]
:这个配置项定义了服务的安装方式,如服务的启动级别、启动顺序等。在这个配置项中,可以设置服务的启动级别、启动顺序等。
这三个配置项分别定义了服务的基本属性、具体执行方式和安装方式。
除了
[Unit]
、
[Service]
和
[Install]
之外,systemd还支持其他一些配置项,用于进一步定义和配置服务。以下是一些常用的配置项:
[Path]
:用于监控文件或目录的变化,并在变化发生时触发服务的启动、停止或重启。[Timer]
:用于定义定时器,可以在指定的时间间隔或特定时间点触发服务的启动、停止或重启。[Socket]
:用于定义套接字,可以监听指定的网络端口或UNIX域套接字,并在有连接请求时触发服务的启动。[Mount]
:用于定义挂载点,可以在指定的文件系统挂载或卸载时触发服务的启动、停止或重启。[Automount]
:用于定义自动挂载点,可以在访问指定的文件系统路径时自动挂载该文件系统。[Swap]
:用于定义交换空间,可以在指定的交换文件或分区被启用或禁用时触发服务的启动、停止或重启。
配置子项
[Unit]
配置子项
-
Description
:用于设置服务的描述信息。
-
Requires
:用于指定服务所依赖的其他服务。
-
After
:用于指定服务启动的顺序,可以设置在哪些服务之后启动。
-
Before
:用于指定服务启动的顺序,可以设置在哪些服务之前启动。
[Service]
配置子项
-
ExecStart
:用于指定服务的启动命令。
-
WorkingDirectory
:用于指定服务的工作目录。
-
Environment
:用于设置服务的环境变量。
-
User
:用于指定服务运行的用户。
-
Group
:用于指定服务运行的用户组。
[Install]
配置子项
-
WantedBy
:用于指定服务在哪些目标(target)下启动。
WantedBy
是systemd服务配置文件中的一个选项,用于指定服务所属的启动级别(target)。启动级别是一组定义了系统启动过程中要启动的服务的目标单元的集合。
在systemd中,启动级别由target单元来表示。每个target单元都是一组相关的服务单元的集合,用于定义系统在不同阶段启动时应该启动哪些服务。例如,
multi-user.target
是一个常见的启动级别,用于表示系统已经启动到多用户模式,此时应该启动所有与用户交互相关的服务。
WantedBy
选项用于指定服务所属的启动级别。它接受一个目标单元的名称作为参数。当你将服务配置文件放置在
/etc/systemd/system/
目录下,并使用
systemctl enable
命令启用服务时,systemd会根据
WantedBy
选项中指定的目标单元,将服务添加到相应的启动级别中。
在上面的例子中,
WantedBy=multi-user.target
表示该服务应该属于
multi-user.target
启动级别,即系统已经启动到多用户模式时应该启动该服务。
在systemd中,有以下几个常见的启动级别(target):
poweroff.target
:系统关机时的目标单元。rescue.target
:用于系统救援的目标单元,提供了一个最小的功能集合,用于修复系统问题。multi-user.target
:多用户模式的目标单元,用于正常的多用户操作。graphical.target
:图形界面模式的目标单元,用于启动图形界面环境。reboot.target
:系统重启时的目标单元。
除了上述常见的启动级别,还有其他一些特定的启动级别,如
network.target
(网络启动完成后的目标单元)、
default.target
(默认目标单元,通常是
multi-user.target
或
graphical.target
)等。
对于普通程序来说,通常会将其配置为属于
multi-user.target
或
graphical.target
这样的启动级别,以便在系统启动到多用户模式或图形界面模式时自动启动。你可以根据你的需求选择适合的启动级别。
-
RequiredBy
:用于指定哪些目标(target)依赖于该服务。
systemd官方文档(systemd.service完整配置选项)
https://www.freedesktop.org/software/systemd/man/systemd.service.html
vscode相关插件:Systemd Helper
可以方便我们编辑systemd配置文件:
使用软链接链接systemd配置文件
可以将
.service
文件创建为软链接,链接到实际文件。这样做可以使服务配置文件保持在原始位置,同时在
/etc/systemd/system
目录下创建一个链接,以便systemd能够找到并管理该服务。
步骤
以下是创建软链接的步骤:
- 在
/etc/systemd/system
目录下创建一个软链接,链接到实际文件。例如,假设实际文件位于/path/to/my-service/my-service.service
,可以使用以下命令创建软链接:sudoln-s /path/to/my-service/my-service.service /etc/systemd/system/
或者:sudoln-s /path/to/my-service/my-service.service /etc/systemd/system/my-service.service
注意:systemd要求软链接必须与目标名称相同,如果不同执行systemctl enable xxx时将报
Failed to enable unit: File xxx.service: Link has been severed
错误
- 确保软链接的文件权限正确设置。一般来说,软链接的所有者应为
root
用户,权限应为644
:sudochown root:root /etc/systemd/system/my-service.servicesudochmod644 /etc/systemd/system/my-service.service
通过这种方式,服务配置文件将保持在原始位置,而软链接将位于
/etc/systemd/system
目录下,使systemd能够找到并管理该服务。这样做的好处是,当需要修改或更新服务配置文件时,只需在原始位置进行操作,而不需要修改软链接。
注意:如果用软链接配置,disable服务时,会将/etc/systemd/system下的.service软链接删除;但是如果是普通文件方式,disable服务时,不会将/etc/systemd/system下的.service文件删除
请看下面测试示例:
- 普通
.service
文件方式(将.service
文件拷贝到/etc/systemd/system
下):
root@nvidia:/userdata/testOnebuttonDeploy/shsany_ai/clean_up# systemctl enable ky_ai_algo_manager.service
Created symlink /etc/systemd/system/default.target.wants/ky_ai_algo_manager.service → /etc/systemd/system/ky_ai_algo_manager.service.
root@nvidia:/userdata/testOnebuttonDeploy/shsany_ai/clean_up#
root@nvidia:/userdata/testOnebuttonDeploy/shsany_ai/clean_up# systemctl disable ky_ai_algo_manager.service
Removed /etc/systemd/system/default.target.wants/ky_ai_algo_manager.service.
root@nvidia:/userdata/testOnebuttonDeploy/shsany_ai/clean_up#
root@nvidia:/userdata/testOnebuttonDeploy/shsany_ai/clean_up# ll /etc/systemd/system/ky_ai_algo_manager.service-rwxr-xr-x 1 root root 240 Aug 1611:36/etc/systemd/system/ky_ai_algo_manager.service*
- 软链接方式(在
/etc/systemd/system
中创建软链接链接到实际文件):
root@nvidia:/userdata/testOnebuttonDeploy/shsany_ai/clean_up# systemctl disable ky_ai_algo_manager
Removed /etc/systemd/system/ky_ai_algo_manager.service.
Removed /etc/systemd/system/default.target.wants/ky_ai_algo_manager.service.
root@nvidia:/userdata/testOnebuttonDeploy/shsany_ai/clean_up#
root@nvidia:/userdata/testOnebuttonDeploy/shsany_ai/clean_up#
root@nvidia:/userdata/testOnebuttonDeploy/shsany_ai/clean_up# ll /etc/systemd/system/ky_ai_algo_manager.service
ls: cannot access '/etc/systemd/system/ky_ai_algo_manager.service': No such fileor directory
systemd服务配置相关指令
-
systemctl start <service>
:启动一个服务。
-
systemctl stop <service>
:停止一个服务。
-
systemctl restart <service>
:重启一个服务。
-
systemctl reload <service>
:重新加载一个服务的配置文件,使其生效。
-
systemctl enable <service>
:设置一个服务在系统启动时自动启用。
-
systemctl disable <service>
:设置一个服务在系统启动时不自动启用。
-
systemctl status <service>
:查看一个服务的状态,包括是否正在运行、最后一次的活动时间等信息。
注意,使用systemctl status查看某个服务状态时,可能因为服务日志信息太长产生分页,阻塞程序执行,这时可以加个
--no-pager
选项屏蔽(suppress)分页,如:
systemctl status $SERVICE_NAME --no-pager
-
systemctl is-active <service>
:检查一个服务是否正在运行。
-
systemctl is-enabled <service>
:检查一个服务是否已经设置为在系统启动时自动启用。
-
systemctl list-units
:列出所有正在运行的单位(包括服务、套接字、挂载点等)。
-
systemctl list-unit-files
:列出所有可用的单位文件(包括服务、套接字、挂载点等)。
systemd其他指令
查看systemd服务日志(journalctl -u $SERVICE_NAME --no-pager -u $LINE_COUNT)
查看systemd某个服务的日志,可以使用
journalctl
命令。
journalctl
命令用于查看systemd日志,包括系统日志和服务日志。
要查看某个服务的日志,可以使用以下命令:
journalctl -u$SERVICE_NAME
其中,
$SERVICE_NAME
是要查看日志的服务名称。这将显示与该服务相关的日志条目。
还可以使用其他选项来进一步筛选和格式化日志。例如,可以使用
-n
选项指定要显示的日志条目数量,使用
-f
选项实时跟踪日志,使用
--since
和
--until
选项指定时间范围等。
以下是一些示例命令:
# 显示最近的10条服务日志
journalctl -u$SERVICE_NAME-n10# 实时跟踪服务日志
journalctl -u$SERVICE_NAME-f# 显示指定时间范围内的服务日志
journalctl -u$SERVICE_NAME--since"2022-01-01"--until"2022-01-02"
systemd支持在/etc/systemd/system创建子目录,便于我们方便管理我们的.service文件(没成功)
systemd会递归遍历
/etc/systemd/system
目录下的所有
.service
文件以及子目录中的
.service
文件。这意味着可以在
/etc/systemd/system
目录下创建子目录,并在子目录中放置您的服务配置文件。
例如,如果在
/etc/systemd/system
目录下创建了一个名为
my-service
的子目录,并将服务配置文件
my-service.service
放置在该子目录中,systemd仍然能够找到并管理该服务。
这种递归遍历的机制使得您可以更好地组织和管理多个服务的配置文件,而不会造成混乱。
测试1:创建子目录,在子目录中创建软链接,[执行systemctl daemon-reload],执行system enable xxx,报错:Failed to enable unit: Unit file xxx.service does not exist.
[]
为可选,下同
测试2:创建子目录,将.service文件拷贝到子目录,[执行systemctl daemon-reload],执行system enable xxx,报错:Failed to enable unit: Unit file xxx.service does not exist.
测试3:不创建子目录,创建软链接到/etc/systemd/system下,[执行systemctl daemon-reload],执行system enable xxx,成功
莫非只能在
/etc/systemd/system
下?不支持子目录?
配置示例
20230802
ky_ai_convert_video.service
[Unit]
Description=ky_ai_convert_video
After=network.target
[Service]
ExecStart=/ky/tml/ky_ai_convert_video/kyai_video_converter
WorkingDirectory=/ky/tml/ky_ai_convert_video
Restart=always
RestartSec=3[Install]
WantedBy=default.target
测试
开个log监控:
tail -f ky_ai_api.log
杀进程:
ps -ef | grep convert
kill <pid>
发现过三秒就又起来了:
重启测试:
程序运行正常
版权归原作者 Dontla 所有, 如有侵权,请联系我们删除。