Exploring
首页
  • Java

    • 面向对象的思想OOP
    • 浅谈Java反射原理
    • endorsed覆盖JDK中的类
  • 认证与授权

    • LDAP概念和原理介绍
    • OAuth2介绍
  • Impala

    • Impala 介绍
  • MySQL

    • 关于MySQL的一些面试题
    • 解决MySQL不到中文数据
    • 数据库之事务与实现原理
  • Oracle

    • oracle的表空间,用户管理,表操作,函数
    • oracle的查询、视图、索引
    • plsql简单入门
  • Redis

    • 数据类型详解
    • 跳越表
    • 数据持久化的两种方式
  • 共识算法

    • gossip
  • RPC

    • GRPC初识与快速入门
    • ProtocolBuffer基本语法
  • RabbitMQ

    • RabbitMQ入门程序之HelloWorld
    • RabbitMQ之工作模式
  • Zookeeper

    • Zookeeper一文入门
  • Docker

    • Docker入门初体验
  • Maven

    • 把自己的包到Maven中央仓库
    • Maven之自定义插件
  • Nginx

    • nginx的安装
    • nginx的配置文件
    • nignx 的变量
  • Tomcat

    • Servlet3通过SPI进行注册组件
  • Vagrant

    • vagrant 初始化
    • vagrant 常用配置
    • vagrant 自己制作 box
  • Linux

    • 启动方式 Systemd
    • 后台服务
    • 防火墙与 Iptables
  • 设计模式

    • 设计模式-代理
    • 设计模式-单例模式
    • 设计模式-迭代器
  • 分布式

    • CAP 理论
  • 数据结构

    • 数据结构之堆Heap
    • 数据结构之哈希表
    • 数据结构之队列
  • 计算机网络

    • HTTP与HTTPS详解
    • 浅谈DNS协议
    • ISP中的网络层
  • 算法

    • 常用查找算法及Java实现
    • 常用排序算法及Java实现
    • 迪杰斯特拉算法
  • 操作系统

    • 操作系统之进程调度算法
    • 操作系统之进程通讯IPC
    • 操作系统之内存管理
  • 抓包

    • 生成安卓系统证书
  • 加解密

    • 常见加密算法
    • 公开秘钥基础知识
    • RSA 解析
  • Windows

    • scoop 包管理
    • windows-terminal 配置
    • 增强 PowerShell
归档
Github (opens new window)
首页
  • Java

    • 面向对象的思想OOP
    • 浅谈Java反射原理
    • endorsed覆盖JDK中的类
  • 认证与授权

    • LDAP概念和原理介绍
    • OAuth2介绍
  • Impala

    • Impala 介绍
  • MySQL

    • 关于MySQL的一些面试题
    • 解决MySQL不到中文数据
    • 数据库之事务与实现原理
  • Oracle

    • oracle的表空间,用户管理,表操作,函数
    • oracle的查询、视图、索引
    • plsql简单入门
  • Redis

    • 数据类型详解
    • 跳越表
    • 数据持久化的两种方式
  • 共识算法

    • gossip
  • RPC

    • GRPC初识与快速入门
    • ProtocolBuffer基本语法
  • RabbitMQ

    • RabbitMQ入门程序之HelloWorld
    • RabbitMQ之工作模式
  • Zookeeper

    • Zookeeper一文入门
  • Docker

    • Docker入门初体验
  • Maven

    • 把自己的包到Maven中央仓库
    • Maven之自定义插件
  • Nginx

    • nginx的安装
    • nginx的配置文件
    • nignx 的变量
  • Tomcat

    • Servlet3通过SPI进行注册组件
  • Vagrant

    • vagrant 初始化
    • vagrant 常用配置
    • vagrant 自己制作 box
  • Linux

    • 启动方式 Systemd
    • 后台服务
    • 防火墙与 Iptables
  • 设计模式

    • 设计模式-代理
    • 设计模式-单例模式
    • 设计模式-迭代器
  • 分布式

    • CAP 理论
  • 数据结构

    • 数据结构之堆Heap
    • 数据结构之哈希表
    • 数据结构之队列
  • 计算机网络

    • HTTP与HTTPS详解
    • 浅谈DNS协议
    • ISP中的网络层
  • 算法

    • 常用查找算法及Java实现
    • 常用排序算法及Java实现
    • 迪杰斯特拉算法
  • 操作系统

    • 操作系统之进程调度算法
    • 操作系统之进程通讯IPC
    • 操作系统之内存管理
  • 抓包

    • 生成安卓系统证书
  • 加解密

    • 常见加密算法
    • 公开秘钥基础知识
    • RSA 解析
  • Windows

    • scoop 包管理
    • windows-terminal 配置
    • 增强 PowerShell
归档
Github (opens new window)
  • Docker

  • Maven

  • Nginx

  • Tomcat

  • Vagrant

  • Linux

    • 启动过程
    • 后台服务
      • 介绍
      • 自动依赖
        • 隐式依赖
        • 默认依赖
      • 参数列表
        • Type
        • ExitType
        • PIDFile
        • ExecStart
        • ExecReload
        • RestartSec
        • Environment
      • 命令行
      • 示例
        • sample 服务
        • oneshot 服务
        • 可停止的oneshot 服务
        • 典型的 forking 服务
        • DBug 服务
        • 能够通知初始化已完成的服务
    • 防火墙与 Iptables
    • 路由与 IP 命令
  • DevOps
  • Linux
unclezs
2022-05-30
0
目录

后台服务

# 介绍

我们日常中用到的最多的 Unit 就是服务了(.service)。所以学会再当今最流行的 Systemd 启动模式下的后台服务的编写是十分有必要的。

以 ssh-deamon 服务的配置文件为例

systemctl cat sshd
------------
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.service
Wants=sshd-keygen.service

[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

包含 Unit、Service、Install 三个 Section。

# 自动依赖

# 隐式依赖

隐式添加了以下依赖项:

  • 比如设置了Type=dbus的服务,会自动获取dbus.socket 的 Requires=和 After=作为依赖关系 。
  • 套接字激活的服务在激活 .socket 单元后通过自动 After= 依赖项自动排序。服务还通过自动和依赖关系拉入.socket列出的所有单元。Sockets=``Wants=``After=

# 默认依赖

除非设置DefaultDependencies=no,否则将添加以下依赖项:

  • 服务单元被加上 sysinit.target 中 Requires= 和 After= 类型的依赖项、basic.target 中 After= 的依赖,shutdown.target中Conflicts=和 Before= 的依赖。这些确保正常的服务单元拉入基本的系统初始化,并在系统关闭之前干净地终止。只有涉及提前启动或延迟系统关闭的服务才应禁用此选项。
  • 实例化的服务单元(即@名称中带有“”的服务单元)默认分配一个每个模板切片单元(参见 systemd.slice (5) (opens new window)),以模板单元命名,包含特定模板的所有实例。此切片通常与所有模板实例一起在关闭时停止。如果不需要,DefaultDependencies=no请在模板单元中设置,并定义您自己的每个模板切片单元文件,该文件也设置 DefaultDependencies=no,或Slice=system.slice在模板单元中设置(或另一个合适的切片)。

# 参数列表

列举一些常用的参数,全部参数可见:Service Options (opens new window)

# Type

配置此服务单元的进程启动类型。 simple、exec、forking、oneshot、dbus、notify 或 idle 之一:

# simple

默认的,systemctl start 启动一个 simple的都不会提示失败,即使无法成功调用服务的可执行文件(例如,因为选定的 User=不存在,或者服务可执行文件不存在等)。

# exec

systemctl start 启动一个 exec 的能够提示失败,即使无法成功调用服务的可执行文件(例如因为所选内容不存在,或者服务可执行文件不不存在)。

# forking

主进程退出后,子进程会继续执行任务,并且状态会变为 running。

# oneshot

类似于 simple,主进程退出后就结束了,但是提供了RemainAfterExit=选项来配置,告诉服务管理器是不是有子进程继续在干活。注意,如果不使用此选项RemainAfterExit=,服务将永远不会进入“ active”单元状态,而是直接从“ activating”转换为“ deactivating”或“ dead”,因为没有配置应连续运行的进程。特别是这意味着在这种类型的服务运行之后(并且RemainAfterExit=未设置)它不会在之后显示为已启动,而是显示为已死。

# dbus

类似于 simple,但是该服务会在 D-Bus 总线上获得一个名称,如 BusName=. 在获得 D-Bus 总线名称后,systemd 将继续启动后续单元。

# notify

类似于 exec,启动完成后会发送一个消息sd-notify (opens new window)。systemd 收到进程发来的消息后,会继续启动后续的 Unit。如果使用此选项,则 NotifyAccess=应设置为打开对 systemd 提供的通知套接字的访问。如果 NotifyAccess= 缺失或设置为 none,它将被强制设置为 main。

# idle

# ExitType

有 main 和 cgroup 两种,默认是 main。

  • 如果设置为main,根据 Type=中的特性来决定是否为退出 。因此,它不能与 Type=oneshot.
  • 如果设置为cgroup,只要 cgroup 中至少有一个进程没有退出,服务就会被认为正在运行。

# PIDFile

指定 PID 文件的输出位置,服务关闭后自动删除,type = forking 的推荐使用这个。

# ExecStart

启动此服务时执行的带有参数的命令。

# ExecReload

要执行的命令以触发服务中的配置重新加载。这里可以使用 $MAINPID获取进程ID。

ExecReload=kill -HUP $MAINPID
1

# RestartSec

配置重新启动服务之前的睡眠时间。采用以秒为单位的无单位值,或时间跨度值,例如“5min 20s”。默认为 100 毫秒。

# Environment

指定环境变量,注意启动的时候系统的环境变量都还是不可用的

Environment=ONE='one' "TWO='two two' too" THREE=
1

EnvironmentFile 指定环境变量文件路径,一行一个。key、value形式。

# 命令行

本节介绍 ExecStart=、ExecStartPre=、ExecStartPost=、ExecReload=、ExecStop= 和 ExecStopPost= 选项的命令行解析以及变量和说明符替换。

多行命令可以用 \ 进行换行

Environment=ONE='one' "TWO='two two' too" THREE=
ExecStart=/bin/echo ${ONE} ${TWO} ${THREE}
ExecStart=/bin/echo $ONE $TWO $THREE
ExecStart=echo / >/dev/null & \; \
ls
1
2
3
4
5

第三个中 echo 被传了5个参数 "/", ">/dev/null", "&", ";", "ls".

# 示例

# sample 服务

下面的单元文件创建了一个运行 /usr/sbin/foo-daemon 守护进程的服务。 未设置 Type= 等价于 Type=``simple 默认设置。 systemd 执行守护进程之后, 即认为该单元已经启动成功。

[Unit]
Description=Foo

[Service]
ExecStart=/usr/sbin/foo-daemon

[Install]
WantedBy=multi-user.target
1
2
3
4
5
6
7
8

# oneshot 服务

Type=``oneshot 用于那些只需要执行一次性动作而不需要持久运行的单元, 例如文件系统检查或者清理临时文件。 此类单元, 将会在启动后一直等待指定的动作完成, 然后再回到停止状态。 下面是一个执行清理动作的单元:

[Unit]
Description=Cleanup old Foo data

[Service]
Type=oneshot
ExecStart=/usr/sbin/foo-cleanup

[Install]
WantedBy=multi-user.target
1
2
3
4
5
6
7
8
9

# 可停止的oneshot 服务

有时候, 单元需要执行一个程序以完成某个设置(启动), 然后又需要再执行另一个程序以撤消先前的设置(停止), 而在设置持续有效的时段中,该单元应该视为处于"活动"(active)状态, 但实际上并无任何程序在持续运行。 网络配置服务就是一个典型的例子。 此外,只能启动一次(不可多次启动)的一次性服务, 也是一个例子。

可以通过设置 RemainAfterExit=yes 来满足这种需求。 在这种情况下,systemd 将会在启动成功后将该单元视为处于"活动"(active)状态(而不是"停止"(inactive)状态)。 RemainAfterExit=yes 虽然可以用于所有 Type= 类型, 但是在实践中主要用于 Type=oneshot 和 Type=simple 类型。 对于 Type=oneshot 类型, systemd 一直等到服务启动成功之后,才会将该服务置于"活动"(active)状态。 所以,依赖于该服务的其他单元必须等待该服务启动成功之后,才能启动。 但是对于 Type=simple 类型, 依赖于该服务的其他单元无需等待, 将会和该服务同时并行启动。 下面的类似展示了一个简单的静态防火墙服务:

[Unit]
Description=Simple firewall

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/simple-firewall-start
ExecStop=/usr/local/sbin/simple-firewall-stop

[Install]
WantedBy=multi-user.target
1
2
3
4
5
6
7
8
9
10
11

# 典型的 forking 服务

许多传统的守护进程/服务后台(即fork,daemonize)在启动时自己在服务的单元文件中设置 Type=forking 以支持这种操作模式。 systemd 将在原始程序仍在运行时认为服务处于初始化过程中。一旦它成功退出并且至少有一个进程保留(并且 RemainAfterExit=no),则认为该服务已启动。

[Unit]
Description=Some simple daemon

[Service]
Type=forking
ExecStart=/usr/sbin/my-simple-daemon -d

[Install]
WantedBy=multi-user.target
1
2
3
4
5
6
7
8
9

# DBug 服务

对于需要在 D-Bus 系统总线上注册一个名字的服务, 应该使用 Type=``dbus 并且设置相应的 BusName= 值。 该服务不可以派生任何子进程。 一旦从 D-Bus 系统总线成功获取所需的名字,该服务即被视为初始化成功。 下面是一个典型的 D-Bus 服务:

[Unit]
Description=Simple DBus service

[Service]
Type=dbus
BusName=org.example.simple-dbus-service
ExecStart=/usr/sbin/simple-dbus-service

[Install]
WantedBy=multi-user.target
1
2
3
4
5
6
7
8
9
10

# 能够通知初始化已完成的服务

Type=``simple 类型的服务 非常容易编写, 但是, 无法向 systemd 及时通知 "启动成功"的消息, 是一个重大缺陷。 Type=``notify 可以弥补该缺陷, 它支持将"启动成功"的消息及时通知给 systemd 。 下面是一个典型的例子:

[Unit]
Description=Simple notifying service

[Service]
Type=notify
ExecStart=/usr/sbin/simple-notifying-service

[Install]
WantedBy=multi-user.target
1
2
3
4
5
6
7
8
9
在 GitHub 编辑此页 (opens new window)
上次更新: 2024/02/25, 12:11:11
启动过程
防火墙与 Iptables

← 启动过程 防火墙与 Iptables→

Theme by Vdoing | Copyright © 2018-2024 unclezs
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式