对于CentOS7系列感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍二系统服务配置--单元,并为您提供关于CentOS6.5Varnish缓存服务配置与应用、CentOS7将Nginx添加系统
对于CentOS 7 系列感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍二系统服务配置--单元,并为您提供关于CentOS 6.5 Varnish缓存服务配置与应用、CentOS 7 将 Nginx 添加系统服务、CentOS 7 将 nginx 配置成系统服务、CentOS 7 系列(一)系统服务 systemd的有用信息。
本文目录一览:- CentOS 7 系列(二)系统服务配置--单元(Unit)(centos7服务管理)
- CentOS 6.5 Varnish缓存服务配置与应用
- CentOS 7 将 Nginx 添加系统服务
- CentOS 7 将 nginx 配置成系统服务
- CentOS 7 系列(一)系统服务 systemd
CentOS 7 系列(二)系统服务配置--单元(Unit)(centos7服务管理)
systemd.unit
单元(Unit)
Systemd由一个叫做单元(Unit)的概念,它保存了服务、设备、挂载点和操作系统其他信息的配置文件,并能够处理不同单元之间的依赖关系。大部分单元都静态的定义在单元文件中,也有一些是动态生成的。单元有多种状态:
处于活动的则是(active),当前正在运行
停止的则是(inactive),当前已经停止
启动中的则是(activing),当前正在启动
停止中的则是(deactiving),当前正在停止
失败的则是(Failed)状态,意思说单元启动过程中遇到错误比如找不到文件、路径或者进程运行中崩溃了等。
一共有11种不同类型的单元:
单元类型 | 说明 | |
service单元 | 用于封装一个后台服务进程,比如通过systemctl start firewalld启动防火墙,这种就属于service单元。 | |
socket单元 | target单元 | 用于将多个单元在逻辑上组合在一起让它们同时启动。 |
device单元 | 用于封装一个设备文件,可用于基于设备启动。并不是每一个设备文件都需要一个device单元,但是每一个被udev规则标记的设备都必须作为一个device单元出现。 | |
mount单元 | 用于封装一个文件系统挂载点(向后兼容/etc/fstab) | |
automount单元 | 用于封装一个文件系统自动挂载点,只有该文件系统被访问时才会进行挂载,它取代了传统的autofs服务。 | |
timer单元 | 用于封装一个基于时间触发的动作,它取代了atd、crond等计划任务。 | |
swap单元 | 用于封装一个交换分区或者交换文件,它与mount类似。 | |
path单元 | 用于根据文件系统上特定对象的变化来启动其他服务。 | |
slice单元 | 用于控制特定的CGroup内所有进程的总体资源占有。 | |
scope单元 | 它与service单元类似,但是由systemd根据D-bus接口接收到的信息自动创建,可用于管理外部创建的进程。 |
systemd能够处理各种依赖与冲突关系以及先后顺序,依赖与冲突、先后顺序两者之间是独立的。比如service1依赖service2,而且启动service1必须先启动service2,,那么这2个服务将会同时启动。
说明:一个单元配置文件只能描述一种单元。
系统提供两种级别的单元:
系统单元:在/lib/systemd/system目录中,优先级高于用户单元。
用户单元:在/usr/lib/systemd/system目录中
当systemd以系统实例运行,那么优先级如下:
系统单元目录 | 说明 | 优先级 |
/lib/systemd/system | 本地配置的系统单元 | 高 |
/run/systemd/system | 运行时配置的系统单元 | 中 |
/usr/lib/systemd/system | 软件包安装的系统单元 | 低 |
使用下面的命令可以列出系统所有单元
systemctllist-unit-files
说明:注意单元名称的后缀,可以看出是那一类单元。另外,enabled表示被启用的单元并不是说当前在运行,disabled表示被禁用的单元,至于static则表示不能直接启用,它们是被其他单元所依赖的对象。
如果想要查看某一类型的单元
systemctllist-unit-files--type=类型
如果想要查看当前服务的状态,使用下面的命令,可以看到active表示当前正在运行。
systemctlstatus服务名称
如果某个服务启动不了,你可以通过这个命令看一下启动过程哪里出错了。
单元文件中的布尔值写法:1,yes,true,on表示真;0,no,false,off表示假
单位文件中的时长写法:默认是秒,us(微妙),ms(毫秒),s(秒),min(分钟),h(小时),d(天),w(星期)。
其他约束:空白行或者以“#”或者以“;”开头的都会被忽略,行尾“\”表示续行符,在续行时被替换为一个空格。
[Unit] 段:
这个段在大部分单元文件中都会存在,下面看一下它的配置字段有哪些,红色为常用字段。
字段 | 说明 |
Description= | 对单元进行简单描述的字符串。 用于UI中紧跟单元名称之后的简要描述文字。 例如 "Apache2 Web Server" 就是一个好例子。 不好的例子: "high-performance light-weight HTTP server"(太通用) 或 "Apache2"(信息太少)。 |
Documentation= | 一组用空格分隔的文档URI列表, 这些文档是对此单元的详细说明。 可接受 "http://","https://","file:","info:","man:" 五种URI类型。 有关URI语法的详细说明,参见 uri(7) 手册。 这些URI应该按照相关性由高到低列出。 比如,将解释该单元作用的文档放在第一个, 最好再紧跟单元的配置说明, 最后再附上其他文档。 可以多次使用此选项, 依次向文档列表尾部添加新文档。 但是,如果为此选项设置一个空字符串, 那么表示清空先前已存在的列表。 |
Requires= | 设置此单元所必须依赖的其他单元。 当此单元被启动时,所有这里列出的其他单元也必须被启动。 如果有某个单元未能成功启动,那么此单元也不会被启动。 想要添加多个单元, 可以多次使用此选项, 也可以设置一个空格分隔的单元列表。 注意,此选项并不影响单元之间的启动或停止顺序。 想要调整单元之间的启动或停止顺序, 请使用 After= 或 Before= 选项。 例如,在 foo.service 中设置了 Requires=bar.service 但是并未使用 After= 或 Before= 设定两者的启动顺序, 那么,当需要启动 foo.service 的时候, 这两个单元会被并行的同时启动。 建议使用 Wants= 代替 Requires= 来设置单元之间的非致命依赖关系, 从而有助于获得更好的健壮性, 特别是在某些单元启动失败的时候。 |
Wants= | 此选项是 Requires= 的弱化版。 当此单元被启动时,所有这里列出的其他单元只是尽可能被启动。 但是,即使某些单元不存在或者未能启动成功, 也不会影响此单元的启动。 推荐使用此选项来设置单元之间的依赖关系。 注意,此种依赖关系也可以在单元文件之外通过向 .wants/ 目录中添加软连接来设置, 详见前文 |
BindsTo= | 与 Requires= 类似, 不同之处在于: 如果这里列出的单元停止运行或者崩溃, 那么也会连带导致该单元自身被停止。 这就意味着该单元可能因为 某个单元的主动退出、某个设备被拔出、某个挂载点被卸载, 而被强行停止。 |
PartOf= | 与 Requires= 类似, 不同之处在于:仅作用于单元的停止或重启。 其含义是,当停止或重启这里列出的某个单元时, 也会同时停止或重启该单元自身。 注意,这个依赖是单向的, 该单元自身的停止或重启并不影响这里列出的单元。 |
Conflicts= | 指定单元之间的冲突关系。 接受一个空格分隔的单元列表,表明该单元不能与列表中的任何单元共存, 也就是说:(1)当此单元启动的时候,列表中的所有单元都将被停止; (2)当列表中的某个单元启动的时候,该单元同样也将被停止。 注意,此选项与 After= 和 Before= 选项没有任何关系。 |
Before= After= |
强制指定单元之间的先后顺序。 接受一个空格分隔的单元列表。 假定 foo.service 单元 包含 Before=bar.service 设置, 那么当两个单元都需要启动的时候, bar.service 将会一直延迟到 foo.service 启动完毕之后再启动。 注意,停止顺序与启动顺序正好相反, 也就是说, 只有当 bar.service 完全停止后, 才会停止 foo.service 单元。 After= 的含义 与 Before= 正好相反, 假定 foo.service 单元 包含 After=bar.service 设置, 那么当两个单元都需要启动的时候, foo.service 将会一直延迟到 bar.service 启动完毕之后再启动。 注意,停止顺序与启动顺序正好相反, 也就是说, 只有当 foo.service 完全停止后, 才会停止 bar.service 单元。 注意,此选项仅用于指定先后顺序, 与 Requires= 选项没有任何关系。 不过在实践中也经常遇见 将某个单元同时设置到 After= 与 Requires= 选项中的情形。 可以多次使用此选项, 以将多个单元添加到列表中。 假定两个单元之间存在先后顺序(无论谁先谁后), 并且一个要停止而另一个要启动, 那么永远是"先停止后启动"的顺序。 但如果两个单元之间没有先后顺序, 那么它们的停止和启动就都是相互独立的, 并且是并行的。 |
OnFailure= | 接受一个空格分隔的单元列表。 当该单元进入失败("Failed")状态时, 将会启动列表中的单元。 |
PropagatesReloadTo= ReloadPropagatedFrom= |
接受一个空格分隔的单元列表。 PropagatesReloadTo= 表示 在 reload 该单元时,也同时 reload 所有列表中的单元。 ReloadPropagatedFrom= 表示 在 reload 列表中的某个单元时,也同时 reload 该单元。 |
JoinsNamespaceOf= | 接受一个空格分隔的单元列表, 表示将该单元所启动的进程加入到列表单元的网络及 临时文件(/tmp,/var/tmp) 的名字空间中。 如果单元列表中仅有一个单元处于已启动状态, 那么该单元将加入到这个唯一已启动单元的名字空间中。 如果单元列表中有多个单元处于已启动状态, 那么该单元将随机加入一个已启动单元的名字空间中。 此选项仅适用于支持 PrivateNetwork= 与/或 PrivateTmp= 指令的单元 (对加入者与被加入者都适用)。 详见 systemd.exec(5) 手册。 |
RequiresMountsFor= | 接受一个空格分隔的绝对路径列表,表示该单元将会使用到这些文件系统路径。 所有这些路径中涉及的挂载点所对应的 mount 单元,都会被隐式的添加到 Requires= 与 After= 选项中。 也就是说,这些路径中所涉及的挂载点都会在启动该单元之前被自动挂载。 |
OnFailureJobMode= | 可设为 "fail","replace","replace-irreversibly","isolate","flush","ignore-dependencies","ignore-requirements" 之一。 默认值是 "replace" 。 指定 OnFailure= 中列出的单元应该以何种方式排队。值的含义参见 systemctl(1) 手册中对 --job-mode= 选项的说明。 如果设为 "isolate" , 那么只能在 OnFailure= 中设置一个单独的单元。 |
IgnoreOnIsolate= | 如果设为 yes , 那么在执行 systemctl isolate another.target 命令时,此单元不会被停止。 默认值是 no 。 |
StopWhenUnneeded= | 如果设为 yes , 那么当此单元不再被任何已启动的单元依赖时, 将会被自动停止。 默认值 no 的含义是, 除非此单元与其他即将启动的单元冲突, 否则即使此单元已不再被任何已启动的单元依赖, 也不会自动停止它。 |
RefuseManualStart= RefuseManualStop= |
如果设为 yes , 那么此单元将拒绝被手动启动(RefuseManualStart=) 或拒绝被手动停止(RefuseManualStop=)。 也就是说, 此单元只能作为其他单元的依赖条件而存在, 只能因为依赖关系而被间接启动或者间接停止, 不能由用户以手动方式直接启动或者直接停止。 设置此选项是为了 禁止用户意外的启动或者停止某些特定的单元。 默认值是 no。 |
AllowIsolate= | 如果设为 yes , 那么此单元将允许被 systemctl isolate 命令操作, 否则将会被拒绝。 唯一一个将此选项设为 yes 的理由,大概是为了兼容SysV初始化系统。 此时应该仅考虑对 target 单元进行设置, 以防止系统进入不可用状态。 建议保持默认值 no |
DefaultDependencies= | 默认值 yes 表示为此单元隐式地创建默认依赖。 不同类型的单元,其默认依赖也不同,详见各自的手册页。 例如对于 service 单元来说, 默认的依赖关系是指: (1)开机时,必须在基础系统初始化完成之后才能启动该服务; (2)关机时,必须在该服务完全停止后才能关闭基础系统。 通常,只有那些在系统启动的早期就必须启动的单元, 以及那些必须在系统关闭的末尾才能关闭的单元, 才可以将此选项设为 no 。 注意,设为 no 并不表示取消所有的默认依赖, 只是表示取消非关键的默认依赖。 强烈建议对绝大多数普通单元保持此选项的默认值 yes 。 |
JobTimeoutSec= JobTimeoutAction= JobTimeoutRebootArgument= JobTimeoutSec= |
用于设置该单元等候外部任务(job)完成的最长时限。 如果超时,那么超时的 job 将被撤销,并且该单元将保持其现有状态不变。 对于非 device 单元,此选项的默认值是 "infinity"(永不超时)。 注意,此选项的超时不是指单元自身的超时(例如 TimeoutStartSec= 就是指单元自身的超时), 而是指该单元在启动或者停止等状态变化过程中,等候某个外部任务完成的最长时限。 换句话说,适用于单元自身的超时设置(例如 TimeoutStartSec=)用于指定单元自身在改变其状态时,总共允许使用多长时间; 而 JobTimeoutSec= 则是设置此单元在改变其状态的过程中,等候某个外部任务完成所能容忍的最长时间。 |
JobTimeoutAction= | 用于指定当超时发生时, 将触发什么样的额外动作。 默认值为 none 。 可设置的值与 StartLimitaction= 相同,参见 systemd.service(5) 手册。 JobTimeoutRebootArgument= 用于指定传递给 reboot(2) 系统调用的字符串参数。 |
StartLimitIntervalSec= StartLimitBurst= |
设置单元的启动频率限制。 默认情况下,一个单元在10秒内最多允许启动5次。 StartLimitIntervalSec= 用于设置时长, 默认值等于 DefaultStartLimitIntervalSec= 的值(默认为10秒),设为 0 表示不作限制。 StartLimitBurst= 用于设置在一段给定的时长内,最多允许启动多少次, 默认值等于 DefaultStartLimitBurst= 的值(默认为5次)。 虽然此选项通常与 Restart= (参见 systemd.service(5)) 一起使用, 但实际上,此选项作用于任何方式的启动(包括手动启动), 而不仅仅是由 Restart= 触发的启动。 注意,一旦某个设置了 Restart= 自动重启逻辑的单元 触碰到了启动频率限制,那么该单元将再也不会尝试自动重启; 不过,如果该单元后来又被手动重启成功的话,那么该单元的自动重启逻辑将会被再次激活。 注意,systemctl reset-Failed 命令能够重置单元的启动频率计数器。 系统管理员在手动启动某个已经触碰到了启动频率限制的单元之前,可以使用这个命令清除启动限制。 注意,因为启动频率限制位于所有单元条件检查之后,所以基于失败条件的启动不会计入启动频率限制的启动次数之中。 注意, slice,target,device,scope 单元不受此选项的影响, 因为这几种单元要么永远不会启动失败、要么只能成功启动一次。 |
RebootArgument= | 当 StartLimitaction= 或 FailureAction= 触发关机动作时, 此选项的值就是传递给 reboot(2) 系统调用的字符串参数。 相当于 systemctl reboot 命令接收的可选参数。 |
ConditionArchitecture=, ConditionVirtualization= ConditionHost= ConditionKernelCommandLine= ConditionSecurity= ConditionCapability= ConditionACPower= ConditionNeedsUpdate= ConditionFirstBoot= ConditionPathExists= ConditionPathExistsGlob= ConditionPathIsDirectory= ConditionPathIsSymbolicLink=,ConditionPathIsMountPoint= ConditionPathIsReadWrite= ConditionDirectoryNotEmpty= ConditionFileNotEmpty= ConditionFileIsExecutable= |
这组选项用于在启动单元之前,首先测试特定的条件是否为真。 若为真则开始启动,否则将会(悄无声息地)跳过此单元(仅是跳过,而不是进入"Failed"状态)。 注意,即使某单元由于测试条件为假而被跳过,那些由于依赖关系而必须先于此单元启动的单元并不会受到影响(也就是会照常启动)。 可以使用条件表达式来跳过那些对于本机系统无用的单元, 比如那些对于本机内核或运行环境没有用处的功能。 如果想要单元在测试条件为假时进入"Failed"状态(而不是跳过), 可以使用对应的另一组 AssertXXX= 选项(见下面)。 |
ConditionArchitecture= | 检测是否运行于特定的硬件平台: x86,x86-64,ppc,ppc-le,ppc64,ppc64-le,ia64,parisc,parisc64,s390,s390x,sparc,sparc64,mips,mips-le,mips64,mips64-le,alpha,arm,arm-be,arm64,arm64-be,sh,sh64,m86k,tilegx,cris,native(编译 systemd 时的目标平台)。 可以在这些关键字前面加上感叹号(!)前缀表示逻辑反转。 注意,Personality= 的设置对此选项没有任何影响。 |
ConditionVirtualization= | 检测是否运行于(特定的)虚拟环境中: qemu,kvm,zvm,vmware,microsoft,oracle,xen,bochs,uml,openvz,lxc,lxc-libvirt,systemd-nspawn,docker,rkt,vm(某种虚拟机),container(某种容器),yes(某种虚拟环境),no(物理机)。 参见 systemd-detect-virt(1) 手册以了解所有已知的虚拟化技术及其标识符。 如果嵌套在多个虚拟化环境内, 那么以最内层的那个为准。 可以在这些关键字前面加上感叹号(!)前缀表示逻辑反转。 |
ConditionHost= | 检测系统的 hostname 或者 "machine ID" 。 参数可以是一个主机名字符串(首尾可加引号界定), 或者是一个 "machine ID" 格式的字符串(首尾不可加引号), 参见 machine-id(5) 手册。 可以在字符串前面加上感叹号(!)前缀表示逻辑反转。 |
ConditionKernelCommandLine= | 检测是否设置了某个特定的内核引导选项。 参数可以是一个单独的单词,也可以是一个 "var=val" 格式的赋值字符串。 如果参数是一个单独的单词,那么以下两种情况都算是检测成功: (1)恰好存在一个完全匹配的单词选项; (2)在某个 "var=val" 格式的内核引导选项中等号前的 "var" 恰好与该单词完全匹配。 如果参数是一个 "var=val" 格式的赋值字符串, 那么必须恰好存在一个完全匹配的 "var=val" 格式的内核引导选项,才算检测成功。 可以在字符串前面加上感叹号(!)前缀表示逻辑反转。 |
ConditionSecurity= | 检测是否启用了特定的安全模块: selinux,apparmor,ima,smack,audit 。 可以在这些关键字前面加上感叹号(!)前缀表示逻辑反转。 |
ConditionCapability= | 检测 systemd 的 capability 集合中是否存在特定的 capabilities(7) 。 参数应设为例如 "CAP_MKNOD" 这样的 capability 名称。 注意,此选项不是检测特定的 capability 是否实际可用, 而是仅检测特定的 capability 在绑定集合中是否存在。 可以在名称前面加上感叹号(!)前缀表示逻辑反转。 |
ConditionACPower= | 检测系统是否正在使用交流电源。 yes 表示至少在使用一个交流电源, 或者更本不存在任何交流电源。 no 表示存在交流电源, 但是没有使用其中的任何一个。 |
ConditionNeedsUpdate= | 可设为 /var 或 /etc 之一, 用于检测指定的目录是否需要更新。 设为 /var 表示 检测 /usr 目录的最后更新时间(mtime) 是否比 /var/.updated 文件的最后更新时间(mtime)更晚。 设为 /etc 表示 检测 /usr 目录的最后更新时间(mtime) 是否比 /etc/.updated 文件的最后更新时间(mtime)更晚。 可以在值前面加上感叹号(!)前缀表示逻辑反转。 当更新了 /usr 中的资源之后,可以通过使用此选项, 实现在下一次启动时更新 /etc 或 /var 目录的目的。 使用此选项的单元必须设置 ConditionFirstBoot=systemd-update-done.service , 以确保在 .updated 文件被更新之前启动完毕。 参见 systemd-update-done.service(8) 手册。 |
ConditionFirstBoot= | 可设为 yes 或 no 。 用于检测 /etc 目录 是否处于未填充的原始状态 (也就是系统出厂后的首次启动)。 此选项可用于系统出厂后,首次开机时执行必要的初始化操作。 |
ConditionPathExists= | 检测指定的路径是否存在, 必须使用绝对路径。 可以在路径前面加上感叹号(!)前缀表示逻辑反转。 |
ConditionPathExistsGlob= | 与 ConditionPathExists= 类似, 唯一的不同是支持通配符。 |
ConditionPathIsDirectory= | 检测指定的路径是否存在并且是一个目录,必须使用绝对路径。 可以在路径前面加上感叹号(!)前缀表示逻辑反转。 |
ConditionPathIsSymbolicLink= | 检测指定的路径是否存在并且是一个软连接,必须使用绝对路径。 可以在路径前面加上感叹号(!)前缀表示逻辑反转。 |
ConditionPathIsMountPoint= | 检测指定的路径是否存在并且是一个挂载点,必须使用绝对路径。 可以在路径前面加上感叹号(!)前缀表示逻辑反转。 |
ConditionPathIsReadWrite= | 检测指定的路径是否存在并且可读写(rw),必须使用绝对路径。 可以在路径前面加上感叹号(!)前缀表示逻辑反转。 |
ConditionDirectoryNotEmpty= | 检测指定的路径是否存在并且是一个非空的目录,必须使用绝对路径。 可以在路径前面加上感叹号(!)前缀表示逻辑反转。 |
ConditionFileNotEmpty= | 检测指定的路径是否存在并且是一个非空的普通文件,必须使用绝对路径。 可以在路径前面加上感叹号(!)前缀表示逻辑反转。 |
ConditionFileIsExecutable= | 检测指定的路径是否存在并且是一个可执行文件,必须使用绝对路径。 可以在路径前面加上感叹号(!)前缀表示逻辑反转。 |
[Install] 段:
这个段包含单元启动信息,只有单元状态为enable或者disabled才会用到这个段,这个段不能出现在单元的.d/*.conf配置文件中。
字段 | 说明 |
Alias= | 启用时使用的别名,可以设为一个空格分隔的别名列表。 每个别名的后缀(也就是单元类型)都必须与该单元自身的后缀相同。 如果多次使用此选项,那么每个选项所设置的别名都会被添加到别名列表中。 在启用此单元时,systemctl enable命令将会为每个别名创建一个指向该单元文件的软连接。 注意,因为 mount,slice,swap,automount 单元不支持别名,所以不要在这些类型的单元中使用此选项。 |
WantedBy= requiredBy= |
接受一个空格分隔的单元列表, 表示在使用systemctl enable启用此单元时, 将会在每个列表单元的 这个选项跟启动级别有关,通常设置的值为mult-user.targe 这是一个target,之后再讲,你只需要知道这相当于启动级别中的多用户默认。 |
Also= | 设置此单元的附属单元,可以设为一个空格分隔的单元列表。 表示当使用systemctl enable启用 或systemctl disable停用 此单元时, 也同时自动的启用或停用附属单元。如果多次使用此选项, 那么每个选项所设置的附属单元列表都会合并在一起。 |
DefaultInstance= | 仅对模板单元有意义, 用于指定默认的实例名称。 如果启用此单元时没有指定实例名称, 那么将使用这里设置的名称。 |
参考链接:systemd.unit中文手册
CentOS 6.5 Varnish缓存服务配置与应用
1、varnish的基本介绍
Varnish 的作者Poul-Henning Kamp是FreeBSD的内核开发者之一,他认为现在的计算机比起1975年已经复杂许多。在1975年时,储存媒介只有两种:内存与硬盘。但现在计算机系统的内存除了主存外,还包括了cpu内的L1、L2,甚至有L3快取。硬盘上也有自己的快取装置,因此squid cache自行处理物件替换的架构不可能得知这些情况而做到最佳化,但操作系统可以得知这些情况,所以这部份的工作应该交给操作系统处理,这就是 Varnish cache设计架构。
Varnish与一般服务器软件类似,就是一个web缓存代理服务器,分为master(management)进程和child(worker,主要做cache的工作)进程。master进程读入命令,进行一些初始化,然后fork并监控child进程。child进程分配若干线程进行工作,主要包括一些管理线程和很多woker线程。
Management进程主要实现应用新的配置、编译VCL、监控varnish、初始化varnish以及提供一个命令行接口等。Management进程会每隔几秒钟探测一下Child进程以判断其是否正常运行,如果在指定的时长内未得到Child进程的回应,Management将会重启此Child进程。
Child进程包含多种类型的线程,常见的如:
Acceptor线程:接收新的连接请求并响应;
Worker线程:child进程会为每个会话启动一个worker线程,因此,在高并发的场景中可能会出现数百个worker线程甚至更多;
Expiry线程:从缓存中清理过期内容;
Varnish依赖“工作区(workspace)”以降低线程在申请或修改内存时出现竞争的可能性。在varnish内部有多种不同的工作区,其中最关键的当属用于管理会话数据的session工作区。
进程的工作过程原理及过程:
2、varnish与squid的区别
varnish和squid在中小规模的应用上,varnish足够轻量级,足够好用,但是在巨大的并发请求来说,单个varnish所能够承载的并发访问量大概在5000个连接请求左右,超出5000个可能就就得不稳定了;而在这里squid就能表现出良好的性能了,因此在大规模的企业级应用中仍然是以squid居多,而在中小规模的自己公司的反向代理缓存中varnish居多;
3、varnish的日志说明
为了与系统的其它部分进行交互,Child进程使用了可以通过文件系统接口进行访问的共享内存日志(shared memory log),因此,如果某线程需要记录信息,其仅需要持有一个锁,而后向共享内存中的某内存区域写入数据,再释放持有的锁即可。而为了减少竞争,每个worker线程都使用了日志数据缓存。
共享内存日志大小一般为90M,其分为两部分,前一部分为计数器,后半部分为客户端请求的数据。varnish提供了多个不同的工具如varnishlog、varnishncsa或varnishstat等来分析共享内存日志中的信息并能够以指定的方式进行显示。
4、VCL基本介绍
Varnish Configuration Language (VCL)是varnish配置缓存策略的工具,它是一种基于“域”(domain specific)的简单编程语言,它支持有限的算术运算和逻辑运算操作、允许使用正则表达式进行字符串匹配、允许用户使用set自定义变量、支持if判断语句,也有内置的函数和变量等。使用VCL编写的缓存策略通常保存至.vcl文件中,其需要编译成二进制的格式后才能由varnish调用。事实上,整个缓存策略就是由几个特定的子例程如vcl_recv、vcl_fetch等组成,它们分别在不同的位置(或时间)执行,如果没有事先为某个位置自定义子例程,varnish将会执行默认的定义。
VCL策略在启用前,会由management进程将其转换为C代码,而后再由gcc编译器将C代码编译成二进制程序。编译完成后,management负责将其连接至varnish实例,即child进程。正是由于编译工作在child进程之外完成,它避免了装载错误格式VCL的风险。因此,varnish修改配置的开销非常小,其可以同时保有几份尚在引用的旧版本配置,也能够让新的配置即刻生效。编译后的旧版本配置通常在varnish重启时才会被丢弃,如果需要手动清理,则可以使用varnishadm的vcl.discard命令完成。
5、varnish的后端存储
varnish的缓存对象在每次服务重启时都会被清空并重新建立,所以这些服务器都是不应该随便去重启的,varnish为了把数据更持久化的存储,引入了更多的存储机制,所以varnish支持多种不同的后端存储;
varnish支持多种不同类型的后端存储,这可以在varnishd启动时使用-s选项指定。后端存储的类型包括:
(1)file:使用特定的文件存储全部的缓存数据,并通过操作系统的mmap()系统调用将整个缓存文件映射至内存区域(如果条件允许);
(2)malloc:使用malloc()库调用在varnish启动时向操作系统申请指定大小的内存空间以存储缓存对象;
(3)persistent(experimental):与file的功能相同,但可以持久存储数据(即重启varnish数据时不会被清除);仍处于测试期;
varnish无法追踪某缓存对象是否存入了缓存文件,从而也就无从得知磁盘上的缓存文件是否可用,因此,file存储方法在varnish停止或重启时会清除数据。而persistent方法的出现对此有了一个弥补,但persistent仍处于测试阶段,例如目前尚无法有效处理要缓存对象总体大小超出缓存空间的情况,所以,其仅适用于有着巨大缓存空间的场景。
选择使用合适的存储方式有助于提升系统性,从经验的角度来看,建议在内存空间足以存储所有的缓存对象时使用malloc的方法,反之,file存储将有着更好的性能的表现。然而,需要注意的是,varnishd实际上使用的空间比使用-s选项指定的缓存空间更大,一般说来,其需要为每个缓存对象多使用差不多1K左右的存储空间,这意味着,对于100万个缓存对象的场景来说,其使用的缓存空间将超出指定大小1G左右。另外,为了保存数据结构等,varnish自身也会占去不小的内存空间。
6、varnish的工作原理及工作流程
官方提供的工作流程图:
vcl的工作方式是基于状态引擎(state engine)来实现的;上图说明:
vcl_recv的结果如果可以查询缓存并可以识别,那就要到vcl_hash这步了,如果无法识别那就通过pipe(管道)送给vcl_pipe,如果能识别,但不是一个可缓存的对象,那就通过pass送到vcl_pass去,vcl_hash之后就可查看缓存中有没有了,有这个请求的对象就表示命中(vcl_hit),如果没有那就表示未命中(vcl_miss),如果命中的就可以直接通过deliver直接送给vcl_deliver响应了,如果未命中就通过fetch交给vcl_fatch去后端服务器上去取数据,取回数据之后如果数据可以缓存就缓存(cache),本地缓存完之后再构建响应,如果不可以缓存就不做缓存交给vcl_deliver响应了;而如果命中了交给vcl_pass,交给pass之后就要到Fetch objet from backend后端服务器上去取数据了,这是因为这个命中的对象可能是过期或者是要做单独立额外的处理的;这就是vcl的状态引擎过程。
一、安装实现过程:
# 安装varnish,版本是3.0.4-1.el6 [root@node0 ~]# rpm -ivh varnish-3.0.4-1.el6.x86_64.rpm varnish-docs-3.0.4-1.el6.x86_64.rpm varnish-libs-3.0.4-1.el6.x86_64.rpm [root@node0 ~]# rpm -ql varnish # 查看varnish的安装文件[root@node0 ~]# vim /etc/sysconfig/varnish # 查看配置文件 NFILES=131072 # 所能够打开的最大文件数 MEmlock=82000 # 用多大内存空间保存日志信息 DAEMON_COREFILE_LIMIT="unlimited" # 进程核心转储所使用的内存空间,unlimited表示无上限 RELOAD_VCL=1 # 重新启动服务时是否重新读取VCL并重新编译的 VARNISH_VCL_CONF=/etc/varnish/default.vcl # 默认读取的VCL文件 VARNISH_LISTEN_PORT=80 # 监听的端口,默认监听6081 VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1 # 管理接口监听的地址 VARNISH_ADMIN_LISTEN_PORT=6082 # 管理接口监听的端口 VARNISH_SECRET_FILE=/etc/varnish/secret # 使用的密钥文件 VARNISH_MIN_THREADS=1 # 最少线程数 VARNISH_MAX_THREADS=1000 # 最大线程数 VARNISH_THREAD_TIMEOUT=120 # 线程的超时时间 VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin # 基于文件存储时的文件路径 VARNISH_STORAGE_SIZE=1G # 存储文件的大小 VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}" # 存储的文件格式 VARNISH_TTL=120 # 联系后端服务器的超时时间 DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \ -f ${VARNISH_VCL_CONF} \ -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \ -t ${VARNISH_TTL} \ -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \ -u varnish -g varnish \ -S ${VARNISH_SECRET_FILE} \ -s ${VARNISH_STORAGE}" # 使用定义的各高级配置的参数 # 定义后端服务器 [root@node0 sysconfig]# cd /etc/varnish/ [root@node0 varnish]# cp default.vcl default.vcl.bak [root@node0 varnish]# mv default.vcl test.vcl [root@node0 varnish]# vim test.vclbackend webserver { .host = "172.16.27.1"; # 后端服务器的地址 .port = "80"; # 后端服务监听的端口 } # 启动服务 [root@node0 sysconfig]# service varnish start [root@node0 varnish]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 200 201 ----------------------------- Varnish Cache CLI 1.0 ----------------------------- Linux,2.6.32-431.el6.x86_64,x86_64,-smalloc,-hcritbit Type 'help' for command list. Type 'quit' to close CLI session. varnish> help 200 377 help [command] ping [timestamp] auth response quit banner status start stop stats vcl.load <configname> <filename> vcl.inline <configname> <quoted_VCLstring> vcl.use <configname> vcl.discard <configname> vcl.list vcl.show <configname> param.show [-l] [<param>] param.set <param> <value> purge.url <regexp> purge <field> <operator> <arg> [&& <field> <oper> <arg>]... purge.list |
安装配置好后端web服务器并启动,地址为172.16.27.1,而后通过varnish服务器地址访问后端服务器,这里仅仅只是定义一指向后端服务器,也就说现在也只能工作起来,但是还没有定义相关的缓存属性等信息,那就先通过varnish服务器端访问一下先吧:
[root@node1 ~]# yum -y install httpd PHP PHP-MysqL [root@node1 ~]# cd /var/www/html [root@node1 html]# vim index.html <h1>www.tanxw.com and varnish fo backend</h1> |
二、设置响应是否命中,接着继续编写配置文件:
[root@node0 varnish]# vimtest.vcl sub vcl_deliver { # 定义子例程 if (obj.hits > 0){ # 判断如果命中了就在http响应首部设置X-Cache为HITset resp.http.X-Cache = "HIT from " server.ip; } else { # 否则就在http响应首部设置X-Cache为MISS set resp.http.X-Cache = "MISS";} } # 在varnish的命令行中重新编译重新加载配置文件 varnish> vcl.load test1 /etc/varnish/test.vcl 200 13 backend webserver { [root@node0 varnish]# curl -Ihttp://172.16.27.88/index.html# 也可以在命令行请求 |
然后再到页面上访问看一下是否已经生效:
三、指定某些文件不能查缓存,断续添加配置文件
[root@node0 varnish]# vim test.vcl # 添加如下代码 sub vcl_recv { # 定义请求的文件中如果匹配test.html就pass,就不查缓存 if (req.url ~ "test.html"){return(pass); } return(lookup); } # 再到varnish的命令行中重新加载配置文件并应用 varnish> vcl.load test4 /etc/varnish/test.vcl # 在命令行请求看一下缓存,不管怎么请求X-Cache都是MISS [root@node0 varnish]# curl -I http://172.16.27.88/test.html |
而后再请求test.html页面;
四、设定缓存时长和定义图片防盗链:
[root@node0 varnish]# vim default.vcl sub vcl_fetch { if (req.url ~ "\.(jpg|jpeg|gif|png)$") { # 如果url是以图片格式结尾的缓存2小时set beresp.ttl = 7200s; } if (req.url ~ "\.(html|css|js)$") { # 如果url是以html|css|js结尾的缓存20分钟 set beresp.ttl = 1200s; } } sub vcl_recv { # 图片防盗链 |
五、移除单个缓存对象:purge用于清理缓存中的某特定对象及其变种(variants),因此,在有着明确要修剪的缓存对象时可以使用此种方式。HTTP协议的PURGE方法可以实现purge功能,不过,其仅能用于vcl_hit和vcl_miss中,它会释放内存工作并移除指定缓存对象的所有vary:-变种,并等待下一个针对此内容的客户端请求到达时刷新此内容。另外,其一般要与return(restart)一起使用。
[root@node0 varnish]# vim default.vcl acl purgers { # 定义acl访问控制,只允许以下网段或主机执行purgers操作 "127.0.0.1";"172.16.0.0"/16; } sub vcl_recv { if (req.request == "PURGE") { # 如果请求方法是PURGE,并且客户端IP在上面定义的网段内的就允许执行PURGE操作,否则生成一个错误页面返回给用户 if (!client.ip ~ purgers) { error 405 "Method not allowed"; } return (lookup); } } sub vcl_hit { if (req.request == "PURGE") { # 如果缓存中命中,那么就清除缓存内容 purge; error 200 "Purged"; } } sub vcl_miss { if (req.request == "PURGE") { # 如果缓存中未命中,说明缓存中没有内容 purge; error 404 "Not in cache"; } } sub vcl_pass { if (req.request == "PURGE") { # 如在pass中要清除缓存,直接返回错误码 error 502 "PURGE on a passed object"; } } # 保存退出,而后直接在命令行中进行测试一下: [root@node0 varnish]# curl -I http://172.16.27.88/index.html [root@node0 varnish]# curl -X PURGE http://172.16.27.88/index.html [root@node0 varnish]# curl -I http://172.16.27.88/index.html |
六、Varnish检测后端主机的健康状态:
Varnish可以检测后端主机的健康状态,在判定后端主机失效时能自动将其从可用后端主机列表中移除,而一旦其重新变得可用还可以自动将其设定为可用。为了避免误判,Varnish在探测后端主机的健康状态发生转变时(比如某次探测时某后端主机突然成为不可用状态),通常需要连续执行几次探测均为新状态才将其标记为转换后的状态。
每个后端服务器当前探测的健康状态探测方法通过.probe进行设定,其结果可由req.backend.healthy变量获取,也可通过varnishlog中的Backend_health查看或varnishadm的debug.health查看。
.probe中的探测指令常用的有:
(1) .url:探测后端主机健康状态时请求的URL,默认为“/”;
(2) .request: 探测后端主机健康状态时所请求内容的详细格式,定义后,它会替换.url指定的探测方式;比如:
.request =
"GET /.healthtest.html HTTP/1.1"
"Host: www.magedu.com"
"Connection: close";
(3) .window:设定在判定后端主机健康状态时基于最近多少次的探测进行,默认是8;
(4) .threshold:在.window中指定的次数中,至少有多少次是成功的才判定后端主机正健康运行;默认是3;
(5) .initial:Varnish启动时对后端主机至少需要多少次的成功探测,默认同.threshold;
(6) .expected_response:期望后端主机响应的状态码,默认为200;
(7) .interval:探测请求的发送周期,默认为5秒;
(8) .timeout:每次探测请求的过期时长,默认为2秒;
backend webserver { .host ="www.magedu.com"; # 定义后端主机 .probe = { .url = "/.healthtest.html"; # 向后端主机获取这个页面 .interval = 1s; # 每隔1秒钟尝试一次 .window = 5; # 最多尝试5次,判断采样的样本 .threshold = 2; # 如果采样5次,如果有2次是错误的,就认为是失败的,上线也是一样 }} |
七、Varnish的命令行工具
varnishadm命令语法:varnishadm [-t timeout] [-S secret_file] [-T address:port] [-n name] [command [...]]
通过命令行的方式连接至varnishd进行管理操作的工具,指定要连接的varnish实例的方法有两种:
-n name —— 连接至名称为“name”的实例;
-T address:port —— 连接至指定套接字上的实例;
其运行模式有两种,当不在命令行中给出要执行的"command"时,其将进入交互式模式;否则,varnishadm将执行指定的"command"并退出。要查看本地启用的缓存,可使用如下命令进行。
# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 storage.list
总结:
varnish是一个很强大的缓存服务器,还可以做动静分离,这里限于篇幅,在这里就不一一例举了,有关信息可以参数官方文档,还可以做后端服务器的调度等,于是这里总结得过于仓促,有做得不到之处还望大神多多指出,如果有什么问题可以留言交流学习。
本文出自 “温水煮青蛙” 博客,请务必保留此出处http://tanxw.blog.51cto.com/4309543/1412984
CentOS 7 将 Nginx 添加系统服务
导语
经过编译安装以及解决问题,Nginx 已经运行正常,但是此时 Nginx 并没有添加进系统服务。接下来会将 Nginx 添加进系统服务并且设置开机启动。
查看服务
首先查看 Nginx 的服务状态,输入 systemctl status nginx
,结果如下
没有找到相关的服务,下一步就是添加系统服务。
添加系统服务
在 /usr/lib/systemd/system
目录中添加 nginx.service
,根据实际情况进行修改,详细解析可查看下方参考资料中的文章。内容如下
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
添加完成后再来看下
设置开机自动启动
首先测试一下,重启然后来查看 Nginx 服务
确实没有启动。输入 systemctl start nginx
启动
可以使用 systemctl
启动,说明之前添加的 nginx.service
没有问题。然后输入 systemctl enable nginx
设置开机启动
最后重启检查下是否设置成功
没有问题,到此关于 Nginx 的编译安装完成,接下来是 PHP 的安装。
参考资料:CentOS 7 systemd添加自定义系统服务、
CentOS 7 将 nginx 配置成系统服务
在CentOS 7中对用户安装的应用服务设置为系统服务,比CentOS 6方便很多,下面以配置nginx为系统服务为例子进行说明。
本例中的nginx采用源码编译方式进行安装,安装位置在/usr/local/nginx。要配置nginx为系统服务,需要有nginx.service文件,执行如下操作,编写service脚本。
vi /usr/lib/systemd/system/nginx.service #nginx.service内容
[Unit] Description=nginx - high performance web server Documentation=http://nginx.org/en/docs/ After=network.target remote-fs.target nss-lookup.target [Service] Type=forking PIDFile=/your nginx pid file path/nginx.pid ExecStartPre=/your nginx path/sbin/nginx -t -c /your nginx path/conf/nginx.conf ExecStart=/your nginx path/sbin/nginx -c /your nginx path/conf/nginx.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s QUIT $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target
添加完之后,开启服务
systemctl enable nginx.service
systemctl daemon-reload
CentOS 7 系列(一)系统服务 systemd
Systemd:
在CentOS 7中开始使用了Systemd,它取代了原来的SysVinit,我们在系统中查看,你会发现systemd这个进程的PID为1,而不是原来的init进程。systemd进程将作为所有进程的父进程运行,这就是在CentOS 7中的新的进程管理程序。
Systemd是Linux内核发起的第一个程序,通过上面的截图也可以印证这一点,而且它还扮演很多角色,它会启动系统服务、处理用户登陆、执行一些定时任务等。它变成了Linux的的一种基础系统。在启动过程中内核检查完硬件加载完基础驱动,就会运行systemd这个程序(原来是/sbin/init),这个程序会加载文件系统、其他驱动以及运行各种系统服务。
Systemd与之前的init最大的不同是引入了并行启动概念,之前的init进程是一个一个的启动其他进程的。Systemd会为每一个需要启动的守护进行建立一个套接字,这样不同进程就可以相互通信。Systemd创建进程并为每个进程分配一个控制组也就是CGroup,通过这个组来追踪进程。
日志文件:
另外在systemd中的一个变化就是日志变成二进制格式,它实际上是一个日志系统,它产生的日志你无法用文本编辑器查看,不过好处是记录的信息更全带有很多的元数据,可以很容易的进行内容过滤。比如查看日志可以用下面的命令
journalctl
默认将命令输出管道给了less程序,这样方便查看,不过它会输出所有日志。如果仅仅想看本次系统启动的日志呢:
journalctl-b
如果是上一次启动的日志呢:
journalctl-b-1
以此类推,-2就是上上次的。如果想看某一个时刻到现在的启动信息呢?
journalctl-b--since="2017-03-3117:00"
如何根据特定程序查看日志呢?
journalctl-uNginx.service
今天关于CentOS 7 系列和二系统服务配置--单元的介绍到此结束,谢谢您的阅读,有关CentOS 6.5 Varnish缓存服务配置与应用、CentOS 7 将 Nginx 添加系统服务、CentOS 7 将 nginx 配置成系统服务、CentOS 7 系列(一)系统服务 systemd等更多相关知识的信息可以在本站进行查询。
本文标签: