城乡建设部网站甘红刚,创意家居网站建设与管理,提升网站流量该怎么做,网站建设对于企业的重要性背景#xff1a;
最近对所有项目完成了一个切换#xff0c;服务管理方式由#xff1a; init- systemd。对相关知识进行总结一下。
1.启动流程
服务器的整体启动流程如下图所示#xff1a; POST#xff1a; 计算机通电后进行POST( Power-On Self-Test )加电自检
最近对所有项目完成了一个切换服务管理方式由 init- systemd。对相关知识进行总结一下。
1.启动流程
服务器的整体启动流程如下图所示 POST 计算机通电后进行POST( Power-On Self-Test )加电自检检查 CPU、内存、硬盘、显卡、声卡、网卡等硬件是否正常工作; 检查完成后触发BIOS程序(来自主板)。
BIOS BIOS程序( Basic Input Output System )来自主板被执行后会拥有整个裸机的执行权。BIOS会做以下几件事 (1) 对硬件设置的检查和初始化 (2) 加载MBR并执行。BIOS加载启动盘的第一个扇区(0盘/0道/0扇区)将扇区的所有内容复制到内存中并执行(将CPU的指令寄存器指向该内存)。 说明: (1) CPU被设计只能从内存中取数据和指令启动过程中涉及的程序(保存在硬件中)都需要在执行前预先被加载到内存。(2) 在机器启动时按F2(dell服务器)可以进入BIOS。在BIOS的启动选项菜单中可以选择引导设备使用CD或者U盘安装系统时将其作为首选引导设备安装完成后会自动弹出CD重启服务器即可。如果把CD推入重启会再走安装流程(安装完最好把它取出来)。
MBR MBR(Master Boot Record)表示硬盘的主引导记录它位于第一个扇区(0盘/0道/0扇区)。MBR大小为512字节包含446字节的引导加载程序(主boot-loader)、64字节的分区表信息、2字节的结束标志(0xAA55)。 主boot loader的唯一任务是加载次boot-loader(内核加载程序)。加载过程分为了主/次boot-loader两个加载器因为512字节不足以完成将操作系统加载内核到内存的工作。
加载操作系统内核: 内核加载程序(grub/grub2)主要负责启动操作系统和加载内核。centos6(及以前)使用grub, 而centos7默认使用grub2。 说明计算机上安装多个系统时在grub/grub2阶段可以与用户交互选择要加载的操作系统。 至此计算机完全由操作系统接管。
init/systemd: 内核加载完成后会启动第一个进程init/systemd. 在centos6及以前使用init进程管理服务centos7及以后使用systemd守护进行管理服务。init/systemd会加载和运行其他的系统进程。 至此开机启动完成。
2.init进程
2.1 Linux系统的运行级别
0-关机状态: 执行init 0会关闭计算机;
1-单用户模式只支持root用户不支持远程登录一般用于系统维护
2-多用户模式支持多用户不支持远程登录。
3-多用户-NFS支持多用户支持远程登录。
4-保留;
5-图形化(多用户、远程登录、支持图形化界面);
6-重启;可以通过 init 运行级别 实现系统运行级别的切换。
2.2 init进程的启动过程
(1) init进程从配置文件/etc/inittab中读取运行级别根据运行级别来确定启动的程序。在CentOS 6中默认的运行级别是运行级别3。 可以通过runlevel查看当前系统的运行级别
runlevel
N 5(2) 启动子进程 对每个运行级别在/etc/rc.d文件夹都有一个文件夹:rc0.d ~ rc6.d。比如当运行级别是5时rc3.d目录下的配置文件生效。包含如下文件 文件名格式为K/S 数字 服务名。K表示停止进程(Kill), S表示启动进程(Start); 数字表示运行级别数字越小执行越靠前。 此时init进程会拉起network进程。
为防止在各个级别下(各个rcN.d目录下)都存放重复的文件使用链接的形式引用。目录下的所有链接文件会指向/etc/init.d/目录下的脚本。当运行级别进行切换时会给这些脚本进行传参start或stop. 因此需要安装模板规定开发服务脚本, 如下所示
#! /bin/sh
# 准备操作SERVER_NAMEdemostart(){echo -e \nStart ${SERVER_NAME}...#todo: 启动逻辑echo -e \nStart ${SERVER_NAME} success!
}stop(){echo -e \nShutdown ${SERVER_NAME}...#todo: 停止逻辑echo -e \nShutdown ${SERVER_NAME} finish!
}case $1 inrestart)stopstart;;stop)stop;;start)start;;*)echo parameter error!! ;echo three parameters are valid----restart, start, stop;;
esac(3) init进程根据上述流程创建一系列子进程当系统启动完成后init进程将变成为守护进程监视系统其他进程的运行状态并在需要时重新启动它们。
2.3 常用API
添加服务
chkconfig --add ${servicename}删除服务
chkconfig --del ${servicename}查看所有的系统服务
chkconfig --list#查看指定服务信息
chkconfig --list ${servicename}设置服务的运行级别
chkconfig --level 运行级别 ${servicename} on/offeg:
设施mysql在运行级别为3和5下开机自启动
chkconfig --level 35 mysqld on2.4 案例介绍
1.在/etc/init.d/目录下新建服务名如ewen 脚本如下所示
#! /bin/shecho $SERVER_NAMEewenstart(){echo -e \nStart ${SERVER_NAME}...echo -e \nStart ${SERVER_NAME} success!
}stop(){echo -e \nShutdown ${SERVER_NAME}...echo -e \nShutdown ${SERVER_NAME} finish!
}case $1 inrestart)stopstart;;stop)stop;;start)start;;*)echo parameter error!! ;echo three parameters are valid----restart, start, stop;;
esac此时在环境上执行service命令时可以将参数带入脚本
service ewen start a1 bc2 333 d4
#输出
start a1 bc2 333 d4
Start ewen...
Start ewen success2.通过chkconfig将ewen服务注册到init:
chkconfig --add ewen3.设置运行级别
chkconfig --level 3 ewen ewen on/off3.systemd进程
init进程因串行化地启动程序存在效率问题且需要自定义脚本; systemd通过并行启动以及通过引入service配置文件规避了上面两个问题。
ini使用service命令systemd使用systemctl工具来管理并且在操作上做了兼容处理(将service指令重定向到systemctl)如下所示:
service ewen stop
Redirecting to /bin/systemctl ewen ota.service在centos7之后(含centos7)使用systemd来管理程序, 通过ls -al /sbin/init 查看链接指向了systemd程序 通过查看/etc/inittab也可以得到提示如下:
通过ps 命令查看systemd的进程号(进程号为1)
3.1 启动流程
(1) 获取运行模式 当systemd进程启动后会读取配置文件确定运行模式。通过/etc/systemd/system/default.target文件链接到/usr/lib/systemd/system/multi-user.target还是/usr/lib/systemd/system/graphical.target确定运行模式。
(2) 获取需要开机启动的服务 以multi-user模式为例系统进入/etc/systemd/system/multi-user.target.wants获取所有配置的服务并启动这些服务。
3.2 service配置文件介绍
3.2.1 文件路径
service配置文件用于自定义服务的启动顺序、运行方式、属组、启动方式等可以将service文件放在 /usr/lib/systemd/[ system | user ]/ 或 /etc/systemd/[ system | user ]/目录下。user表示用户服务开机时不启动服务用户登录后才触发启动服务system表示系统服务开机时启动服务而不需要用户登录。 /usr/lib/systemd/[ system | user ]/ 通常用于存放yum等软件安装的服务包。优先级/etc/systemd/system要高于/usr/lib/systemd/system。 一般而言自定义的服务建议放在/etc/systemd/system目录下。
3.2.2 service文件组成
如下所示是redis服务的service文件:
[Unit]
DescriptionRedis persistent key-value database
Afternetwork.target
Afternetwork-online.target
Wantsnetwork-online.target[Service]
ExecStart/usr/bin/redis-server /etc/redis.conf --supervised systemd
ExecStop/usr/libexec/redis-shutdown
Typenotify
Userredis
Groupredis
RuntimeDirectoryredis
RuntimeDirectoryMode0755[Install]
WantedBymulti-user.target由三个部分组成: [Unit]、[Service]、[Install]以下通过分章节分别进行介绍。
3.2.2.1 service文件的unit部分
unit部分可以定义服务描述、启动顺序和依赖关系。 描述 (1) Descriptionsystemd使用Description描述服务信息(给读者看的一般用一个简单的名称短语即可)。 (2) Documentation: 指定服务的详细说明文档(地址)多个使用空格进行分隔.
依赖关系 (1) Requires/Requisite所依赖的单元必须已经启动多个用都改分隔。 (2) RequiresAny: 指定列表中任意一个已经启动即可。 (3) PartOf关联停止和重启多个用逗号分隔。当被关联的服务停止或启动时该服务也将随着停止和启动。 (4) BindsTo: 设置绑定服务列表多个用逗号分隔。绑定列表中的所有服务被启动后该服务才能被启动绑定列表中的任一服务停止后该服务被迫停止。绑定配置只有单向关系即该服务停止后不会影响列表中服务的状态。 (5) Conflicts: 指定相互冲突的服务多个使用空格分开。该单元启动时Conflicts指定的列表中所有单元都将被停止列表中的某个单元启动时该单元被停止。
启动顺序 systemd不够友好依赖关系并不能保证启动顺序需要用户通过Before和After手动指定。 redis.service文件中通过After指定了在network.target(网络服务)和yslog.target(系统日志服务)之后启动。即系统启动时redis服务要等待network.target和yslog.target启动后才可启动。 可以通过空格进行分隔也可以通过多个After项进行配置(如redis.service)
[Unit]
Afternetwork.target
Aftersyslog.target等价于
[Unit]
Afternetwork.target syslog.targetBefore与After完全相反。
案例介绍 基于上述说明对于不同场景可以有一下组合 case1服务B在服务A之后重启且依赖于服务A
B.service[Unit]
AfterA.servicecase2服务A重启后服务B必须重启
B.service[Unit]
AfterA.service
PartOfA.servicecase3服务C依赖于服务A或B
C.service[Unit]
RequiresAnyA.service B.service
AfterA.service B.servicecase4服务D依赖于服务A和B但是与C处于冲突状态
D.service[Unit]
RequiresA.service B.service
AfterA.service B.service
ConflictsC.service3.2.2.2 service文件的service部分
用于定义服务的类型和属组启停命令和重启机制、环境变量等。 服务类型 鉴于章节篇幅关于simple和forking的详细介绍在章节3.3中进行 Type定义服务类型: simple默认类型使用当前线程作为主进程 forking服务会使用fork创建新进程新进程作为主进程 oneshot一般用于执行一次性任务与simple相似区别在于systemd执行完oneshot类型才会认为该服务执行成功而simple开始执行即认为执行成功。 除此之外还有dbus, notify, idle等类型因在开发过程中很少见这里不进行说明。
服务的属组 User和Group定义服务运行时归属的用户和群组。
启停命令 (1) ExecStart和ExecStop和ExecReload指定启动和停止时执行的命令(含参数) (2) ExecStartPre和ExecStartPost设置ExecStart启动前和启动后执行的命令 (3) ExecStopPost设置停止后执行的命令 (4) ExecReload表示重启服务时执行的命令。
环境变量 Environment用于添加环境变量.
重启策略 Restart和RestartSec用于配置服务重启策略。 (1) RestartSec定义重新启动服务的间隔时间, 单位:秒 (2) Restart服务重启策略 no(默认值)不重启 always总是重新启动 on-success/on-failure分别表示当服务正常退出(exit 0)/异常(exit 1)退出时重启. (3) KillMode设置systemd停止服务的策略 control-group(默认值)kill主进程和所有子进程 none不直接kill主进程或子进程仅执行服务的stop命令 process仅kill主进程 mixed向主进程发送SIGTERM(kill)信号向所有子进程发送SIGKILL(kill -9)信号。 说明: systemd提供了丰富的配置能力可参考 https://www.jinbuguo.com/systemd/systemd.special.html 案例介绍:
[Service]
TypeforkingUserewen
GroupewenExecStart/usr/local/buaa/bin/ewen start
ExecStop/usr/local/buaa/bin/ewen stop
ExecReload/bin/kill -s HUP $MAINPIDEnvironmentEWEN_HOME/usr/local/buaa
#设置该服务可以打开的最大文件数为65535。
LimitNOFILE65535PrivateTmptrue
Restarton-failure
RestartSec10KillModecontrol-group3.2.2.3 service文件的Install部分
通过WantedBy指定开机自启动模式可指定为multi-user.target(多用户模式) 或 graphical.target(界面模式)等。上述的redis.service文件中: WantedBymulti-user.target. 当执行systemctl enable redis[.service]时创建一个链接文件 systemctl enable redis
Created symlink from /etc/systemd/system/multi-user.target.wants/redis.service to /etc/systemd/system/redis.service.当执行systemctl disable redis[.service]时删除该链接文件.
systemd启动时如果是multi-user模式则从/etc/systemd/system/multi-user.target.wants目录中读取service文件并启动从而实现开机自启动graphical模式则从/etc/systemd/system/graphical.target.wants目录下读取。
也可为服务设置多种模式通过空格分开如
[Install]
WantedBymulti-user.target graphical.target3.3 simple和forking服务类型
systemd启动simple和forking类型的服务流程如下图所示 systemd进程启动服务时会fork子进程然后委托这些systemd子进程去启动服务即执行ExecStart配置的指令。 simple和forking对于systemd进程的核心区别在于“谁是我该监管的进程”当启动simple类型的服务时systemd子进程自身作为主进程接受systemd的监管而启动forking类型的服务时systemd子进程将作为中间父进程退出新创建的进程(systemd通过推断确定)作为主进程接受systemd的监管。 案例说明 case1: simple服务类型 上述案例中redis的service部分如下所示
[Service]
ExecStart/usr/bin/redis-server /etc/redis.conf --supervised systemd
ExecStop/usr/libexec/redis-shutdown
Typenotify
Userredis
Groupredis
RuntimeDirectoryredis
RuntimeDirectoryMode0755没有定义Type即使用默认的Typesimple类型。 启动redis后查询进程状态: 此时systemd跟总的主进程就是调用ExecStart指令的进程。该进程启动后systemd就任务该服务启动成功。
case2: forking服务类型 nginx的service配置文件如下所示:
[Unit]
DescriptionThe nginx HTTP and reverse proxy server
Afternetwork-online.target remote-fs.target nss-lookup.target
Wantsnetwork-online.target[Service]
Typeforking
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?id1268621
ExecStartPre/usr/bin/rm -f /run/nginx.pid
ExecStartPre/usr/sbin/nginx -t
ExecStart/usr/sbin/nginx
ExecReload/usr/sbin/nginx -s reload
KillSignalSIGQUIT
TimeoutStopSec5
KillModeprocess
PrivateTmptrue[Install]
WantedBymulti-user.target通过Typeforking指定了服务类型。 启动nginx后查询进程状态: 可以看到systemd实际监控的进程为18412而执行ExecStart指令的进程为18409(中间进程由systemd创建已正常退出)该进程通过forking创建出了18412. 当中间进程退出且新进程生成后systemd任务该服务启动成功。 另外执行ExecStarPre的进程也是systemd创建的子进程。
上述案例的核心在于systemd监控的主进程如果可以梳理清楚以下两种场景simple和forking区别才算真正理解。
场景分析: 场景1: 应当设置为simple的服务被设置为了forking会发生什么现象 场景2: 应当设置为forking的服务被设置为了simple会发生什么现象 这里仅对第一种场景通过案例进行说明, 读者可通过相同方法对第二种进行梳理 # test.service文件
[Unit]
Descriptiontest[Service]
Typeforking
ExecStart/bin/bash -c sleep 60给ExecStart设置的启动指令是sleep 60即进程休眠1分钟。 执行systemctl start test后systemd认为test服务是一个forking类型因此等待这个进程退出(而该进程处于休眠状态不会退出)所以通过systemctl status test查询test服务时一直处于启动中状态: 1分钟后进程退出且没有新的进程被fork出来systemd会认为该服务启动失败: 修改为simple类型后:
# test.service文件
[Unit]
Descriptiontest[Service]
Typesimple
ExecStart/bin/bash -c sleep 60执行systemctl start test后systemd认为simple服务是一个forking类型执行完/bin/bash -c sleep 60指令后systemd认为该服务启动成功: 1分钟后进程退出systemd会认为该服务退出运行:
3.4 systemctl
(1) 运行模式:
#设置graphical运行模式
systemctl set-default graphical.target#设置multi-user运行模式
systemctl set-default multi-user.target#获取运行模式
systemctl get-default设置运行模式的本质就是将/etc/systemd/system/default.target指向/usr/lib/systemd/system/multi-user.target或/usr/lib/systemd/system/graphical.target.
(2) 注册服务 将服务的service文件放到systemd管理的路径比如/etc/systemd/system/目录后指向以下命令进行重新加载
systemctl daemon-reload(3) 启停服务(常用)
#启动服务
systemctl start 服务名[.service]#停止服务
systemctl stop 服务名[.service]#重启服务
systemctl restart 服务名[.service]#查看服务状态
systemctl status 服务名[.service](4) 开机自启动
#开启开机自启动
systemctl enable 服务名[.service]#关闭开机自启动
systemctl disable 服务名[.service]设置开机自启动本质是在/etc/systemd/system/multi-user.target.wants/目录下创建了一个链接文件。