layout: post

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

date: 2019-09-09

tags: linux

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

0 背景

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

1 systemd介绍

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

  1. $ sudo /etc/init.d/apache2 start

或者

  1. $ service apache2 start

这种方法有两个缺点。

一是启动时间长。init进程是串行启动,只有前一个进程启动完,才会启动下一个进程。

二是启动脚本复杂。init进程只是执行启动脚本,不管其他事情。脚本需要自己处理各种情况,这往往使得脚本变得很长。

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

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

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

-立即启动一个服务

  1. $ systemctl start apache.service

-立即停止一个服务

  1. $ systemctl stop apache.service

-重启一个服务

  1. $ systemctl restart apache.service

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

  1. $ systemctl kill apache.service

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

  1. $ systemctl reload apache.service

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

  1. $ systemctl daemon-reload

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

  1. $ systemctl show httpd.service

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

  1. $ systemctl show -p CPUShares httpd.service

-设置某个 Unit 的指定属性

  1. $ systemctl set-property httpd.service CPUShares=500

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

2 服务端脚本

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

  1. <?php
  2. $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
  3. socket_bind($sock, '0.0.0.0', 10000);
  4. for (;;) {
  5. socket_recvfrom($sock, $message, 1024, 0, $ip, $port);
  6. $reply = str_rot13($message);
  7. socket_sendto($sock, $reply, strlen($reply), 0, $ip, $port);
  8. }

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

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

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

  1. $ nc -u 127.0.0.1 10000
  2. Hello, world!
  3. Uryyb, jbeyq!

3 创建服务

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

  1. [Unit]
  2. Description=ROT13 demo service
  3. After=network.target
  4. StartLimitIntervalSec=0
  5. [Service]
  6. Type=simple
  7. Restart=always
  8. RestartSec=1
  9. User=ltpc
  10. ExecStart=/usr/bin/env php /path/to/server.php
  11. [Install]
  12. WantedBy=multi-user.target

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

  1. StartLimitIntervalSec=0
  2. Restart=always
  3. RestartSec=1

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

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

  1. $ systemctl start rot13

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

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

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

  1. $ systemctl enable rot13

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

4 自动重启

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

  1. $ systemctl status rot13 | grep PID
  2. Main PID: 44532 (php)
  3. $ sudo kill 44532
  4. $ systemctl status rot13 | grep PID
  5. Main PID: 44255 (php)

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


编写服务配置

  1. vim /lib/systemd/system/website.service
  2. [Unit]
  3. Description=website
  4. After=network.target
  5. [Service]
  6. Type=forking
  7. ExecStart=/home/monitor/website/start.sh
  8. ExecReload=/home/monitor/website/restart.sh
  9. ExecStop=/home/monitor/website/shutdown.sh
  10. [Install]
  11. WantedBy=multi-user.target

编写对应启动停止等脚本

开启:

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

关闭:

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

重启:

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

授权运行:

  1. 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服务配置及自动重启的更多相关文章

  1. 监控windows服务,当服务停止后自动重启服务

    近期花时间研究了一下windows和linux下某服务停了后自动重启的功能,在网上收集了些资料,并经过测试,在此整理一下.这里介绍的是windows服务的监控,是通过批处理来实现的.本例是监控wind ...

  2. systemd实践: 依据情况自动重启服务【转】

    1.最简单的自动重启范例 [Unit] Description=mytest [Service] Type=simple ExecStart=/root/mytest.sh Restart=alway ...

  3. Linux系统Apache服务 - 配置 HTTP 的虚拟机主机

    接Linux系统Apache服务 - 配置HTTP的默认主页 1.创建/srv目录,作为httpd的文件目录,并创建/srv/default/www和/srv/www1.example.com/www ...

  4. PHPWAMP自启异常,服务器重启后Apache等服务不会自动重启的原因分析

    在使用“PHPWAMP自动任务”时,不少学生遇到如下问题: “phpwamp绿色集成环境重启动电脑(服务器)后,不会自动启动网站服务” (如果是其他环境或是自己搭建时遇到此问题,也是可以用此法解决) ...

  5. systemd实践: 依据情况自动重启服务

    systemd服务异常自动重启很好用,但有的时候希望某些服务只在特定情况下进行重启,其他时候不要自动重启(比如OOM,需要人工介入). 本文抛砖引玉,旨在能够让读者对systemd的重启机制有一定了解 ...

  6. CentOS 7下设置Docker代理(Linux下Systemd服务的环境变量配置)

    Docker守护程序使用HTTP_PROXY,HTTPS_PROXY以及NO_PROXY环境变量在其启动环境来配置HTTP或HTTPS代理的行为.无法使用daemon.json文件配置这些环境变量. ...

  7. linux中 systemd相关配置

    systemd相关配置 推荐使用systemd管理进程,相比使用supervisord systemd提供系统级别的支援. 一.系统管理 Systemd 并不是一个命令,而是一组命令,涉及到系统管理的 ...

  8. Linux SSH,FTP服务配置

    CentOS-6.4-x86_64-minimal 0.网卡配置 参考:Linux系统\Centos没有网卡eth0配置文件怎么办? - http://jingyan.baidu.com/articl ...

  9. linux下Samba服务配置

    SMB是基于客户机/服务器型的协议,因而一台Samba服务器既可以充当文件共享服务器,也可以充当一个Samba的客户端,例如,一台在Linux 下已经架设好的Samba服务器,windows客户端就可 ...

随机推荐

  1. 详解webpack4打包--新手入门(填坑)

    注意,这个dev和build好像在哪儿见过??对了, 刚刚才在package.json里配置的“scripts”这一项的值就有“dev”和“build”.对,一点都不错,就是这2个值,这2个值代表的是 ...

  2. Wannafly挑战赛27 D绿魔法师

    链接Wannafly挑战赛27 D绿魔法师 一个空的可重集合\(S\),\(n\)次操作,每次操作给出\(x,k,p\),要求支持下列操作: 1.在\(S\)中加入\(x\). 2.求\[\sum_{ ...

  3. Julia 语言

    同时安装多个库 Pkg.add.(["IJulia", "Combinatorics", "Plots", "TaylorSeri ...

  4. Java缓冲字符读取

    public class BufferedReaderDemo { public static void main(String[] args) throws IOException { // 创建流 ...

  5. 基于ELK Stack7.1.0构建多用户安全认证日志系统

    ​ 配置tls加密通信及身份验证,主要目的是为了确保集群数据安全.在es早期版本,安全认证相关功能都属于商业付费服务,一般普通公司如果集群部署在内网,基本上就忽略了这些安全认证,当然也可以通过Ngin ...

  6. JavaScript学习第一篇

    在学习之前让我们了解了解JavaScript的由来 Javascript是一种web技术,最初起名叫LiveScript,它是Netscape开发出来一种脚本语言,其目的是为了扩展基本的Html的功能 ...

  7. CodeForces - 35D

    题目:https://vjudge.net/contest/326867#problem/A 题意:有一个农场,自己有m斤粮食,有n天,每天动物吃的量不同,那个动物的食量的是由他是从那天开始进这个农场 ...

  8. 浅析java中的string

    在学习java36讲的时候看到评论区有人提出的一个问题: String s1 = new String("do"); s1.intern(); String s2 = " ...

  9. idea2019.2 svn 忽略文件问题

    自己用的是idea2019.2最新版本,今天提交的时候Commit Changes Dialog local changes refresh一直再刷新 其他的方法都是老版本都不适合 解决办法 找到Se ...

  10. Linux┊详解udev

    是一小部分例子,如果你的系统采用了udev方式,那你应该可以看到更多的规则.如果你想修改设备的权限或者创建信的符号连接,那么你需要熟读这些规则,特别是要仔细注意你修改的那些与之相关的设备. 修改你的u ...