CentOS7添加一个systemd服务教程

一、说明

1.1 背景说明

刚工作时D运营商多用CentOS6,在很长的一段时间内搞不清这两个问题:为什么yum安装的mysql服务用service命令就能启动了、如果自己rpm安装的或自己写的程序也想改成能用service命令启动那又该怎么做。

后来更多用了CentOS7,CentOS7又改用systemctl,和service又有所不同。

自己对Linux时常有一些畏惧感,这种畏惧的由来是有些东西研究了很多次仍然研究不清楚,比如firewall就研究了很多次但现在仍不太会用,这进而导致一些只是看起来难的东西也不想去看了。systemctl就是如此。

最近经同事的提点,对systemctl有了些理解,在此记一记。

 

1.2 service和systemctl

是使用service还是systemctl,取决于操作系统初使化进程(即pid为1的进程)使用的是System V init还是Systemd,前者使用的服务管理命令是service后者使用的是systemctl。

总的而言Systemd在启动速度等方面较System V init都具有优势,虽然有一些反对的声音,但Systemd取代System V init已是大势所趋。更多内容可点击链接

在新版本的CentOS7中我们可以看到也是可以使用service命令的,但这个service命令其实只是systemctl的一个脚本封装。

 

二、添加一个systemd服务

我们这使用nc没安装先用yum安装一下:yum install nc -y

2.1 创建简单的服务配置文件

cat > /usr/lib/systemd/system/lstestd.service << EOF
[Unit]
Description=it is a ls test service
Documentation=man:nc
After=network.target

[Service]
ExecStart=/usr/bin/nc -l 9998
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target
EOF

其中其实最主要的就是systemctl start调用的ExecStart(其值就是正常的bash命令)和systemctl stop使用的KillMode,其他随意看着填。(停止也可以用"ExecStop=/bin/kill -9 $MAINPID"这种暴力写法)

 

2.2 启动和停止服务

创建上边配置文件后一个systemd服务就相当于配置完了,下边直接用systemctl来启动即可。我们文件名是lstestd,即用该名称来调用即可。

# 查看服务状态
systemctl status lstestd

# 启动服务
systemctl start lstestd

# 停止服务
systemctl stop lstestd

如下图所示可以成功使用systemctl进行控制

 

三、systemd服务的几种情况

上边的systemd服务配置还是很简单的,事实上systemd还可以配置在服务启动前(ExecStartPre)、启动后(ExecStartPost)、停止后(ExecStopPost)等众多情况做很多事情,可自行man systemd.service查看手册进行学习。这只说自己疑惑的几种情况

3.1 systemctl enable在做什么

我们知道systemctl enable lstestd表示将lstestd服务设为开机自启动(service对应的是chkconfig lstestd on),那他到底是如何实现的呢。

man systemctl看了一下说就只是给配置文件创建了一个软件链,且在执行systemctl enable时会直接输出他做了什么,我们测试如下:

 那所谓设置开机自启动,那猜测就是系统启动时会自动启动/etc/systemd/system/目录下的服务,在这目录下创建/删除软链接即能设置/f去除开机自启动。

另外要注意如果一个服务被设置为开机自启动后,再去修改服务配置文件时,需要执行一下“systemctl daemon-reload”,不然后续操作该服务会报如下错误:

Warning: lstestd.service changed on disk. Run 'systemctl daemon-reload' to reload units.这

这个命令我还不太确定是做了什么事情,因为我们对配置文件的修改已经保存了,enable也只是做个软链,那还需要额外做什么呢。

 

3.2 systemctl启动命令时如何给服务传递参数

日常启程序时我们常在命令行给程序传递参数,比如"nc -l 9998",那systemctl有没有类似“systemctl start lstestd -l 9998”之类的写法,能让我们在命令行给服务传递参数呢。

首先结论是systemctl是不支持通过命令行给程序动态传递参数的,折中的做法是可以使用Environment/EnvironmentFile配置变量,然后在后边的命令中就可以使用这些参数了。

直接定义变量:

Environment="ONE=one" 'TWO=two two'
ExecStart=/bin/echo $ONE $TWO ${TWO}

变量定义在另外的配置文件中:

EnvironmentFile=/etc/sysconfig/testenv
ExecStart=/bin/echo $ONE $TWO

/etc/sysconfig/testenv定义如下:

# define your vars like in bash file
ONE=one
TWO=two

 

posted on 2021-04-30 17:42  诸子流  阅读(1622)  评论(0编辑  收藏  举报