Linux之systemd服务配置及自动重启
layout: post
title: Linux之systemd服务配置及自动重启
date: 2019-09-09
tags: linux
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环境下拷贝。
Linux之systemd服务配置及自动重启的更多相关文章
- 监控windows服务,当服务停止后自动重启服务
近期花时间研究了一下windows和linux下某服务停了后自动重启的功能,在网上收集了些资料,并经过测试,在此整理一下.这里介绍的是windows服务的监控,是通过批处理来实现的.本例是监控wind ...
- systemd实践: 依据情况自动重启服务【转】
1.最简单的自动重启范例 [Unit] Description=mytest [Service] Type=simple ExecStart=/root/mytest.sh Restart=alway ...
- Linux系统Apache服务 - 配置 HTTP 的虚拟机主机
接Linux系统Apache服务 - 配置HTTP的默认主页 1.创建/srv目录,作为httpd的文件目录,并创建/srv/default/www和/srv/www1.example.com/www ...
- PHPWAMP自启异常,服务器重启后Apache等服务不会自动重启的原因分析
在使用“PHPWAMP自动任务”时,不少学生遇到如下问题: “phpwamp绿色集成环境重启动电脑(服务器)后,不会自动启动网站服务” (如果是其他环境或是自己搭建时遇到此问题,也是可以用此法解决) ...
- systemd实践: 依据情况自动重启服务
systemd服务异常自动重启很好用,但有的时候希望某些服务只在特定情况下进行重启,其他时候不要自动重启(比如OOM,需要人工介入). 本文抛砖引玉,旨在能够让读者对systemd的重启机制有一定了解 ...
- CentOS 7下设置Docker代理(Linux下Systemd服务的环境变量配置)
Docker守护程序使用HTTP_PROXY,HTTPS_PROXY以及NO_PROXY环境变量在其启动环境来配置HTTP或HTTPS代理的行为.无法使用daemon.json文件配置这些环境变量. ...
- linux中 systemd相关配置
systemd相关配置 推荐使用systemd管理进程,相比使用supervisord systemd提供系统级别的支援. 一.系统管理 Systemd 并不是一个命令,而是一组命令,涉及到系统管理的 ...
- Linux SSH,FTP服务配置
CentOS-6.4-x86_64-minimal 0.网卡配置 参考:Linux系统\Centos没有网卡eth0配置文件怎么办? - http://jingyan.baidu.com/articl ...
- linux下Samba服务配置
SMB是基于客户机/服务器型的协议,因而一台Samba服务器既可以充当文件共享服务器,也可以充当一个Samba的客户端,例如,一台在Linux 下已经架设好的Samba服务器,windows客户端就可 ...
随机推荐
- UNIX网络编程总结二
绝大多数客户-服务程序使用TCP和UDP,这两个协议转而使用IP.UDP是一种简单的,不可靠的数据报协议,TCP是一种精致的可靠的字节流协议. 在TCP/IP协议族中: mrouted:IGMP→IP ...
- 1145. Hashing - Average Search Time (25)
The task of this problem is simple: insert a sequence of distinct positive integers into a hash tabl ...
- dd hdparm 速度不一致
https://www.cnblogs.com/yinzhengjie/p/9935478.html hparm # 它用来在基于Linux的系统上获取或设置硬盘参数,包括测试读性能以及缓存性 ...
- Flutter-ListTile
ListTile 通常用于在 Flutter 中填充 ListView.在这篇文章中,我将用可视化的例子来说明所有的参数. title title 参数可以接受任何小部件,但通常是文本小部件 List ...
- CSS--使用CSS Grid(网格)布局
.一 CSS Grid(网格布局)简介 CSS Grid 布局由两个核心组成部分是父元素和子元素,父元素 是实际的 grid(网格),子元素是 grid(网格) 内的内容.下面是一个父元素和六个子元素 ...
- python数据分析第二版:numpy
一:Numpy # 数组和列表的效率问题,谁优谁劣 # 1.循环遍历 import numpy as np import time my_arr = np.arange(1000000) my_lis ...
- 启动模式:uefi, legacy,以及GRUB命令使用
机器启动模式:uefi, legacy 设置入口:BIOS:boot mode 磁盘分区表格式: gpt uefi所使用(此种模式下,grub只能识别gpt格式的boot引导项) mbr legacy ...
- JAVA泛型通配符T,E,K,V区别,T以及Class<T>,Class<?>的区别
1. 先解释下泛型概念 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛 ...
- SpringBoot 快速集成 Elastic Job
一.引入依赖 <dependency> <groupId>com.github.kuhn-he</groupId> <artifactId>elasti ...
- 使用linkedlist封装简单的先进先出队列
创建一个类Queue代表队列(先进先出),添加add(Object obj) 及get()方法, 并添加main()方法进行验证 思路: 使用LinkedList实现队列,在向LinkedList中添 ...