CenOS 7.x的高级管理工具systemd介绍

一、系统启动流程回顾

POST(加电自检) - BIOS(硬件检测,找到启动的设备) – MBR(Bootloader) – GRUB(查看并加载内核) – Kernel(可能要记住ramdisk,挂载rootfs,加载init程序) – 用户空间启动初始化工作(init程序通过不同机制来实现)。
接下来,我们主要讲的就是CentOS 7.x引入的一个用来实现init工作的管理工具,叫systemd。当然,它的功能也不仅仅是完成init原先的工作。

二、CentOS 5.x,6.x,7.x的init程序区别

linux的init程序类型:
(1) CentOS 5.x以及之前
init是SysV init;
配置文件:/etc/inittab
(2) CentOS 6.x
init是upstart来实现的一部分;
配置文件:/etc/inittab,为了向后兼容,其实该配置文件作用很小
实质的配置读取的配置文件:/etc/init/*.conf
(3) CentOS 7.x
init是systemd实现的一部分;
配置文件:/usr/lib/systemd/system/, /etc/systemd/system/
实际/sbin/init是一个指向/lib/systemd/systemd程序的一个链接文件;

三、systemd工具介绍

参考链接:
https://wiki.archlinux.org/index.php/Systemd_(简体中文)
https://linux.cn/article-7365-1.html
https://www.freedesktop.org/wiki/Software/systemd/
http://www.jinbuguo.com/systemd/systemd.html
https://baike.baidu.com/item/systemd/18473007
http://blog.51cto.com/andyxu/2122109?source=dra

3.1、systemd工具概述

在CentOS 7.x中,init命令默认是一个指向systemd命令的软链接:

[root@localhost ~]# ls -l /usr/sbin/init 
lrwxrwxrwx. 1 root root 22 Nov 25  2018 /usr/sbin/init -> ../lib/systemd/systemd
[root@localhost ~]# ls -l /lib/systemd/systemd
-rwxr-xr-x. 1 root root 1612152 Apr 11  2018 /lib/systemd/systemd

查看systemd软件包的信息和安装文件:

[root@localhost ~]# rpm -qi systemd
Name        : systemd
Version     : 219
Release     : 57.el7
Architecture: x86_64
Install Date: Sun 25 Nov 2018 07:24:02 PM CST
Group       : Unspecified
Size        : 24389374
License     : LGPLv2+ and MIT and GPLv2+
Signature   : RSA/SHA256, Wed 25 Apr 2018 07:48:21 PM CST, Key ID 24c6a8a7f4a80eb5
Source RPM  : systemd-219-57.el7.src.rpm
Build Date  : Wed 11 Apr 2018 03:37:32 PM CST
Build Host  : x86-01.bsys.centos.org
Relocations : (not relocatable)
Packager    : CentOS BuildSystem <http://bugs.centos.org>
Vendor      : CentOS
URL         : http://www.freedesktop.org/wiki/Software/systemd
Summary     : A System and Service Manager
Description :
systemd is a system and service manager for Linux, compatible with
SysV and LSB init scripts. systemd provides aggressive parallelization
capabilities, uses socket and D-Bus activation for starting services,
offers on-demand starting of daemons, keeps track of processes using
Linux cgroups, supports snapshotting and restoring of the system
state, maintains mount and automount points and implements an
elaborate transactional dependency-based service control logic. It can
work as a drop-in replacement for sysvinit.

[root@localhost ~]# rpm -ql systemd
/etc/X11/xorg.conf.d
/etc/X11/xorg.conf.d/00-keyboard.conf
/etc/binfmt.d
/etc/dbus-1/system.d/org.freedesktop.hostname1.conf
/etc/dbus-1/system.d/org.freedesktop.import1.conf
/etc/dbus-1/system.d/org.freedesktop.locale1.conf
/etc/dbus-1/system.d/org.freedesktop.login1.conf
/etc/dbus-1/system.d/org.freedesktop.machine1.conf
/etc/dbus-1/system.d/org.freedesktop.systemd1.conf
/etc/dbus-1/system.d/org.freedesktop.timedate1.conf
/etc/hostname
/etc/locale.conf
/etc/localtime
/etc/machine-id
/etc/machine-info
/etc/modules-load.d
/etc/pam.d/systemd-user
/etc/rc.d/init.d/README
/etc/rc.d/rc.local
/etc/rc.local
/etc/rsyslog.d/listen.conf
/etc/sysctl.d
/etc/systemd
/etc/systemd/bootchart.conf
/etc/systemd/coredump.conf
/etc/systemd/journald.conf
/etc/systemd/logind.conf
/etc/systemd/system
/etc/systemd/system.conf
/etc/systemd/system/runlevel2.target
/etc/systemd/system/runlevel3.target
/etc/systemd/system/runlevel4.target
/etc/systemd/system/runlevel5.target
......#因为systemd包的内容很多,所以省略

作用:systemd是一个linux系统基础组件的集合,提供来一个系统和服务管理器,运行为pid为1的并负责其他程序。包括:
(1) 支持并行化任务,完成系统引导时候实现服务并行启动;
(2) 同时采用socket方式与D-Bus总线式激活服务;
(3) 实现按需启动守护进程;
(4) 利用linux的Cgroups监视进程;
(5) 支持快照和系统恢复;
(6) 维护挂载点和自动挂载点;
(7) 对各服务间基于一来关系进程精密控制;
(8) systemd支持SysV和LSB出事脚本,可以替代sysVinit;
(9) 可以实现众多其他功能,包括控制日志进程、控制基础系统配置、维护登录用户列表以及系统账户、运行时目录和设置,可以运行容器和虚拟机,可以简单的管理网络配置、网络时间同步、日志转发和名称解析等。

关于Cgroups可以介绍参考:https://www.imooc.com/article/72502

[root@localhost ~]# ps axo pid,ppid,command|grep systemd
     1      0 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
   355      1 /usr/lib/systemd/systemd-journald
   389      1 /usr/lib/systemd/systemd-udevd
   538      1 /usr/lib/systemd/systemd-logind
   539      1 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
  1866   1195 grep --color=auto systemd

上面的进程,主进程是pid为1的,然后其他进程都是辅助完成工作的。

主要特性:
(1) 系统引导时候实现服务并行启动;
(2) 可以按需激活进程;
(3) 可以对系统状态做快照;
(4) 基于依赖关系定义服务控制逻辑。

扫描二维码关注公众号,回复: 4959709 查看本文章

支持的命令行选项有:(应用不多,不重要,了解即可)

#程序完整路径:/usr/lib/systemd/systemd 
#因为没有加入路径环境变量PATH中,所以使用的时候要使用程序命令的绝对路径;
-h, --help  #查看帮助信息
--version #查看帮助信息
--test #检测并输出启动序列,然后退出。 仅用于调试目的。不要使用操作管理员运行带上这个选项,会有报错提示。使用还要配置相关环境变量。
--dump-configuration-items #输出一个单元(unit)列表。 此列表简明且完整的列出了 所有单元文件中定义的"unit"。简单来说就是unit文件中每个配置段可以参数设置有哪些
--unit=  #设置启动时默认启动的单元(unit)。 默认值是 default.target

--system #--system 表示强制作为系统实例运行(即使"PID≠1"), --user 表示强制作为用户实例运行(即使"PID=1")。 通常不应该使用此选项。 此选项仅用于调试目的, 而且 --system 仅在与 --test 一起使用时才有实际意义。
--dump-core #在崩溃时进行内存转储。 当作为用户实例运行时,此选项没有实际意义。 此选项还可以通过内核引导选项 systemd.dump_core= 开启。
--crash-shell #在崩溃时启动一个 shell 。 当作为用户实例运行时,此选项没有实际意义。 此选项还可以通过内核引导选项 systemd.crash_shell= 开启。

--confirm-spawn #在派生新进程时进行确认提示。 当作为用户实例运行时,此选项没有实际意义。
--show-status= #设置是否显示单元状态信息。接受一个布尔值或特殊值 auto 。 设为 yes 表示在系统启动与关闭的过程中,在控制台上显示简明的单元状态信息。 设为 no 表示不显示这些信息。 设为 auto 与 no 类似,不同之处在于,一旦遇见单元失败或启动流程出现重大延迟,立即自动切换为 yes 设置。 当作为用户实例运行时,此选项没有实际意义。
--log-target= #设置日志的目标,其参数必须是 console, journal, kmsg, journal-or-kmsg, null 之一。
--log-level= #设置日志的级别, 其参数必须是一个数字或者 符合 syslog(3) 习惯的 emerg, alert, crit, err, warning, notice, info, debug 之一(小写)。
--log-color= #高亮重要的日志信息,其参数必须是一个表示真假的布尔值, 若未指定则相当于设为 yes
--log-location= #在日志中包含代码的位置, 其参数必须是一个表示真假的布尔值, 若未指定则相当于设为 yes 。仅用于调试目的。
--default-standard-output=, --default-standard-error= 
#为所有的 service 与 socket 设置默认的标准输出与标准错误, 相当于设置 StandardOutput= 与 StandardError= 指令的值(参见 systemd.exec(5) 手册)。其参数必须是 inherit, null, tty, journal, journal+console, syslog, syslog+console, kmsg, kmsg+console 之一(小写)。 --default-standard-output= 的默认值是 journal ;而 --default-standard-error= 的默认值是 inherit

#上面可能用的到的一个选项,我觉得是–dump-configuration-items

[root@localhost ~]# /usr/lib/systemd/systemd --dump-configuration-items
[Unit]
Description=STRING
Documentation=URL
SourcePath=PATH
Requires=UNIT [...]
RequiresOverridable=UNIT [...]
#此处省略......
[Service]
PIDFile=PATH
ExecStartPre=PATH [ARGUMENT [...]]
ExecStart=PATH [ARGUMENT [...]]
ExecStartPost=PATH [ARGUMENT [...]]
ExecReload=PATH [ARGUMENT [...]]
ExecStop=PATH [ARGUMENT [...]]
#此处省略......
[Socket]
ListenStream=SOCKET [...]
ListenDatagram=SOCKET [...]
ListenSequentialPacket=SOCKET [...]
ListenFIFO=SOCKET [...]
#此处省略......
[BusName]
Name=STRING
Activating=BOOLEAN
Service=OTHER
#此处省略......
[Mount]
What=STRING
Where=PATH
Options=STRING
Type=STRING
TimeoutSec=SECONDS
DirectoryMode=MODE
#此处省略......
[Automount]
Where=PATH
DirectoryMode=MODE
TimeoutIdleSec=SECONDS
[Swap]
What=PATH
Priority=INTEGER
Options=STRING
TimeoutSec=SECONDS
#此处省略......
[Timer]
OnCalendar=TIMER
OnActiveSec=TIMER
OnBootSec=TIMER
#此处省略......
[Path]
PathExists=PATH
PathExistsGlob=PATH
#此处省略......
[Slice]
Slice=SLICE
CPUAccounting=BOOLEAN
CPUShares=SHARES
StartupCPUShares=SHARES
#此处省略......
[Scope]
Slice=SLICE
CPUAccounting=BOOLEAN
CPUShares=SHARES
StartupCPUShares=SHARES
CPUQuota=OTHER
MemoryAccounting=BOOLEAN
MemoryLimit=LIMIT
#此处省略......
[Install]
Alias=OTHER
WantedBy=OTHER
RequiredBy=OTHER
Also=OTHER
DefaultInstance=OTHER

3.2、systemctl工具概述

systemctl是systemd系统和服务管理器,它可用于检查和控制 systemd 系统与服务管理器的状态。

3.3、service以及chkconfig工具使用回顾

service SCRIPT COMMAND [OPTIONS]
其中SCRIPT表示被service管理的服务脚本,通常位于/etc/init.d/下。COMMAND表示对服务操作的的命令,比如start,stop,reload,restart等。OPTIONS表示传递的命令执行选项。
说明:COMMAND表示服务脚本中定义的命令,至少要包含start和stop这两种,才能交由service管理。服务脚本被service管理后,只继承来LANG和TERM这连个环境变量。所以建议在做Sysv或upstart服务脚本的时候,建议在指定位置指明好环境变量设置。

常用组合如下:(假设服务的脚本为name)
service name start #启动指定服务;
service name stop #停止指定服务;
service name restart #重启指定服务;
service name status #查看指定服务状态;
service name condrestart #条件式重启,如果服务已经启动,才重启,没有启动不做任何操作;
service --status-all #按照服务字母顺序,列出所有服务脚本执行status命令后的结果;

对于chkconfig来说,大概语法格式如下:
chkconfig [--list] [--type type][name]
chkconfig --add name
chkconfig --del name
chkconfig --override name
chkconfig [--level levels] [--type type] name <on|off|reset|resetpriorities>
chkconfig [--level levels] [--type type] name

--list [--type type] [name]:列出向chkconfig所注册的所有已知的服务,并且显示是否在指定的运行级别,该服务是否启动。可以指定具体的服务,表示只查看具体的服务。其中--type的可选参数有sysv和xinetd,默认不指定--type表示显示所有sysv的独立服务以及xinetd管理的非独立服务。
--add name:指定添加给chkconfig管理的服务脚本名。这个脚本的开头几行有固定格式,一会儿示例配置注解文件,将会给出说明。
--del name:移除指定给chkconfig管理的服务脚本;
--level levels:指定运行级别。可以指定0,1,2,3,4,5,6这6个数字,可以随机组合。常见的添加时候指定的运行级别就是3,4,5,即可以这样指定--level 345.通常指定运行级别后,在服务后边指定出现两个比较常见的字符串,on或off。on表示启用(在指定运行级别下,指定运行级别可以通过--level指定或者服务脚本中的固定语法),off表示禁用(在指定运行级别下,指定运行级别可以通过--level指定或者服务脚本中的固定语法)。

关于运行级别文件说明:

Each  service  which  should  be  manageable  by chkconfig needs two or more commented lines added to its init.d script. The first line tells chkconfig what runlevels the service should be started in by default,  as  well  as
the  start  and  stop  priority  levels. If the service should not, by default, be started in any runlevels, a -
should be used in place of the runlevels list.  The second line contains a description for the service, and  may
be extended across multiple lines with backslash continuation.
每个存在于/etc/init.d目录下的被chkconfig管理的服务脚本,都需要两行或者更多行的注释添加在脚本文件中。
第一行特定注释用于高速chkconfig默认服务在什么运行级别下启动,以及启动和停止服务时相较于其他服务脚本的运行优先级。如果想初始的时候,服务脚本在类型运行级别下都不启动,可以指定短破折号(-)占位符。
第二行特定注释部分用来对服务进行一个描述,如果一行不够写,可以是否用符号\来扩展到多行。

For example, random.init has these three lines:
# chkconfig: 2345 20 80
# description: Saves and restores system entropy pool for \
# higher quality random number generation.
This  says  that the random script should be started in levels 2, 3, 4, and 5, that its start priority should be
20, and that its stop priority should be 80.  You should be able to figure out what the description says; the 
causes the line to be continued.  The extra space in front of the line is ignored.

例如,random 服务脚本有下面三行:
# chkconfig: 2345 20 80
# description: Saves and restores system entropy pool for \
# higher quality random number generation.
第一行"#chkconfig: 2345 20 80",其中的2345表示服务被注册或添加加到chkconfig管理,在2,3,4,5运行
级别下,这个服务是启动的,在0,1,6运行级别下,这个服务是不启动的。然后后面的数字20和80分别表示
启动优先级。优先级,数字越小,越是优先启动,被依赖的服务先启动,而依赖的服务后启动,优先级,数字
越小,越是优先关闭;依赖的服务先关闭,而后关闭被依赖的。
结合启动和关闭优先级数字以及运行级别,具体一点来说,把这个random脚本给上执行权限,放在/etc/init.d目录
下,然后通过chkconfig --add random注册后,在/etc/rc.d/rc0.d,/etc/rc.d/rc1.d,/etc/rc.d/rc6.d目录下,会有一个
名叫K80random的链接文件,链接文件指向的是/etc/rc.d/init.d/random。因为以K开头的脚本表示关闭时执行的
脚本。而在/etc/rc.d/rc2.d ,/etc/rc.d/rc3.d,/etc/rc.d/rc.4.d,/etc/rc.d/rc5.d目录下,会有一个名叫K20random
的链接文件,链接文件指向的是/etc/rc.d/init.drandowm。因为以S开头的脚本表示启动时执行的脚本。

第二行是对服务脚本的一个描述信息,因为为了格式,所以利用符号\进行来换行。

chkconfig  also  supports  LSB-style init stanzas, and will apply them in preference to "chkconfig:" lines where
available.  A LSB stanza looks like:
### BEGIN INIT INFO
# Provides: foo
# Required-Start: bar
# Defalt-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: Foo init script
### END INIT INFO
chkconfig也支持LSB风格的初始段落,而且如果与# chkconfig: 同时出现,这个LSB风格的优先级更高。一个LSB
风格的配置段如下:(LSB风格配置语法很多,一般如果是自己编写服务脚本,我们都没有写这种风格的,不过
对于常见服务的rpm包,完整格式的,这两风格都有给定)
### BEGIN INIT INFO
# Provides: foo
# Required-Start: bar
# Defalt-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: Foo init script
### END INIT INFO

In this case, the start priority of "foo" would be changed such that it is higher than the "bar" start priority,
if  "bar"  is  enabled.  Care must be taken when adding dependencies, as they can cause vast shifts in the start
and stop priorities of many scripts.
在这种情况下, 因为通过# Required-Start指明来服务bar,所以foo服务要启动,其优先级要比bar低,因为要
启动foo,要先启动bar。如果bar服务脚本已经启动,在添加依赖关系的时候要特别小心,因为添加依赖关系
可能回改变大多数服务脚本启动或停止时候的优先级。
Default-Start: 2 3 4 5 表示的含义为在运行级别为2、3、4、5下,服务脚本启动;
Default-Stop: 0 1 6 表示的含义为在运行级别为0、1、6下,服务脚本关闭;
Description: Foo init script表示描述信息
上面的这些注释信息要指定在INIT INFO的段落中,也是注释信息。

选取redis的rpm包的一个服务脚本的分析实例:

#!/bin/sh
#
# redis        init file for starting up the redis daemon  ##redis以守护进程运行时候的init 文件(upstart的脚本文件)
#
# chkconfig:   - 20 80			#-表示匹配所有的运行级别默认都不启动该脚本(一旦执行chkconfig --add redis添加服务脚本给chkconfig管理之后,在/etc/rc.d/rcRUNLEVEL.d/目录下会都是K80redis,
#K*表示停止要执行的脚本)。后边如果要想让redis在指定运行级别下启动,需要通过chkconfig [--level levels] redis on来设置,如果没有指定运行级别,默认是2345,如果有指定,就是指定级别。比如没有指定
#执行了chkconfig redis on表示2345运行级别要启动redis脚本,那么/etc/rc.d/rc[2-5].d/S20redis脚本将会存在(之前是K80redis),而/etc/rc.d/rc{0,1,6}.d/目录下还是K80redis
#20表示脚本的启动优先级数字,80表示脚本关闭的优先级数字(服务脚本托管给chkconfig管理的规范语法,可以省略)
# description: Starts and stops the redis daemon.	#服务管理脚本的描述信息:启动和关闭redis进程
# 


### BEGIN INIT INFO
# Provides: redis-server
# Required-Start: $local_fs $remote_fs $network
# Required-Stop: $local_fs $remote_fs $network
# Short-Description: start and stop Redis server
# Description: A persistent key-value database
### END INIT INFO
#上面这样段是LSB的段落信息,也是定义脚本启动以来关系的。因为语法比较复杂,讲起来一会儿讲不清楚,忽略即可。


# Source function library.	#载入系统的一个定义的函数库,里边有很多有用的函数;
. /etc/rc.d/init.d/functions

name="redis-server"	#redis程序的名字;
exec="/usr/bin/$name"  #执行redis程序调用的绝对路径
shut="/usr/libexec/redis-shutdown"	#执行关闭调用的脚本程序绝对路径
pidfile="/var/run/redis/redis.pid"   #进程运行的pid文件
REDIS_CONFIG="/etc/redis.conf"   #redis的主配置文件

[ -e /etc/sysconfig/redis ] && . /etc/sysconfig/redis #如果redis的配置文件控制配置文件存在,则载入(一般这个地方的配置文件会预设一些变量控制)

lockfile=/var/lock/subsys/redis	#进程运行过程中的锁文件

start() {    #定义启动函数
    [ -f $REDIS_CONFIG ] || exit 6	#如果主配置文件不存在,则以状态值为6退出。
    [ -x $exec ] || exit 5	#如果redis调用程序文件不存在或没有执行权限,则以状态值5退出。
    echo -n $"Starting $name: "  #$""这种写法是bash的一种兼容性写法,会根据本地的locale做字符串的转换,$name还是会做变量替换,这里就是echo -n Starting redis-server,提示启动redis-server
    daemon --user ${REDIS_USER-redis} "$exec $REDIS_CONFIG --daemonize yes --pidfile $pidfile" 
	#REDIS_USER变量为空,会以redis为初始值。
	#daemon是/etc/rc.d/init.d/functions中定义的一个函数。
	#这里实际就是以守护进程的方式运行redis,运行/usr/bin/redis-server /etc/redis.conf --daemonize yes --pidfile /var/run/redis/redis.pid
    retval=$?   #运行redis状态信息
    echo	#空一行
    [ $retval -eq 0 ] && touch $lockfile  #如果运行redis守护进程成功,就创建redis的锁文件
    return $retval    #start(启动函数)的返回值(返回启动状态值)
}

stop() {
    echo -n $"Stopping $name: "	   #打印提示关闭信息,echo -n Stopping redis-server
    [ -x $shut ] && $shut		   #如果/usr/libexec/redis-shudown关闭脚本存在且有执行权限,则执行/usr/libexec/redis-shutdown
    retval=$?					   #停止状态
    if [ -f $pidfile ]             #如果redis进程运行文件(/var/run/redis/redis.pid)还存在,表示调用redis-shutdown关闭异常了
    then
        # shutdown haven't work, try old way   #关闭执行异常,会调用kill这种老方式来关闭程序
        killproc -p $pidfile $name     #直接调用/etc/rc.d/init.d/functions中定义的killproc函数关闭程序(killproc -p /var/run/redis/redis.pid redis-server)
        retval=$?
    else
        success "$name shutdown"	   #如果/var/run/redis/redis.pid文件不存在,表示进程关闭成功,调用函数successs(/etc/rc.d/init.d/functions中定义的)打印信息 [ OK ]。
    fi
    echo
    [ $retval -eq 0 ] && rm -f $lockfile  #如果成功关闭后,把锁文件删除
    return $retval     #stop(停止函数)的返回值(返回停止状态值)
}

restart() {   #重启函数,就是先调用停止函数,然后调用启动函数
    stop
    start
}

rh_status() {
    status -p $pidfile $name   #调用status函数(/etc/rc.d/init.d/functions中定义的)检测redis程序状态,
}

rh_status_q() {    #安静模式,只是检测进程状态值
    rh_status >/dev/null 2>&1   
}

#case分支语句,脚本调用支持start,stop,restart,reload,force-reload,status,condrestart,try-restart
case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1   #这里调用有问题,因为根本没有定义reload函数,而且functions中也没有reload函数。经过测试redis不支持HUP信号。
			  #他被许多守护进程理解为一个重新设置的请求.如果一个进程不用重新启动就能重新读取它的配置文件并调整自给以适应变化的话,那么HUP通常来触发这种行为.
			  #所以生产中可以把这个reload去掉,redis如果要运行时修改,可以使用CONFIG指令修改,而且支持永久保存配置文件。
        ;;
    force-reload)
        force_reload  #这里调用有问题,因为根本没有定义force_reload函数,而且functions中也没有force_reload函数。
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)   #redis没有先检测语法的能力,所以这里这个分支判断没必要,而且下面的实现逻辑就是检测状态成功后并重启。
        rh_status_q || exit 0    
        restart
        ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart}"
        exit 2
esac
exit $?

3.4、systemd中的unit介绍

systemd中的unit一共有12中,分别是:

service.service,service.service, socket.socket, device.device, mount.mount, 
automount.automount, swap.swap, target.target, path.path,timer.timer, 
snapshot.snapshot, slice.slice, scope.scope

详情请参考:
man systemd.unit

unit的常见类型:

(1) Service unit:文件扩展名为.service,用于定义系统服务;
(2) Target unit:文件扩展为.target,用于模拟实现“运行级别”;
(3) Device unit: .device,用于定义内核识别的设备;
(4) Mount unit: .mount,定义文件系统挂载点;
(5) Socket unit: .socket,用于标识进程间通信用到的socket文件;
(6) Snapshot unit: .snapshot, 管理系统快照;
(7) Swap unit: .swap, 用于标识swap设备;
(8) Automount unit: .automount,文件系统自动点设备;
(9) Path unit: .path, 用于定义文件系统中的一文件或目录;

3.5、systemctl工具实现service和chkconfig的功能

systemctl  [OPTIONS...]  COMMAND  [NAME...]
这里的OPTIONS表示systemctl工具支持的选项(用到时候再查即可),下面才是对重要的,和之前service
和chkconfig工具的一个对比,如果没有写上service或chkconfig表示只是systemctl独有的;

(1) 启动服务: service  NAME  start  ==>  systemctl  start  NAME.service
(2) 停止服务: service  NAME  stop  ==> systemctl  stop  NAME.service
(3) 重启服务: service  NAME  restart  ==>  systemctl  restart  NAME.service
(4) 查看服务状态: service  NAME  status  ==>  systemctl  status  NAME.service
(5) 条件式重启服务:service  NAME  condrestart  ==>  systemctl  try-restart  NAME.service
(6) 重载或重启服务: systemctl  reload-or-restart  NAME.servcie
(7) 重载或条件式重启服务:systemctl  reload-or-try-restart  NAME.service
(8) 查看某服务当前激活与否的状态: systemctl  is-active  NAME.service
(9) 查看所有已激活的服务:systemctl  list-units  --type  service
(10) 查看所有服务(已激活及未激活): chkconfig --lsit  ==>  systemctl  list-units  -t  service  --all	
或 stemctl list-unit-files --type service	
(11) 设置服务开机自启: chkconfig  NAME  on  ==>  systemctl  enable  NAME.service
(12) 禁止服务开机自启: chkconfig  NAME  off  ==>  systemctl  disable  NAME.service 
(13) 查看某服务是否能开机自启: chkconfig  --list  NAME  ==>  systemctl  is-enabled  NAME.service

(14) 禁止某服务设定为开机自启: systemctl  mask  NAME.service
(15) 取消此禁止: systemctl  unmask  NAME.servcie
(16) 查看服务的依赖关系:systemctl  list-dependencies  NAME.service
(17) 杀掉进程:systemctl kill unitname


查看服务状态信息:

systemctl list-unit-files --type service --all显示状态

loaded:Unit配置文件已处理
active(running):一次或多次持续处理的运行
active(exited):成功完成一次性的配置
active(waiting):运行中,等待一个事件
inactive:不运行
enabled:开机启动
disabled:开机不启动
static:开机不启动,但可被另一个启用的服务激活

3.6、systemctl实现运行级别切换和管理

管理target units:

	运行级别:
		0  ==>  runlevel0.target,  poweroff.target
		1  ==>  runlevel1.target,  rescue.target
		2  ==>  runlevel2.tartet,  multi-user.target
		3  ==>  runlevel3.tartet,  multi-user.target
		4  ==>  runlevel4.tartet,  multi-user.target
		5  ==>  runlevel5.target,  graphical.target
		6  ==>  runlevel6.target,  reboot.target
		
	级别切换: init  N  ==>  systemctl  isolate  NAME.target
	
	查看级别: runlevel  ==>  systemctl  list-units  --type  target
	查看所有级别: systemctl  list-units  -t  target  -a
	
	获取默认运行级别:systemctl  get-default  
	修改默认运行级别: systemctl  set-default   NAME.target
	
	切换至紧急救援模式: systemctl  rescue
	切换至emergency模式: systemctl  emergency
	

电源管理:

其它常用命令:
	关机: systemctl  halt,  systemctl  poweroff
	重启: systemctl  reboot
	挂起: systemctl  suspend
	快照: systemctl  hibernate 
	快照并挂起: systemctl  hybrid-sleep

3.7、unit配置文件语法说明

  • 文件通常由三部分组成:
    [Unit]:定义与Unit类型无关的通用选项;用于提供unit的描述信息、unit行为及依赖关系等;
    [Service]:与特定类型相关的专用选项;此处为Service类型;还有之前介绍的不同的unit,例如socket,
    [Install]:定义由“systemctl enable”以及"systemctl disable“命令在实现服务启用或禁用时用到的一些选项;

  • 配置文件摘要说明:
    /etc/systemd/system:系统管理员和用户使用
    /usr/lib/systemd/system:发行版打包者使用
    unit文件中以 “#” 开头的行后面的内容会被认为是注释,
    相关布尔值,1、yes、on、true 都是开启,0、no、off、false 都是关闭
    时间单位默认是秒,所以要用毫秒(ms)分钟(m)等须显式说明
    对于新创建的unit文件或修改了的unit文件,要通知systemd重载此配置文件:systemctl daemon-reload

  • 以服务的unit文件常用语法进行说明

(1) Unit段的常用选项:
	Description:描述信息; 意义性描述;
	Documentation:服务的启动文件和配置文件;
	Before:如果该字段指定的Unit也要启动,那么必须在当前Unit之后启动;
	After:定义unit的启动次序;表示当前unit应该晚于哪些unit启动;其功能与Before相反;
	Requies:依赖到的其它units;强依赖,被依赖的units无法激活时,当前unit即无法激活;
	Wants:依赖到的其它units;弱依赖;
	BindsTo:与Requires类似,它指定的Unit如果退出,会导致当前Unit停止运行;
	Conflicts:定义units间的冲突关系;
	Condition...:当前Unit运行必须满足的条件,否则不会运行;
	Assert...:当前Unit运行必须满足的条件,否则会报启动失败;
	
(2) Service段的常用选项:
	Type:用于定义影响ExecStart及相关参数的功能的unit进程启动类型;
		类型:
			simple:表示这个服务主要由ExecStart设置的程序来启动,启动后常驻在内存中;
			forking:表示由ExecStart指定的启动的程序通过spawns产生子进程提供服务,然后父进程退出;
			oneshot:oneshot表示的含义与simple类似,不过这个程序在工作完毕后就结束了,不会常驻在内存中;
			dbus:dbus也与simple类似,但这个服务必须要在取得D-Bus的名称后,才会继续运行!因此通常设置值为这个,也要设置BusName=才行;
			notify:notify也与simple类似,但这个服务必须要收到一个sd_notify()函数发送的消息后,才会继续进行;
			idle:idle与simple类似,意思是,要执行这个服务必须要所有的工作都顺利执行完毕后才会执行。这类的服务通常是开机到最后才执行即可得服务。
	EnvironmentFile:环境配置文件;
	ExecStart:指明启动unit要运行命令或脚本; 
	ExecStartPre:指明启动unit前要运行的命令或脚本;
	ExecStartPost:指明启动unit后要运行的命令或脚本;
	ExecReload:指明重新加载unit时要运行的命令或脚本;
	ExecStop:指明停止unit要运行的命令或脚本;
	ExecStopPost:停止unit后要运行的命令或脚本;
	RestartSec:自动重启当unit时运行的时间;
	Restart:定义何种情况Systemd会自动重启当前unit,可能的值包括always(总是重启)、on-success、on-failure、on-abnormal、on-abort、on-watchdog
	TimeoutSec:定义Systemd停止当前unit之前等待的秒数;
	Environment:指定环境变量;
	User:设置创建目录时的用户属主;
	Group:设置创建目录时的用户属组;
	RuntimeDirectory:用来设置守护进程在运行时候需要创建的目录名字
	RuntimeDirectoryMode:用来设置创建的目录的权限;
	
(3) Install段的常用选项:
	Alias:当前Unit可用于启动的别名;
	Also:当前Unit激活(enable)时,会被同时激活的其他Unit;
	RequiredBy:被哪些units所依赖,它的值是一个或多个Target,当前Unit激活时,符号链接会放入/etc/systemd/system目录下面以Target名加 .required后缀构成的子目录中;
	WantedBy:被哪些units所依赖, 它的值是一个或多个Target,当前Unit激活时(enable)时,符号链接会放入/etc/systemd/system目录下面以Target名加 .wants后缀构成的子目录中;

给出一个redis的unit文件的示例说明:

[root@node1 ~]# cat /usr/lib/systemd/system/redis.service
[Unit] #固定格式,表示这是一个Unit文件  
#Description定义描述新,对该服务进行描述,这里描述信息意义是Redis是一个持#久存储的键值数据库
Description=Redis persistent key-value database
#After定义uni的启动次序。表示当前unit应该晚于哪些unit启动,其功能与Before
#相反,这里定义了After两行,表示redis.service要在network.target这个运行级别以及networ-online.target这个运行级别启动后再启动redis.service
After=network.target
After=network-online.target
#Wants定义了该unit依赖到的其他units,不过Wants指定的依赖于Requires指定#的依赖不一样,Requires指定依赖(这里没有)units无法激活时,当前unit也无法激
#活,而Wants指定的依赖属于弱依赖,可能依赖的unit无法激活时,该unit可以
#被激活。这里定义弱依赖于network-online.target
Wants=network-online.target

[Service] #定义Service类型的配置段,服务说明的固定写法
#ExecStart指明启动unit要运行的命令或脚本。这里就是调用redis-server指定配置
#文件/etc/redis.conf,--supervised systemd表示托管给systemd管理,可以省略。这
#里启动脚本不支持base的一些特殊字符,如果需要,请写入对应的脚本,然后调#用。
ExecStart=/usr/bin/redis-server /etc/redis.conf --supervised systemd
#ExecStop 指明停止unit要运行的命令或脚本,可以看到调用的是rpm提供的
#bash 脚本 /usr/libexec/redis-shutdown
ExecStop=/usr/libexec/redis-shutdown
#Type用于定义影响ExecStart及相关参数的功能的unit进程启动类型,常见的类型#有simple,forking,oneshot,dbus,notify,idle。simple是默认值,如果不通过
#Type指明。simple表示这个服务主要由ExecStart设置的程序来启动,启动后常驻
#在内存中;forking表示由ExecStart指定的启动的程序通过spawns产生子进程提
#供服务,然后父进程退出;oneshot表示的含义与simple类似,不过这个程序在工
#作完毕后就结束了,不会常驻在内存中;dbus也与simple类似,但这个服务必须
#要在取得D-Bus的名称后,才会继续运行!因此通常设置值为这个,也要设置
#BusName=才行;notify也与simple类似,但这个服务必须要收到一个sd_notify()
#函数发送的消息后,才会继续进行;idle与simple类似,意思是,要执行这个服
#务必须要所有的工作都顺利执行完毕后才会执行。这类的服务通常是开机到最后
#才执行即可得服务。
Type=notify
#User和Group分别设置服务进程运行的用户和组;(具体请参考:man systemd.exe)
User=redis
Group=redis
#RuntimeDirectory用来设置守护进程在运行时候需要创建的目录名字,通常位于/run(有个链接目录/var/run)下,这个参数指定的名字只能是一个相对目录,通常是一个名字的字符串。进程如果停止,这个目录也会被删除。对于一些非特权用户启动的守护进程,该配置很有用。创建的目录的权限,通过RuntimeDirectoryMode来指定,用户属主和属组通过User=和Group=来设定,如果不指定Group=,默认取User=指向的用户名作为属组。这里只能简单的描述,而且也没有我写的这么简单,更多详情,请参考man 5 systemd.exec 和 man 5 tmpfiles.d。比如我们这里设定的RuntimeDirectory=redis,RuntimeDirectoryMode=0755,User=redis,Group=redis,我们的redis服务在启动的时候,会在/var/run/目录下创建名为redis的目录,用户属主为redis,用户属组为redis,权限为755。服务停止的时候,这个目录会被删除。
RuntimeDirectory=redis
RuntimeDirectoryMode=0755

[Install]  #这部分是固定写法,定义服务器启用和停用的时候的一些配置选项
#WantedBy定义该units被哪些units所依赖,这里是定义的被multi-user.target所依#赖,而multi-user.target表示多用户运行级别(2,3,4).所以表示在运行级别为2,3,4的#情况下,redis这个服务启动;
WantedBy=multi-user.target

[root@node1 ~]#

3.8、对于编译安装的应用程序如何找到对应的unit配置模板

() nginx 编译安装并配置unit实现开机自启动

第一部分:如何获取nginx的unit文件模板

可以去对应渠道(官网,开源社区,光盘等)找到对应的rpm包,然后把rpm包提取出来,最后获取rpm包中的nginx
的unit模板文件;关于如何获取nginx官网的rpm包,请参考我之前写的相关笔记:
https://blog.csdn.net/u012271055/article/details/84105825

这里以epel元的repo,然后通过yum下载rpm包:
>实验环境
[root@localhost ~]# cat /etc/redhat-release 
CentOS Linux release 7.5.1804 (Core) 
[root@localhost ~]# uname -a
Linux localhost.localdomain 3.10.0-862.el7.x86_64 #1 SMP Fri Apr 20 16:44:24 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
>配置epel的yum客户端的配置文件
yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
省略......
配置好后,可以通过yum repolist查看是否有epel了。

>只下载软件包,不安装
yum install --downloadonly nginx
切换到缓存目录:
cd /var/cache/yum/
cd ./x86_64/7/epel/packages
[root@localhost packages]# pwd
/var/cache/yum/x86_64/7/epel/packages   #这是就是本地yum缓存的从epel仓库下载的nginx的软件包
[root@localhost packages]# ls
lyx-fonts-2.2.3-1.el7.noarch.rpm              nginx-mod-http-image-filter-1.12.2-2.el7.x86_64.rpm
nginx-1.12.2-2.el7.x86_64.rpm                 nginx-mod-http-perl-1.12.2-2.el7.x86_64.rpm
nginx-all-modules-1.12.2-2.el7.noarch.rpm     nginx-mod-http-xslt-filter-1.12.2-2.el7.x86_64.rpm
nginx-filesystem-1.12.2-2.el7.noarch.rpm      nginx-mod-mail-1.12.2-2.el7.x86_64.rpm
nginx-mod-http-geoip-1.12.2-2.el7.x86_64.rpm  nginx-mod-stream-1.12.2-2.el7.x86_64.rpm

>拷贝nginx主包到指定目录展开
[root@localhost packages]# mkdir /tmp/nginx
[root@localhost packages]# cp nginx-1.12.2-2.el7.x86_64.rpm /tmp/nginx/
[root@localhost packages]# cd /tmp/nginx/
[root@localhost nginx]# rpm2cpio nginx-1.12.2-2.el7.x86_64.rpm | cpio -div
./etc/logrotate.d/nginx
./etc/nginx/fastcgi.conf
./etc/nginx/fastcgi.conf.default
./etc/nginx/fastcgi_params
./etc/nginx/fastcgi_params.default
./etc/nginx/koi-utf
./etc/nginx/koi-win
./etc/nginx/mime.types
./etc/nginx/mime.types.default
./etc/nginx/nginx.conf
./etc/nginx/nginx.conf.default
./etc/nginx/scgi_params
./etc/nginx/scgi_params.default
./etc/nginx/uwsgi_params
./etc/nginx/uwsgi_params.default
./etc/nginx/win-utf
./usr/bin/nginx-upgrade
./usr/lib/systemd/system/nginx.service
./usr/lib64/nginx/modules
./usr/sbin/nginx
./usr/share/doc/nginx-1.12.2
./usr/share/doc/nginx-1.12.2/CHANGES
./usr/share/doc/nginx-1.12.2/README
./usr/share/doc/nginx-1.12.2/README.dynamic
./usr/share/doc/nginx-1.12.2/UPGRADE-NOTES-1.6-to-1.10
./usr/share/licenses/nginx-1.12.2
./usr/share/licenses/nginx-1.12.2/LICENSE
./usr/share/man/man3/nginx.3pm.gz
./usr/share/man/man8/nginx-upgrade.8.gz
./usr/share/man/man8/nginx.8.gz
./usr/share/nginx/html/404.html
./usr/share/nginx/html/50x.html
./usr/share/nginx/html/index.html
./usr/share/nginx/html/nginx-logo.png
./usr/share/nginx/html/poweredby.png
./usr/share/vim/vimfiles/ftdetect/nginx.vim
./usr/share/vim/vimfiles/indent/nginx.vim
./usr/share/vim/vimfiles/syntax/nginx.vim
./var/lib/nginx
./var/lib/nginx/tmp
./var/log/nginx
3088 blocks
rpm包的unit文件目录:
[root@localhost nginx]# ls -l usr/lib/systemd/system/nginx.service 
-rw-r--r--. 1 root root 618 Nov 25 22:39 usr/lib/systemd/system/nginx.service
其内容如下:
[root@localhost nginx]# cat usr/lib/systemd/system/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target

第二部分:(引用之前的比较简要说明编译步骤)

编译安装nginx的步骤,之前的笔记链接:
https://blog.csdn.net/u012271055/article/details/84291170

大概步骤:
#安装一些依赖库和组件
yum -y install autoconf automake gcc gcc-c++ zlib-devel zlib openssl-devel openssl pcre-devel pcre gd-devel gd libxml2-devel libxml2 libxslt-devel libxslt perl-devel perl-ExtUtils-Embed libatomic_ops-devel

#其中的Install_Dir变量可以设置成自己要想要安装路径。比如我这里设置
Install_Dir=/data/application
mkdir -pv $Install_Dir

#创建用户和组
groupadd nginx
useradd -M -s /sbin/nologin -g nginx nginx

#创建一些目录
mkdir -p ${Install_Dir}/nginx/client_body
mkdir -p ${Install_Dir}/nginx/proxy
mkdir -p ${Install_Dir}/nginx/uwsgi
mkdir -p ${Install_Dir}/nginx/fastcgi
mkdir -p ${Install_Dir}/nginx/scgi
mkdir -p /etc/nginx
mkdir -p /var/log/nginx
mkdir -p /var/run/nginx
mkdir -p /var/lock/nginx

#一份编译参考配置
./configure \
--prefix=${Install_Dir}/nginx \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx/nginx.lock \
--user=nginx \
--group=nginx \
--with-select_module \
--with-poll_module \
--with-threads \
--with-file-aio \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-http_stub_status_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_auth_request_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_degradation_module \
--with-http_slice_module \
--with-http_stub_status_module \
--with-http_perl_module=dynamic \
--with-mail=dynamic \
--with-mail_ssl_module \
--with-stream=dynamic \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-stream_ssl_preread_module \
--with-pcre \
--with-libatomic \
--http-client-body-temp-path=${Install_Dir}/nginx/client_body/ \
--http-proxy-temp-path=${Install_Dir}/nginx/proxy/ \
--http-fastcgi-temp-path=${Install_Dir}/nginx/fastcgi/ \
--http-uwsgi-temp-path=${Install_Dir}/nginx/uwsgi \
--http-scgi-temp-path=${Install_Dir}/nginx/scgi
make && make install

编译后目录查看:
[root@www sbin]# ls -l /data/application/nginx/
total 0
drwxr-xr-x 2 root root   6 Nov 26 00:15 client_body
drwxr-xr-x 2 root root 333 Nov 26 00:18 conf
drwxr-xr-x 2 root root   6 Nov 26 00:15 fastcgi
drwxr-xr-x 2 root root  40 Nov 26 00:18 html
drwxr-xr-x 2 root root 168 Nov 26 00:18 modules
drwxr-xr-x 2 root root   6 Nov 26 00:15 proxy
drwxr-xr-x 2 root root  19 Nov 26 00:18 sbin
drwxr-xr-x 2 root root   6 Nov 26 00:15 scgi
drwxr-xr-x 2 root root   6 Nov 26 00:15 uwsgi

第三部分:配置nginx的unit测试

unit模板文件:
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target

根据实际环境修改后:
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
#PIDFile=/run/nginx.pid
PIDFile=/var/run/nginx/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
#ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStartPre=/usr/bin/rm -f /var/run/nginx/nginx.pid
ExecStartPre=/data/application/nginx/sbin/nginx -t
ExecStart=/data/application/nginx/sbin/nginx -c /data/application/nginx/conf/nginx.conf
ExecReload=/usr/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target

[Install]
WantedBy=multi-user.target
#这里就大概配置一下,实际生产还要微调整以及配置对应的日志目录,切割脚本,运行进程目录,做好软链接等。
测试nginx的unit:
<1> 修改配置文件,指向pid位置为/var/run/nginx/
vim /data/application/nginx/conf/nginx.conf
pid         /var/run/nginx/nginx.pid;
<2> 启动
[root@www system]# systemctl start nginx.service
[root@www system]# ss -nltu
Netid State      Recv-Q Send-Q                   Local Address:Port                                  Peer Address:Port              
tcp   LISTEN     0      128                                  *:80                                               *:*                  
tcp   LISTEN     0      128                                  *:22                                               *:*                  
tcp   LISTEN     0      100                          127.0.0.1:25                                               *:*                  
tcp   LISTEN     0      128                                 :::22                                              :::*                  
tcp   LISTEN     0      100                                ::1:25                                              :::*                  
[root@www system]# ps aux|grep nginx
root       1567  0.0  0.2  46108  1148 ?        Ss   00:44   0:00 nginx: master process /data/application/nginx/sbin/nginx -c /data/application/nginx/conf/nginx.conf
nginx      1568  0.0  0.3  46576  1924 ?        S    00:44   0:00 nginx: worker process
root       1571  0.0  0.2 112704   972 pts/0    R+   00:44   0:00 grep --color=auto nginx
<3> 查看状态
[root@www system]# systemctl status nginx.service
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: active (running) since Mon 2018-11-26 00:44:23 CST; 19s ago
  Process: 1565 ExecStart=/data/application/nginx/sbin/nginx -c /data/application/nginx/conf/nginx.conf (code=exited, status=0/SUCCESS)
  Process: 1563 ExecStartPre=/data/application/nginx/sbin/nginx -t (code=exited, status=0/SUCCESS)
  Process: 1561 ExecStartPre=/usr/bin/rm -f /var/run/nginx/nginx.pid (code=exited, status=0/SUCCESS)
 Main PID: 1567 (nginx)
   CGroup: /system.slice/nginx.service
           ├─1567 nginx: master process /data/application/nginx/sbin/nginx -c /data/application/nginx/conf/nginx.conf
           └─1568 nginx: worker process

Nov 26 00:44:23 www.example.com systemd[1]: Starting The nginx HTTP and reverse proxy server...
Nov 26 00:44:23 www.example.com nginx[1563]: nginx: the configuration file /data/application/nginx/conf/nginx.conf syntax is ok
Nov 26 00:44:23 www.example.com nginx[1563]: nginx: configuration file /data/application/nginx/conf/nginx.conf test is successful
Nov 26 00:44:23 www.example.com systemd[1]: Started The nginx HTTP and reverse proxy server.
<4> 停止
[root@www system]# systemctl stop nginx.service
[root@www system]# ss -nltu
Netid State      Recv-Q Send-Q                   Local Address:Port                                  Peer Address:Port              
tcp   LISTEN     0      128                                  *:22                                               *:*                  
tcp   LISTEN     0      100                          127.0.0.1:25                                               *:*                  
tcp   LISTEN     0      128                                 :::22                                              :::*                  
tcp   LISTEN     0      100                                ::1:25                                              :::*    
<5>开机启动和开机不启动设置
[root@www system]# systemctl enable nginx.service
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
[root@www system]# systemctl status nginx.service
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: inactive (dead)

Nov 26 00:42:44 www.example.com nginx[1537]: nginx: configuration file /data/application/nginx/conf/nginx.conf test is successful
Nov 26 00:42:44 www.example.com systemd[1]: Started The nginx HTTP and reverse proxy server.
Nov 26 00:44:19 www.example.com systemd[1]: Stopping The nginx HTTP and reverse proxy server...
Nov 26 00:44:19 www.example.com systemd[1]: Stopped The nginx HTTP and reverse proxy server.
Nov 26 00:44:23 www.example.com systemd[1]: Starting The nginx HTTP and reverse proxy server...
Nov 26 00:44:23 www.example.com nginx[1563]: nginx: the configuration file /data/application/nginx/conf/nginx.conf syntax is ok
Nov 26 00:44:23 www.example.com nginx[1563]: nginx: configuration file /data/application/nginx/conf/nginx.conf test is successful
Nov 26 00:44:23 www.example.com systemd[1]: Started The nginx HTTP and reverse proxy server.
Nov 26 00:44:53 www.example.com systemd[1]: Stopping The nginx HTTP and reverse proxy server...
Nov 26 00:44:53 www.example.com systemd[1]: Stopped The nginx HTTP and reverse proxy server.
[root@www system]# systemctl disable nginx.service
Removed symlink /etc/systemd/system/multi-user.target.wants/nginx.service.
[root@www system]# systemctl status nginx.service
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: inactive (dead)

Nov 26 00:42:44 www.example.com nginx[1537]: nginx: configuration file /data/application/nginx/conf/nginx.conf test is successful
Nov 26 00:42:44 www.example.com systemd[1]: Started The nginx HTTP and reverse proxy server.
Nov 26 00:44:19 www.example.com systemd[1]: Stopping The nginx HTTP and reverse proxy server...
Nov 26 00:44:19 www.example.com systemd[1]: Stopped The nginx HTTP and reverse proxy server.
Nov 26 00:44:23 www.example.com systemd[1]: Starting The nginx HTTP and reverse proxy server...
Nov 26 00:44:23 www.example.com nginx[1563]: nginx: the configuration file /data/application/nginx/conf/nginx.conf syntax is ok
Nov 26 00:44:23 www.example.com nginx[1563]: nginx: configuration file /data/application/nginx/conf/nginx.conf test is successful
Nov 26 00:44:23 www.example.com systemd[1]: Started The nginx HTTP and reverse proxy server.
Nov 26 00:44:53 www.example.com systemd[1]: Stopping The nginx HTTP and reverse proxy server...
Nov 26 00:44:53 www.example.com systemd[1]: Stopped The nginx HTTP and reverse proxy server.

(2) httpd2.4编译安装并配置unit实现开机自启动
第一部分:获取光盘中的rpm包并提取文件

[root@localhost ~]# yum install --downloadonly httpd
[root@localhost 7]# ls -l updates/packages/httpd-2.4.6-80.el7.centos.1.x86_64.rpm 
-rw-r--r--. 1 root root 2843116 Jul  3 22:31 updates/packages/httpd-2.4.6-80.el7.centos.1.x86_64.rpm
[root@localhost 7]# pwd
/var/cache/yum/x86_64/7
[root@localhost 7]# mkdir /tmp/http24
[root@localhost 7]# cp updates/packages/httpd-2.4.6-80.el7.centos.1.x86_64.rpm /tmp/http24/
[root@localhost 7]# cd /tmp/http24/
[root@localhost http24]# rpm2cpio httpd-2.4.6-80.el7.centos.1.x86_64.rpm | cpio -div
[root@localhost http24]# ls -l usr/lib/systemd/system/httpd.service 
-rw-r--r--. 1 root root 752 Nov 25 22:43 usr/lib/systemd/system/httpd.service
[root@localhost http24]# cat usr/lib/systemd/system/httpd.service
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)

[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
KillSignal=SIGCONT
PrivateTmp=true

[Install]
WantedBy=multi-user.target

第二部分:编译安装httpd2.4

(1) 安装依赖软件包
yum -y install gcc gcc-c++ autoconf libtool openssl-devel zlib-devel pcre-devel gzip-devel bzip2-devel libmcrypt-deve libaio-devel libxml2-devel bzip2 expat-devel
 

(2) 创建用户和组,以及编译安装目录
useradd -M -s /bin/true apache
[root@localhost ~]# useradd -M -s /bin/true apache
[root@localhost ~]# id apache
uid=1001(apache) gid=1001(apache) groups=1001(apache)

[root@localhost ~]# install_path=/data/application
[root@localhost ~]# mkdir -pv $install_path
mkdir: created directory ‘/data’
mkdir: created directory ‘/data/application’

(4) 软件包位置说明和展开
[root@localhost opt]# ls /opt/
apr-1.6.5.tar.bz2  apr-util-1.6.1.tar.bz2  httpd-2.4.37.tar.bz2
[root@localhost opt]# ls
apr-1.6.5.tar.bz2  apr-util-1.6.1.tar.bz2  httpd-2.4.37.tar.bz2
[root@localhost opt]# tar -xf apr-1.6.5.tar.bz2 
[root@localhost opt]# echo $?
0
[root@localhost opt]# tar -xf apr-util-1.6.1.tar.bz2 
[root@localhost opt]# echo $?
0
[root@localhost opt]# tar -xf httpd-2.4.37.tar.bz2 
[root@localhost opt]# echo $?
0
[root@localhost opt]# ls
apr-1.6.5  apr-1.6.5.tar.bz2  apr-util-1.6.1  apr-util-1.6.1.tar.bz2  httpd-2.4.37  httpd-2.4.37.tar.bz2

(5) 创建目录
mkdir -p /var/log/apache
chown -R apache:apache /var/log/apache
chmod -R 755 /var/log/apache

(3) 编译安装apr (要求大于1.4版本以上)
cd /opt/apr-1.6.5
sed -i '/$RM "$cfgfile"/s/^/#/' configure
./configure --prefix=${install_path}/apr-1.6.5
make
make install
ln -sf ${install_path}/apr-1.6.5 ${install_path}/apr

(4) 编译安装apr-utils
cd /opt/apr-util-1.6.1
./configure --prefix=${install_path}/apr-util-1.6.1 --with-apr=${install_path}/apr 
make
make install
ln -sf ${install_path}/apr-util-1.6.1 ${install_path}/apr-util

(5) 编译安装httpd2.4
cd /opt/httpd-2.4.37
./configure \
--prefix=${install_path}/httpd-2.4.25 \
--with-apr=${install_path}/apr \
--with-apr-util=${install_path}/apr-util \
--sysconfdir=/etc/httpd \
--enable-so \
--enable-cgi \
--enable-cgid \
--enable-deflate \
--enable-expires \
--enable-headers \
--enable-ssl \
--enable-rewrite \
--enable-mpms-shared=all \
--enable-modules=most \
--enable-mods-shared=most \
--with-mpm=worker
make
make install
ln -sf ${install_path}/httpd-2.4.25 ${install_path}/httpd24

第三部分:配置httpd2.4的unit测试

配置unit的模板httpd.service内容为:
[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
KillSignal=SIGCONT
PrivateTmp=true

[Install]
WantedBy=multi-user.target

根据实际编译安装后的路径修改最终的unit文件内容为:
[root@www system]# cat httpd.service 
[Unit]
Description=The Apache's httpd project
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
EnvironmentFile=/etc/httpd/httpd.conf
ExecStart=/data/application/httpd24/bin/httpd -k start -DFOREGROUND
ExecReload=/data/application/httpd24/bin/httpd -k graceful 
ExecStop=/usr/bin/kill -WINCH ${MAINPID}

[Install]
WantedBy=multi-user.target

编辑主配置文件,修改进程运行用户和属组,以及添加一行:
vim /etc/httpd/httpd.conf
把
User daemon
Group daemon
改成
User apache
Group apache
添加:
ServerName  www.example.com
然后/etc/hosts文件加一条解析:
192.168.56.78 www.example.com #这个ip是我的ip地址

测试启动:
<1> 载入systemd的配置
systemctl daemon-reload
<2> 启动测试
[root@www system]# systemctl start httpd.service
[root@www system]# ss -nltu
Netid State      Recv-Q Send-Q                   Local Address:Port                                  Peer Address:Port              
udp   UNCONN     0      0                                    *:123                                              *:*                  
udp   UNCONN     0      0                                   :::123                                             :::*                  
tcp   LISTEN     0      128                                  *:22                                               *:*                  
tcp   LISTEN     0      100                          127.0.0.1:25                                               *:*                  
tcp   LISTEN     0      128                                 :::80                                              :::*                  
tcp   LISTEN     0      128                                 :::22                                              :::*                  
tcp   LISTEN     0      100                                ::1:25                                              :::*                  
[root@www system]# ps aux|grep httpd
root       1303  0.1  0.6  73064  2920 ?        Ss   08:04   0:00 /data/application/httpd24/bin/httpd -k start -DFOREGROUND
apache     1304  0.0  0.4 362028  2160 ?        Sl   08:04   0:00 /data/application/httpd24/bin/httpd -k start -DFOREGROUND
apache     1305  0.0  0.4 362028  2116 ?        Sl   08:04   0:00 /data/application/httpd24/bin/httpd -k start -DFOREGROUND
apache     1306  0.0  0.4 427564  2116 ?        Sl   08:04   0:00 /data/application/httpd24/bin/httpd -k start -DFOREGROUND
root       1400  0.0  0.2 112704   972 pts/0    S+   08:05   0:00 grep --color=auto httpd

<3>查看状态:
[root@www system]# systemctl status httpd.service
● httpd.service - The Apache's httpd project
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: active (running) since Mon 2018-11-26 08:04:58 CST; 7h left
 Main PID: 1303 (httpd)
   CGroup: /system.slice/httpd.service
           ├─1303 /data/application/httpd24/bin/httpd -k start -DFOREGROUND
           ├─1304 /data/application/httpd24/bin/httpd -k start -DFOREGROUND
           ├─1305 /data/application/httpd24/bin/httpd -k start -DFOREGROUND
           └─1306 /data/application/httpd24/bin/httpd -k start -DFOREGROUND

Nov 26 08:04:58 www.example.com systemd[1]: Started The Apache's httpd project.
Nov 26 08:04:58 www.example.com systemd[1]: Starting The Apache's httpd project...

<4>防火墙添加允许http服务,然后设置selinux为非enforcing
[root@localhost ~]# setenforce 0
setenforce: SELinux is disabled #因为我已经把selinux关闭了,所以这个命令设置不了
[root@www ~]# firewall-cmd --add-service=http --permanent
success
[root@www ~]# firewall-cmd --add-service=http
success
[root@www ~]# firewall-cmd --list-service --permanent
ssh dhcpv6-client http
[root@www ~]# firewall-cmd --list-service
ssh dhcpv6-client http

<5>另一台主机访问测试
[root@localhost ~]# curl -I http://192.168.56.78/index.html
HTTP/1.1 200 OK
Date: Sun, 25 Nov 2018 16:11:09 GMT
Server: Apache/2.4.37 (Unix)
Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT
ETag: "2d-432a5e4a73a80"
Accept-Ranges: bytes
Content-Length: 45
Content-Type: text/html
[root@localhost ~]# curl http://192.168.56.78/index.html
<html><body><h1>It works!</h1></body></html>

<6> 开启自启和状态查看
[root@www ~]# systemctl stop httpd.service
[root@www ~]# systemctl enable httpd.service
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
[root@www ~]# systemctl status httpd.service
● httpd.service - The Apache's httpd project
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: inactive (dead)

Nov 26 08:00:24 www.example.com systemd[1]: Started The Apache's httpd project.
Nov 26 08:00:24 www.example.com systemd[1]: Starting The Apache's httpd project...
Nov 26 08:04:01 www.example.com systemd[1]: Stopping The Apache's httpd project...
Nov 26 08:04:02 www.example.com systemd[1]: Stopped The Apache's httpd project.
Nov 26 08:04:58 www.example.com systemd[1]: Started The Apache's httpd project.
Nov 26 08:04:58 www.example.com systemd[1]: Starting The Apache's httpd project...
Nov 26 00:12:15 www.example.com systemd[1]: Stopping The Apache's httpd project...
Nov 26 00:12:15 www.example.com systemd[1]: Stopped The Apache's httpd project.
[root@www ~]# systemctl disable httpd.service
Removed symlink /etc/systemd/system/multi-user.target.wants/httpd.service.

猜你喜欢

转载自blog.csdn.net/u012271055/article/details/84491365