Linux之systemd服务配置及自动重启

2023-05-16

 

Linux之systemd服务配置及自动重启

0 背景

在linux上开发时,往往需要将自己的程序做成服务,并且实现服务开机自动重启,以及服务崩溃后自动重启功能,本文就对该功能的实现做简单介绍,实现方法很简单,使用linux系统的systemd即可实现

1 systemd介绍

历史上,linux的启动一直采用init进程,比如

$ sudo /etc/init.d/apache2 start

或者

$ service apache2 start

这种方法有两个缺点。

一是启动时间长。init进程是串行启动,只有前一个进程启动完,才会启动下一个进程。
二是启动脚本复杂。init进程只是执行启动脚本,不管其他事情。脚本需要自己处理各种情况,这往往使得脚本变得很长。

Systemd 就是为了解决这些问题而诞生的。它的设计目标是,为系统的启动和管理提供一套完整的解决方案。

根据 Linux 惯例,字母d是守护进程(daemon)的缩写。 Systemd 这个名字的含义,就是它要守护整个系统。使用了 Systemd,就不需要再用init了。Systemd 取代了initd,成为系统的第一个进程(PID 等于 1),其他进程都是它的子进程。

systemctl是 Systemd 的主命令,用于管理系统。对于用户来说,最常用的是下面这些命令,用于启动和停止 Unit(主要是 service)。

-立即启动一个服务

$ systemctl start apache.service

-立即停止一个服务

$ systemctl stop apache.service

-重启一个服务

$ systemctl restart apache.service

-杀死一个服务的所有子进程

$ systemctl kill apache.service

-重新加载一个服务的配置文件

$ systemctl reload apache.service

-重载所有修改过的配置文件

$ systemctl daemon-reload

-显示某个 Unit 的所有底层参数

$ systemctl show httpd.service

-显示某个 Unit 的指定属性的值

$ systemctl show -p CPUShares httpd.service

-设置某个 Unit 的指定属性

$ systemctl set-property httpd.service CPUShares=500

本文主要是对systemd的使用进行介绍,如果想进一步了解systemd的基本知识,可查阅相关资料

2 服务端脚本

这里我们写一个php的服务脚本server.php,用来实现一个服务


<?php
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($sock, '0.0.0.0', 10000);
for (;;) {
    socket_recvfrom($sock, $message, 1024, 0, $ip, $port);
    $reply = str_rot13($message);
    socket_sendto($sock, $reply, strlen($reply), 0, $ip, $port);
}

运行后可使用lsof指令来查看端口占用情况

lthpc@lthpc:~$ lsof -i:10000
COMMAND   PID  USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
php     40446 lthpc    3u  IPv4 37381218      0t0  UDP *:10000 

使用nc指令模拟客户端测试

$ nc -u 127.0.0.1 10000
Hello, world!
Uryyb, jbeyq!

3 创建服务
接下来使用systemd创建一个服务,写一个服务配置文件/etc/systemd/system/rot13.service

[Unit]
Description=ROT13 demo service
After=network.target
StartLimitIntervalSec=0
 
[Service]
Type=simple
Restart=always
RestartSec=1
User=ltpc
ExecStart=/usr/bin/env php /path/to/server.php
 
[Install]
WantedBy=multi-user.target

有几点需要注意,为了使服务能够自动无限次重启,需要增加以下几个配置

StartLimitIntervalSec=0

Restart=always

RestartSec=1

关于配置文件的具体参数含义,可参考该文档

设置好后,可以运行如下语句启动服务

$ systemctl start rot13

运行后,便启动了名为rot13的服务,可使用status查看服务状态

lthpc@lthpc:~/workspace_zong/tcptest$ systemctl status rot13
● rot13.service - ROT13 demo service
   Loaded: loaded (/etc/systemd/system/rot13.service; disabled; vendor preset: enabled)
   Active: active (running) since 一 2019-10-28 11:25:43 CST; 1min 28s ago
 Main PID: 44532 (php)
    Tasks: 1
   Memory: 5.2M
      CPU: 24ms
   CGroup: /system.slice/rot13.service
           └─44532 php /home/lthpc/workspace_zong/tcptest/server.php
 
10月 28 11:25:43 lthpc systemd[1]: Started ROT13 demo service.

为了开机自动启动,执行下以下语句

$ systemctl enable rot13

同样的,可以使用nc指令模拟客户端测试,可以看到服务已经正常启动运行了!

4 自动重启
为了测试是否可以正常自动重启,我们手动杀掉启动的服务进程,再查看进程号发现已经更换PID号了,说明重启过进程,并且使用nc -u 127.0.0.1 10000指令测试依然可以调用服务

$ systemctl status rot13 | grep PID
 Main PID: 44532 (php)
$ sudo kill 44532
$ systemctl status rot13 | grep PID
 Main PID: 44255 (php)

注意输入systemctl stop rot13时服务是不会重启的,所以如果有参数需要修改,直接运行stop指令改完再start就可以了


编写服务配置

vim /lib/systemd/system/website.service

[Unit]
Description=website
After=network.target
 
[Service]
Type=forking
ExecStart=/home/monitor/website/start.sh
ExecReload=/home/monitor/website/restart.sh
ExecStop=/home/monitor/website/shutdown.sh
 
[Install]
WantedBy=multi-user.target

编写对应启动停止等脚本
开启:

vim /home/monitor/website/start.sh
#!/bin/sh
export JAVA_HOME=/usr/java/jdk1.8.0_144
export PATH=$JAVA_HOME/bin:$PATH
 
nohup java -jar /home/monitor/website/demo-0.0.1-SNAPSHOT.jar &

关闭:

vim /home/monitor/website/shutdown.sh
#!/bin/sh
ps -ef | grep demo-0.0.1-SNAPSHOT.jar | grep -v grep | awk '{print $2}' | xargs kill -9

重启:

vim /home/monitor/website/restart.sh
#!/bin/sh
export JAVA_HOME=/usr/java/jdk1.8.0_144
export PATH=$JAVA_HOME/bin:$PATH
 
ps -ef | grep demo-0.0.1-SNAPSHOT.jar | grep -v grep | awk '{print $2}' | xargs kill -9
nohup java -jar /home/monitor/website/demo-0.0.1-SNAPSHOT.jar &

授权运行:

chmod +x start.sh shutdown.sh restart.sh

配置自启动
开机启动:systemctl enable website

启动:systemctl start website

关闭:systemctl stop website

重启:systemctl restart website

查看状态:systemctl status website

修改服务配置重新生效:systemctl daemon-reload

常见systemctl错误码
| code | desc |
|:------|:---------------------------------------------------------|
| 0 | 命令成功结束 |
| 1 | 通用未知错误 |
| 2 | 误用shell命令 |
| 126 | 命令不可执行 |
| 127 | 没找到命令 |
| 128 | 无效退出参数 |
| 128+x | Linux 信号x的严重错误 |
| 130 | Linux 信号2 的严重错误,即命令通过SIGINT(Ctrl+C)终止 |
| 203 | 缺失脚本执行器标识 |
| 255 | 退出状态码越界 |

备注
如运行sh脚本报出如下错误:
/bin/sh^M: 坏的解释器: 没有那个文件或目录
是由于在windows下编辑的脚本文件拷贝至linux导致的,windows下编辑文本每一行结尾是\n\r,而Linux下则是\n,
解决方法:
在终端输入sed -i 's/\r$//' daemon.sh
sed -i 's/\r$//' daemon.sh 会把make-all-linux-project.sh中的行尾的\r替换为空白,其中daemon.sh为报错的脚本。
为避免该错误,可以直接在linux新建脚本或者再linux环境下拷贝。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux之systemd服务配置及自动重启 的相关文章

  • 将 bash 脚本作为守护进程运行

    我有一个脚本 它每 X 次运行我的 PHP 脚本 bin bash while true do usr bin php f my script php echo Waiting sleep 3 done 我怎样才能将它作为守护进程启动 要从
  • X 服务器使用什么像素格式?

    X 服务器使用什么像素格式 RGBA ARBG BGRA 如果有任何特定格式的话 Update 我专门寻找有关颜色分量顺序和位模式的信息 你的意思是帧缓冲区格式 或者所有支持的像素图格式 无论是哪一种 都取决于您的图形硬件 驱动程序和配置
  • 如何防止 CMake 在构建时(而不是安装时)为共享库创建符号链接?

    我正在使用 CMake 在 Linux 上使用 Bullet3 构建一个项目 在构建整个解决方案时 它会构建附加了 SOVERSION 的 Bullet 输出库 并创建一个不带版本的符号链接 对于我的特定场景 我不喜欢这种行为 并且我不想编
  • _dl_runtime_resolve -- 共享对象何时加载到内存中?

    我们有一个对性能要求很高的消息处理系统 最近我们注意到第一条消息比后续消息花费的时间要长很多倍 当它通过我们的系统时 会发生大量转换和消息增强 其中大部分是通过外部库完成的 我刚刚描述了这个问题 使用 callgrind 将仅一条消息的 运
  • 动态加载库和共享全局符号

    由于我在动态加载的库中观察到全局变量的一些奇怪行为 因此我编写了以下测试 首先我们需要一个静态链接库 头文件test hpp ifndef BASE HPP define BASE HPP include
  • shell中基于正则表达式的颜色突出显示输出

    我想知道是否可以用颜色突出显示与某些字符串匹配的 shell 命令的输出 例如 如果我运行 myCommand 输出如下 gt myCommand DEBUG foo bar INFO bla bla ERROR yak yak 我希望所有
  • 如何从python导入路径中删除当前目录

    我想使用 Mercurial 存储库hg本身 也就是说 我克隆了 Mercurialhttps www mercurial scm org repo hg https www mercurial scm org repo hg并想运行一些h
  • /usr/bin/as:无法识别的选项“-EL”

    因此 在为我的1plus手机编译android内核时 经过3天的多次尝试 我放弃了并尝试在这里询问是否有人以前遇到过这个问题 这个错误对我来说有点模糊 但我觉得问题来自于我最近对 GNU Linux 发行版 Gentoo 的更改 它在不应该
  • 尝试编译 git 但在 linux 中找不到 libcurl

    我想编译支持 http https 的 git 我有 ls usr include curl curlbuild h curl h curlrules h curlver h easy h mprintf h multi h stdchea
  • 在 4.x 内核上的 64 位内存中查找系统调用表

    我正在尝试编写一个简单的内核模块来查找 Linux 中的 sys call table 但遇到了一些麻烦 我在这里找到了 32 位 Linux 的基本指南 https memset wordpress com 2011 03 18 sysc
  • 检查 Linux 中给定进程的打开 FD 限制

    我最近有一个 Linux 进程 泄露 了文件描述符 它打开了文件描述符 但没有正确关闭其中一些文件描述符 如果我对此进行监控 我就可以提前得知该过程已达到其极限 有没有一种很好的 Bash 或 Python 方法来检查 Ubuntu Lin
  • Python 线程与 Linux 中的多处理

    基于此question https stackoverflow com questions 807506 threads vs processes in linux我假设创建新流程应该几乎和创造新线程在Linux中 然而 很少的测试显示出截
  • 警告构建使用导出符号的内核模块

    我有两个内核模块 例如 modA 和 modB modA 导出一个符号EXPORT SYMBOL symA modB 使用它 我有标题modA h对于modA extern void symA int param and in modB c
  • 如何使用 shell 脚本解压所有 .tar.gz?

    我试过这个 DIR path tar gz if ls A DIR 2 gt dev null then echo not gz else tar zxvf path tar gz C path tar fi 如果该文件夹有一个 tar 则
  • C 标准库函数与系统调用。哪个是“open()”?

    I know fopen 在C标准库中 所以我绝对可以调用fopen C 程序中的函数 我感到困惑的是为什么我可以打电话给open 功能也一样 open 应该是系统调用 所以它不是标准库中的C函数 因为我能够成功地调用open 函数 我调用
  • gnutls_handshake() 失败:握手失败 GIT

    一切都工作正常 但突然我收到错误 致命 无法访问 https 电子邮件受保护 cdn cgi l email protection name repo name git gnutls handshake 失败 握手失败 我在我的计算机和 E
  • 使用 xargs 时如何获取退出代码(并行)

    我制作了一个用于启动并行 rsync 进程的脚本 bin bash LIST 1 DEST DIR 2 RSYNC OPTS 3 echo rsyncing From SRC DIR To DEST DIR RSYNC OPTS RSYNC
  • 我可以告诉 Linux 不要交换特定进程的内存吗?

    有没有办法告诉 Linux 它不应该将特定进程的内存交换到磁盘 它是一个 Java 应用程序 所以理想情况下我希望有一种方法可以从命令行执行此操作 我知道您可以将全局交换性设置为 0 但这明智吗 您可以通过以下方式执行此操作姆洛克尔 2 h
  • 打破条件变量死锁

    我遇到这样的情况 线程 1 正在等待条件变量 A 该变量应该由线程 2 唤醒 现在线程 2 正在等待条件变量 B 该变量应该由线程 1 唤醒 在我使用的场景中条件变量 我无法避免这样的死锁情况 我检测到循环 死锁 并终止死锁参与者的线程之一
  • 串口读取未完成

    下面的函数用于在Linux下从串口读取数据 我在调试时可以读取完整的数据 但是当我启动程序时 读缓冲区似乎并不完整 我正确接收了一小部分数据 但缓冲区的其余部分完全正确zero 可能是什么问题呢 int8 t serial port ope

随机推荐

  • Swift中设置tableview的分割线(separator)的样式、颜色、边距

    Swift中设置tableview的分割线 xff08 separator xff09 的样式 颜色 边距 设置分割线样式 三种分割线样式 xff1a case None 无分割线 case SingleLine 单条分割线 case Si
  • React-Native 程序出现闪退原因之一

    React Native 程序出现闪退原因之一 1 RN的iOS端release版本和staging版本出现闪退 原因 xff1a 使用了Number isInteger 该方法在iOS端debug模式下运行不会出现异常 xff0c 一旦生
  • 【Android】【问题分析】G-sensor因数据交互问题导致手机crash

    G sensor因数据交互问题导致手机crash 问题现象 xff1a 测试同事发现 xff0c 手机在使用和待机时 xff0c 低概率发现手机会crash 问题原因 xff1a G sensor在driver和HAL层因交互的参数不匹配
  • 【瓣芽·Banya】React Native 构建的仿豆瓣应用

    今天介绍一个用 React Native 创建的应用 xff0c 集合了豆瓣电影 xff0c 图书等信息展示功能的 app github 地址 瓣芽 Banya 项目使用了react navigation 做路由 redux 做部分状态管理
  • CSS - position

    在 CSS 中 xff0c position 是实现元素定位的一种重要方式 使用定位的元素层叠级别比浮动会更高 xff0c 采用定位来控制元素位置会更加容易 一般我们使用定位 xff0c 是通过使用定位模式和边偏移量来确定元素位置的 定位模
  • React Native 选择器组件 / react-native-slidepicker

    react native slidepicker 一个纯 JavaScript 实现的的 React Native 组件 xff0c 用于如地址 xff0c 时间等分类数据选择的场景 github https github com lexg
  • 函数式组件 ref 的解决方案

    对于 React 中需要强制修改子组件的情况 xff0c React 提供了 Refs 这种解决办法 xff0c 使得我们可以操作底层 DOM 元素或者自定的 class 组件实例 除此之外 xff0c 文档 xff08 v17 0 1 x
  • JavaScript生成指定范围的随机数和随机数序列

    在JavaScript中我们经常使用Math random 方法生成随机数 xff0c 但是该方法生成的随机数只是0 1之间的随机数 先看如下常用方法的特征 xff1a 1 Math random 结果为0 1间的一个随机数 包括0 不包括
  • JavaScript生成指定范围随机数和随机序列

    在JavaScript中我们经常使用Math random 方法生成随机数 xff0c 但是该方法生成的随机数只是0 1之间的随机数 先看如下常用方法的特征 1 Math random 结果为0 1间的一个随机数 包括0 不包括1 2 Ma
  • 【React Native】JavaScript 中 bind 方法

    这个问题其实是一个 JavaScript 中的问题 JavaScript中jQury的bind方法为选定元素添加事件处理程序 xff0c 规定事件发生时运行的函数 语法为 xff1a selector bind event data fun
  • 瑞利信道:从原理到实现

    瑞利信道模型 瑞利信道模型是无线通信信道最重要 最基础的的仿真模型 无线信道中的平坦衰落信道基本上都是在瑞利信道模型的基础上修改而成 xff0c 比如应用同样广泛的莱斯信道就可以通过在瑞利信道的基础上简单的添加直流分量实现 xff0c 而频
  • N个数中的第k个最大值

    确定一组N个数中的第k个最大值 xff0c 这是数据结构和算法分析 java语言描述 中讨论的第一个问题 书中第一章也已给处两种常规思路 xff1a 1 xff0d 先将N个数的数组整体进行递减排序 xff0c 然后返回位置k 数组索引为k
  • 【React Native】app\build\intermediates\res\merged\debug\values-v24\values-v24.xml中错误

    昨天在项目中使用了 react native svg 库 xff0c 配置完成正在正常启动的时候 xff0c 却出现四个错误 xff0c 全部来源于app build intermediates res merged debug value
  • 【React Native】定位获取经纬度,当前城市等地址信息

    2019 8 21 使用内置对象 navigator 来获取经纬度信息 xff0c 参见 定位获取经纬度 xff0c 获取到经纬度等位置信息后需要用到第三方api位置解析 xff08 本文后半段 xff09 2019 7 20更新 xff1
  • 【React Native】定位获取经纬度

    RN 文档上的定位功能需要谷歌框架支持 xff0c 无疑带来了一些麻烦 github 上也有一些开源库 xff0c react native geolocation service等 但是这里还有一个更简便的位置获取 API 使用内置对象n
  • centos7系统下Python2.7升级到Python3.6踩的坑(yum失效,并非简单修改yum文件头)

    centos系统自带的Python2 7用的好好的 xff0c 我非手贱要去升级 xff0c 结果很严重 xff0c 正在运行服务器里面的yum崩了 xff0c 反复尝试了网上提到的几乎完全一致的解决方法 xff1a 将 usr bin y
  • 关于 Android Studio 4.0 创建新的activity和fragment 发现不存在

    1 在 app文件下面的 build gradle里面 注释以下代码
  • RAR文件格式-笔记

    RAR RAR 文件头 52 61 72 21 1A 07 00RAR 文件尾 C4 3D 7B 00 40 07 00 Rar 文件主要由标记块 xff0c 压缩文件头块 xff0c 文件头块 xff0c 结尾块组成 其每一块大致分为以下
  • pptv电话面试

    1 8种基本数据类型 2 String是基本数据类型吗 3 try return 1 catch return 2 finally return3 4 线程池 5 spring实现原理 6 s
  • Linux之systemd服务配置及自动重启

    Linux之systemd服务配置及自动重启 0 背景 在linux上开发时 xff0c 往往需要将自己的程序做成服务 xff0c 并且实现服务开机自动重启 xff0c 以及服务崩溃后自动重启功能 xff0c 本文就对该功能的实现做简单介绍