Linux下MySQL定时自动完整备份(mysqldump+crontab)

一、前言

1、本文目标

  • 实现数据库全量备份
  • 实现定时执行备份
  • 实现定时清理7天之前的备份

2、环境信息

未分类

二、备份

  • 目录准备
mkdir /mysql
mkdir /mysql/backup
mkdir /mysql/backup/scripts
mkdir /mysql/backup/files
mkdir /mysql/backup/logs
  • 备份脚本

新建脚本

vi /mysql/backup/scripts/backup_full.sh

脚本内容

#!/bin/bash

#备份目录
BACKUP_ROOT=/mysql/backup
BACKUP_FILEDIR=$BACKUP_ROOT/files
BACKUP_LOGDIR=$BACKUP_ROOT/logs

#当前日期
DATE=$(date +%Y%m%d)

######备份######

#查询所有数据库
#-uroot -p123456表示使用root账号执行命令,且root账号的密码为:123456
DATABASES=$(mysql -uroot -p123456 -e "show databases" | grep -Ev "Database|sys|information_schema")
#DATABASES=$(mysql -uroot -p123456 -e "SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME NOT IN ('sys','mysql','information_schema','performance_schema');" | grep -v "SCHEMA_NAME","ken.io") 
echo $DATABASES
#循环数据库进行备份
for db in $DATABASES
do
echo
echo ----------$BACKUP_FILEDIR/${db}_$DATE.sql.gz BEGIN----------
mysqldump -uroot -pRoot@1024 --default-character-set=utf8 -q --lock-all-tables --flush-logs -E -R --triggers -B ${db} | gzip > $BACKUP_FILEDIR/${db}_$DATE.sql.gz
echo ----------$BACKUP_FILEDIR/${db}_$DATE.sql.gz COMPLETE----------
echo
done

echo "done"

备份测试&验证

#执行备份脚本
sh /mysql/backup/scripts/backup_full.sh

#查看备份文件
ll /mysql/backup/files -h

#解压指定文件({file}自己替换成备份的文件)
gunzip /mysql/backup/files/{file}

三、定时任务

  • 安装crontab
yum install -y crontab

1、定时执行MySQL完整备份

  • 创建定时备份任务
#添加定时任务
crontab -e

#每天凌晨3点执行
00 3 * * * sh /mysql/backup/scripts/backup_full.sh

#查看定时任务
crontab -l

2、定时清理7天以前的备份

  • 创建文件清理脚本
#创建脚本文件
vi /mysql/backup/scripts/backup_full_clean.sh

#写入以下内容
#!/bin/bash
find /mysql/backup/files -mtime +7 -name "*.gz" -exec rm -rf {} ;

创建定时清理任务

#添加定时任务
crontab -e

#每天凌晨1点执行
00 1 * * * sh /mysql/backup/scripts/backup_full_clean.sh

#查看定时任务
crontab -l

四、备注

1、crontab命令示例

未分类

2、本文参考

  • https://blog.csdn.net/zmcyu/article/details/75353245
  • http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/crontab.html

本文由 ken.io 创作,采用CC BY 3.0 CN协议 进行许可。 可自由转载、引用、甚至修改,但需署名作者且注明出处。

linux命令之htpasswd

htpasswd是Apache的Web服务器内置的工具,用于创建和更新储存用户名和用户基本认证的密码文件

安装

  1. 由于该工具是Apache的Web服务器内置的工具,所以直接安装Apache,在对应的bin目录下可以看到该命令的

  2. 还可以直接安装httpd-tools这个工具包,比如:yum install httpd-tools,安装成功后就可以直接使用该命令

语法

htpasswd (选项) (参数)

选项

  • -c: 创建一个新的密码文件
  • -b: 在命令行中一并输入用户名和密码而不是根据提示输入密码
  • -D: 删除指定的用户
  • -n: 不更新密码文件,只将加密后的用户名密码输出到屏幕上
  • -p: 不对密码进行加密,采用明文的方式
  • -m: 采用MD5算法对密码进行加密(默认的加密方式)
  • -d: 采用CRYPT算法对密码进行加密
  • -s: 采用SHA算法对密码进行加密
  • -B: 采用bcrypt算法对密码进行加密(非常安全)

参数

  • 用户名: 要创建或者更新的用户名
  • 密码: 用户的新密码

实例

1、 新建一个密码文件.passwd并添加一个用户,不提示直接输入用户名密码
htpasswd -bc .passwd jiang wen

2、 在原有的密码文件.passwd下在添加一个用户
htpasswd -b .passwd wen jiang

3、更新用户的密码:有两种方式
第一种,直接添加相同的用户名,就会自动区更新密码:htpasswd -b .passwd wen wen
第二种,先删除需要更新密码的用户名,在添加用户:htpassdw -D .passwd wen & htpasswd -b .passwd wen wen

4、不更新密码文件,只显示加密后的用户名和密码
htpasswd -bn jiang jiang

5、nginx模块 http_auth_basic_module中的使用,用于生成用户密码文件进行认证

不用装双系统,直接在 Windows 上体验 Linux:Windows Subsystem for Linux

「Microsoft Loves Linux!」

说出这句话的不是所谓的 IT 领域那些技术专家或者是意见领袖,而是时任微软 CEO 的萨蒂亚· 纳德拉,在 2015 年的一次活动中,这位第三任微软 CEO 脱口而出的这句话,让这个曾经开源界最大敌人的微软,正式拥抱这个开源世界最大的操作系统:Linux。

未分类

其实在云计算领域,微软很早之前就让其 Azure 支持多个流行的 Linux 发行版,但对于普通消费者而言,真正的变化发生在后面的 Windows 10:微软宣布将会在 Windows 10 内置 Linux,而采用的技术上并非是所谓的「虚拟化」技术——也就是说,这个子系统的 Linux 完全是原生运行在 Windows 10 上的。

未分类
WSL 技术实现原理
而微软给这个 Linux 系统命名为:Windows Subsystem for Linux,而对于有些系统极客而言,这个名字实在太熟悉了,因为在 Windows 7 之前,微软也曾经内置过一个 UNIX 子系统,可以原生运行 UNIX 二进制程序,他的名字叫做:Windows Services for UNIX。

即便如此,对于很多普通用户而言,Windows Subsystem for Linux 也只是尝鲜的玩物罢了,但对于不少软件开发、系统极客而言,无需通过虚拟机以及双系统的形式体验 Linux ,并且可以实现系统级别的文件互操作,实在是太具有吸引力了。而今天我们就一起来体验探索一番。

如何启动 Linux 子系统

微软从 Windows 10 周年更新(build 14393)开始内置 Windows Subsystem for Linux 组件框架,只不过这项功能当时还只能称作是 Beta 版,而在 Windows 秋季创意者更新中,安装 Linux 子系统变的更为简单——可以直接通过 Microsoft Store 来下载子系统,而可选择的发行版也从最初的只有 Ubuntu 变成可以选择 Suse、Ubuntu、Debian、甚至是用来进行网络安全工作 Kail Linux。

未分类
目前 Microsoft Store 有多款 Linux 发行版可供选择

只不过如果你想要体验这些发行版还需要进行一些简单操作,毕竟 Windows Subsystem for Linux 组件框架并非是默认选中的。

首先我们需要确认自己的 Windows 10 版本,以下的操作方法只适用与 Windows 10 秋季创意者更新(Windows 10 build 16299)以上版本,如果你是 Windows 10 周年更新,安装 Linux 子系统的安装办法你可以检索「 Bash on Windows」自行探索安装方法。此外,系统必须是 64 位操作系统。

未分类
开启「适用于 Linux 的 Windows 子系统」

以上均确认后,打开 「控制面板」—> 「程序和功能」,在左边的「启用和关闭 Windows 功能」里面勾选「适用于 Linux 的 Windows 子系统」,然后点击确定(这一步有可能需要重启)。

未分类

接着打开 Microsoft Store,搜索喜欢的 Linux 发行版,这里我选择的是我比较熟悉的 Linux 发行版 Ubuntu,然后点击安装。对于初学者来说,Ubuntu/ Debian 系的发行版具有非常完善的包管理系统,方便新手快速上手。

未分类

安装完毕之后,你就可以在 Windows 开始菜单中找到「Ubuntu」这个应用了!换言之,现在你的 Windows 10 中就已经成功安装发行版为 Ubuntu 的 Linux 子系统。

Ubuntu 子系统设置与基本命令

在开始菜单中打开 Ubuntu 后,Ubuntu 会进行较长时间的安装和初始化,之后会提示你设置 Linux 的用户名和密码,需要注意的是这个用户名和密码和 Windows 并不通用。

未分类

设置密码是非明文的,不会像 Windows 那样使用「*** 」替代,所以你只要盲打点击确认即可,建议密码使用复杂密码,有些发行版会有强制要求。

输入完成之后,系统会提示你如何提权操作,之后会自动以刚才新设置的用户名登录 Ubuntu。

我安装 Linux 第一件事就是查看内核版本以及系统系统版本,在 Ubuntu 下直接输入以下命令来查看内核版本号:

uname -r

这时系统会显示:4.4.0-43-Microsoft,这表示Linux 内核版本为:4.4.0-43。

至于系统版本号,可以使用:sudo lsb_release -a 来查看,系统会输出:

未分类

这表示 Ubuntu 版本为 16.04。为 Ubuntu 的长期支持版本。

更换 Linux 子系统的软件源并更新软件

之前我说过使用 Ubuntu /debian 系最大的好处就是可以使用「软件源」进行软件安装,使用 Ubuntu 自带的 deb 包管理系统安装软件可以减少直接下载源码编译的麻烦,所以这里就要用到「apt-get」系列命令了。

因为默认的软件源是 Ubuntu 的官方源,我们可以选择替换为国内的软件源,比如说阿里云镜像的软件源。

在当前命令行下面输入:

sudo-i

提权后输入密码,使用 root 权限登录。然后接下来备份当前源,输入以下命令:

cp /etc/apt/sources.list /etc/apt/sources.list.old

不难看出管理源的文件就是 sources.list,我们选择编辑它,编辑器我这里选用的是 vim,所以命令是:

vim /etc/apt/sources.list

使用 vim 后会进入命令模式,敲键盘上的 「i」键键入编辑模式,然后复制下面这段代码(拷贝代码,然后在编辑器上鼠标右击就可以复制):

  # deb cdrom:[Ubuntu 16.04 LTS _Xenial Xerus_ - Release amd64 (20160420.1)]/ xenial main restricted
  deb-src http://archive.ubuntu.com/ubuntu xenial main restricted #Added by software-properties
  deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted
  deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe #Added by software-properties
  deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted
  deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe #Added by software-properties
  deb http://mirrors.aliyun.com/ubuntu/ xenial universe
  deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe
  deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse
  deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse
  deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
  deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse #Added by software-properties
  deb http://archive.canonical.com/ubuntu xenial partner
  deb-src http://archive.canonical.com/ubuntu xenial partner
  deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted
  deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe #Added by software-properties
  deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe
  deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse

完成之后再敲键盘上的「esc」退出编辑模式,然后再输入:wq点击保存并退出编辑器 vim。

未分类
编辑软件源

紧接着我们更新软件源让编辑的文件生效:

apt-get update

这里我们就将 Ubuntu 的软件源切换到阿里云的源了。

之后再输入:apt-get upgrade 对当前系统的软件和类库进行来更新。如果不出意外系统会自动对现有的软件包进行更新,经过这一系列的操作,目前 Ubuntu 的软件以及类库都是最新的,而系统版本也升级到 Ubuntu 16.04.4 LTS。

启用 SSH 并使用SSH 客户端登录

虽说通过 App 或者应用的形式在 Windows 10 上体验 Linux 是一个不赖的选择,但对于很多软件开发的朋友而言,使用 Windows 内置的 CMD 或者 PowerShell 来操作Linux 依旧有着很多不习惯。而最为关键的是当需要对文件进行操作时,使用交互命令远不如使用 SFTP 来的更为「简单粗暴」。因此只要通过配置 SSH 远程登录,就可以像管理远程服务器那样来操作这个 Linux 系统了。

首先,因为 Ubuntu 系统限制,所以我们需要可以为 root 用户设置新密码,这里输入:

sudo passwd root

配置好之后,未来使用 SSH 客户端或者 SFTP 客户端登录系统时,我们就可以直接使用 root 权限进行登录,就不用使用之前的 sudo -i 提权操作了。

其次按照常规,我们使用cp 命令将 SSH 相关配置文件进行备份:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

之后使用 vim 编辑器编辑 「sshd_config」文件:

sudo vim /etc/ssh/sshd_config

键盘上点击 「i」后进入编辑模式,编辑并调整以下设置项:

 Port 8022(因为 Windows 10 的 SSH 端口已经默认被占用,所以我换成了一个新的端口)
  (去掉前面的 #)ListenAddress 0.0.0.0
  UsePrivilegeSeparation no(原来是 yes 改成 no)
  PermitRootLogin yes(修改成 yes)
  (在前面加上 #)StrictModes yes
  PasswordAuthentication yes(原来是 no,改成 yes)

之后点击 「Esc」退出编辑模式,直接输入 :wq 退出并保存。

未分类
编辑配置文件并启动 SSH

然后输入命令:service ssh start 启动 SSH。

如何验证已经可以访问呢?我们首先打开 SSH 客户端,比如我目前使用 Xshell,选择「新建会话」。

之后在新建的会话设置框的「连接」中添加如下内容:

  名称:WSL(这个随便填)
  协议:SSH
  主机:127.0.0.1(本机环回接口)
  端口号:8022

之后在「用户身份验证」中输入验证方法,方法选择 「Password」,然后在输入用户名:root,密码选择刚才新设置的 root 密码,最后点击确定。

未分类

然后在左侧的会话管理器找到刚才设置的新会话,双击后如果显示如下图所示的界面就算是成功了!

未分类

除了使用 Xshell 这种 SSH 客户端进行服务器操作之外,还可以使用 Xftp 进行文件上传和管理,唯一的区别是在新建会话处,协议选择「SFTP」,端口号和之前 Xshell 使用的端口号一致即可,点击确认之后出现类似 FTP 管理的界面就算是成功了!这样你就可以使用更为直观的工具来访问 WSL 系统的文件目录。新建文件上传文件也变得更为简单。

未分类

开启图形化界面

比起 Windows和 macOS,Linux 很多时候给普通用户都是冰冷的命令行形象,这让很多 Linux 初学者望而却步;但实际上 Linux 是可以使用我们所说的 GUI 图形化界面的,只不过图形化界面并没有默认安装,这里我尝试手动安装一个图形化桌面。

未分类

由于属于 Linux 子系统的限制,因此安装一些比较「重」的图形化界面组件会大量消耗系统资源,因此我选择较为轻量级的图形化桌面组件:MATE,也是 Ubuntu MATE 的默认桌面组件,当然另一个轻量级桌面 xfce 体验也不错。

首先在终端中输入以下命令安装 Mate 桌面:

sudo apt-get install mate-desktop-environment

这一步命令就是安装完整的 MATE 桌面,这个过程相当长,因为 WSL 默认没有桌面环境,对应的相关组件也没有安装,所以安装桌面会将相关的组件以及依赖都一并安装。

未分类
安装图形化界面以及 VNC 服务端

紧接着我们需要安装可以访问图形化界面的软件,这里使用图形化远程访问工具:VNC;你可以理解成 Windows 电脑中的远程访问。当然 VNC 服务端 WSL 也是不会默认安装的,所以需要输入以下命令安装:

sudo apt-get install vnc4server

安装完毕之后需要修改 VNC 的默认启动桌面,这时候输入:

sed -i 's$x-window-manager$mate-session$' ~/.vnc/xstartup

将默认启动桌面改成 Mate 桌面启动,然后输入:vncserver 启动服务端(第一次启动需要设置连接密码)。这里 WSL 端就基本设置完毕了。

之后我们需要在 PC 上安装 VNC 的客户端,我这里选择的是 Realvnc,然后直接选择 Chrome 应用版本,在 Chrome 商店中添加为 Chrome 独立应用。

未分类

打开 realvnc 并在地址栏中输入:127.0.0.1:1 ,点连接并输入连接密码,如果不出意外,你就可以看到安装有 mate 桌面的 Ubuntu 界面了!

未分类

可视化桌面的终端里面,你可以输入 sudo apt-get install firefox 来安装 Firefox 浏览器,不一会儿你可以在左上角菜单栏的「Applications」中的「Internet」中找到 Firefox 浏览器啦!好了,接下来还能做什么就自己去探索吧!

未分类
图形化的 Linux 界面

一起动手做:搭建本地静态网站

经过以上的折腾,其实你应该对 WSL 有了比较清楚的认识了,其实对于很多开发者而言,WSL 最大的好处在于更接近项目生产环境,虽说 Windows 本身有 IIS 网页服务器可供选择。但目前大部分网站服务器系统都采用的是 Linux,而网页服务器也多是使用 Apache,所以在 WSL 在本机完成部署调试后可能会接近实际一些。所以这里我们做一个小实践:将开发好的一个静态网站部署到 WSL 里面并可以直接访问。

首先,我们要确保 WSL 中安装有 Apache 网页服务器,所以尝试安装(使用超级用户权限),在终端中输入:

apt-get install apache2

未分类

安装完毕之后在终端中输入以下命令开启 Apache 网页服务器:

service apache2 start

当终端里面显示诸如「 * Starting Apache httpd web server apache2」之后,打开本机的网页浏览器,访问:http://127.0.0.1 ,当显示以下页面就表示 Apache 网页服务器已经生效!

未分类

接下来我们尝试将自己开发的静态网页项目传到对应的目录中,这里我们打开 Xftp 这个远程文件工具,连接到 WSL 这个站点,然后访问 /var/www/html 这个目录,然后将项目文件夹传到该目录下方。

未分类

例如我现在传过去的网页全景项目名为「xuyi」,那么传好后我打开浏览器,访问:http://127.0.0.1/xuyi 就可以看到做好的网页的效果啦!如果你是使用 chrome 访问的话,Wappalyzer 扩展还可以显示出当前网站项目使用的框架等。

未分类

结语

至此,我们已经较为完整的体验了 Windows Subsystem for Linux 的一些基础玩法,其实在我看来,Windows 10 下的 Linux 子系统更多的是补充原本 Windows 10 在开发领域上的一些不足,让软件开发/网络开发人员可以以较低的成本来实现与生成环境的一致性,也不用再为了开发而安装双系统甚至虚拟机了。当然在本次体验中我并没有更深入的探索,比如说在 WSL 中安装 PHP 环境以及 Mysql 数据库,所以如果你对 Linux 感兴趣,想要在 Windows 10 上探索 Linux,系统原生支持的 WSL 不妨一试。

配置ufw防火墙,守护你的Ubuntu

起因

  很久以来许许多多人催促着我赶快配置好防火墙规则以保护vps,但是。。。配置繁琐的iptables使我望而却步(其实就是懒

直到我发现了ufw这个神器

UFW 全称为 UncomplicatedFirewall[1],是 Ubuntu 系统上默认的防火墙组件, 为了轻量化配置 iptables 而开发的一款工具。UFW 提供一个非常友好的界面用于创建基于IPV4,IPV6的防火墙规则。
废话不多说,上教程

环境

Ubuntu 16.04

安装

apt install ufw

配置

首先先打开ssh端口

ufw allow ssh

如果你的ssh端口不是默认的22,就

ufw allow 你的ssh端口

打开53端口,使dns功能不受影响

ufw allow 53/tcp

ufw allow 53/udp

可选:打开80,443端口

ufw allow http/tcp

ufw allow https/tcp

然后

ufw default deny

阻断除上述规则外的外部连接(本机外发流量无影响)

ufw enable

启动防火墙,done!

操作指令

  • 启动防火墙 ufw enable
  • 关闭防火墙 ufw disable
  • 更新配置 ufw reload
  • 查看防火墙状态 ufw status

linux分割文件split命令

分割文件split

  档处理文件时,有时需要将文件做分隔处理,split命令用于分割文件,可以分割文本文件,按指定的行数分隔,每个分隔的文件都包含相同的行数。split可以分隔非文本文件,分割时可以指定每个文件的大小,分隔后的文件有相同的大小。split后的文件可以使用cat命令组装在一起。

      [root@CentOS cmd]# cat src.txt

      [root@CentOS cmd]# split src.txt

      [root@CentOS cmd]# ls

      #split默认按1000行分隔文件

      [root@CentOS cmd]# ls

      [root@CentOS cmd]# wc -l *

      [root@CentOS cmd]# ls -lhtr

      #按每个文件3行分隔文件

      [root@CentOS cmd]# split -l 3 src.txt

      [root@CentOS cmd]# ls

      [root@CentOS cmd]# cat xa*

      #中间结果省略

      [root@CentOS cmd]# cat xaa

      #如文件行数太多,使用默认的2个字符已经不能满足需求

      [root@CentOS cmd]# split -l 3 src.txt

      [root@CentOS cmd]# rm -f xa*

      [root@CentOS cmd]# ls

      #指定分隔前缀的长度

      [root@CentOS cmd]# split -a 5 -l 3 src.txt

      [root@CentOS cmd]# ls

      [root@CentOS cmd]# rm -f xaaaa*

      #使用数字前缀

      [root@CentOS cmd]# split -a 5 -l 3 -d src.txt

      #指定每个文件的大小,默认为字节,可以使用1m类似的参数默认为B,另外有单位b,k,m等

      SIZE可加入单位:b代表512,k代表1k,m代表1Meg

      [root@CentOS cmd]# split -a 5 -b 3 src.txt

      [root@CentOS cmd]# ls -l xaaaaa

      [root@CentOS cmd]# src.txt xaa xaaaaa xaaaab xaaaac xaaaae xaaaaf xaaaag

      [root@CentOS cmd]# cat xa* >dst.txt

      [root@CentOS cmd]# md5sum src.txt dst.txt

      #指定分隔前缀

      [root@CentOS cmd]# split -a 5 -b 3000 src.txt src_

      [root@CentOS cmd]# ls

当把一个大的文件分拆为多个小文件后,如何校验文件的完整性呢,一般通过MD5工具来校验对比。对应的Linux命令为md5sum。

提示:有关md5的校验机制和原理请参考相关文档,本节不再描述。

flask中jinjia2模板引擎使用详解1

在之前的文章中我们介绍过flask调用jinja2模板的基本使用,这次我们来说一下jinjia2模板的使用

Jinja2 在其是一个 Python 2.4 库之前,被设计 为是灵活、快速和安全的。

模板仅仅是文本文件。它可以生成任何基于文本的格式(HTML、XML、CSV、LaTex 等等)。 它并没有特定的扩展名, .html 或 .xml 都是可以的。

模板包含 变量 或 表达式 ,这两者在模板求值的时候会被替换为值。模板中 还有标签,控制模板的逻辑。模板语法的大量灵感来自于 Django 和 Python 。

下面是一个最小的模板,它阐明了一些基础。我们会在文档中后面的部分解释细节:

<html lang="en">
<head>
<title>My Webpage</title>
</head>
<body>
<ul id="navigation">
{% for item in navigation %}
<li><a href="{{ item.href }}">{{ item.caption }}</a></li>
{% endfor %}
</ul>
<h1>My Webpage</h1>
{{ a_variable }}
</body>
</html>

通过上面的模板我们能看到主要有两类标签组成 {{ }}和{% %}这两类标签分别用来包含变量和表达式

如何访问变量

如果传入的变量是对象,要访问对象中的属性,可以用下面两种方式:

{{obj.prop}}

{{obj[“prop”]}

两种方式都会去检查obj对象中有没有prop这个属性以及其中的其它变量,不同的是obj.prop先检查属性,obj[“prop”]先检查变量。

赋值

使用set关键字为变量设置值

<h1>Set为变量赋值</h1>
{% set name = 'Han Mei Mei' %}
{{ name }}

运行效果

未分类

变量过滤器

变量可以通过过滤器进行修改,变量和过滤器中间用|进行分隔,使用的基本格式是{{变量|过滤器1|过滤器2}},jinja2内置了很多过滤器,通过这些内置过滤器,可以进行变量的修改,内置过滤器可以参考 http://docs.jinkan.org/docs/jinja2/templates.html#builtin-filters ,比如我们要把变量转成大写,可以用upper过滤器

未分类

运行效果:

未分类

语句过滤器

上面说的是用过滤器过滤一个变量,下面来说一下如何在代码块中使用过滤器,上例子:

{% filter upper %}
This text becomes uppercase
{% endfilter %}

运行效果:

未分类

is关键字进行变量判断

is关键字用来在表达式中测试变量的值是否满足某条件。比如判断变量是否是数字,就可以用

<h1>name is number? {% if name is number %}true{% else %}false{%
endif %}</h1>

未分类

运行结果:

未分类

当我们修改一下代码,成下面的格式,限制输入为int:

@app.route("/tmpl/<int:name>")

def renderTmpl(name=1):

return render_template("hello.html",name=name)

再次运行:

未分类

Flask内置的is可用的函数参考 : http://docs.jinkan.org/docs/jinja2/templates.html#builtin-tests

欢迎关注“挨踢学霸”同名公众号, 回复jinjia2-1获取源码下载地址。

进程管理工具-Supervisor安装与配置

Supervisor(http://supervisord.org/)是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支持Windows系统。它可以很方便的监听、启动、停止、重启一个或多个进程。用Supervisor管理的进程,当一个进程意外被杀死,supervisort监听到进程死后,会自动将它重新拉起,很方便的做到进程自动恢复的功能,不再需要自己写shell脚本来控制。

因为Supervisor是Python开发的,安装前先检查一下系统否安装了Python2.4以上版本。下面以CentOS7,Python2.7版本环境下,介绍Supervisor的安装与配置步聚:

一、安装Python包管理工具(easy_install)

easy_install是setuptools包里带的一个命令,使用easy_install实际上是在调用setuptools来完成安装模块的工作,所以安装setuptools即可。

wget --no-check-certificate https://bootstrap.pypa.io/ez_setup.py -O - | sudo python

二、安装supervisor

easy_install supervisor

supervisor安装完成后会生成三个执行程序:supervisortd、supervisorctl、echo_supervisord_conf,分别是supervisor的守护进程服务(用于接收进程管理命令)、客户端(用于和守护进程通信,发送管理进程的指令)、生成初始配置文件程序。

三、配置

运行supervisord服务的时候,需要指定supervisor配置文件,如果没有显示指定,默认在以下目录查找:

$CWD/supervisord.conf
$CWD/etc/supervisord.conf
/etc/supervisord.conf
/etc/supervisor/supervisord.conf (since Supervisor 3.3.0)
../etc/supervisord.conf (Relative to the executable)
../supervisord.conf (Relative to the executable)

$CWD表示运行supervisord程序的目录。

可以通过运行echo_supervisord_conf程序生成supervisor的初始化配置文件,如下所示:

mkdir /etc/supervisor
echo_supervisord_conf > /etc/supervisor/supervisord.conf

四、配置文件参数说明

supervisor的配置参数较多,下面介绍一下常用的参数配置,详细的配置及说明,请参考官方文档介绍。
注:分号(;)开头的配置表示注释

[unix_http_server]  
file=/tmp/supervisor.sock   ;UNIX socket 文件,supervisorctl 会使用  
;chmod=0700                 ;socket文件的mode,默认是0700  
;chown=nobody:nogroup       ;socket文件的owner,格式:uid:gid  

;[inet_http_server]         ;HTTP服务器,提供web管理界面  
;port=127.0.0.1:9001        ;Web管理后台运行的IP和端口,如果开放到公网,需要注意安全性  
;username=user              ;登录管理后台的用户名  
;password=123               ;登录管理后台的密码  

[supervisord]  
logfile=/tmp/supervisord.log ;日志文件,默认是 $CWD/supervisord.log  
logfile_maxbytes=50MB        ;日志文件大小,超出会rotate,默认 50MB,如果设成0,表示不限制大小  
logfile_backups=10           ;日志文件保留备份数量默认10,设为0表示不备份  
loglevel=info                ;日志级别,默认info,其它: debug,warn,trace  
pidfile=/tmp/supervisord.pid ;pid 文件  
nodaemon=false               ;是否在前台启动,默认是false,即以 daemon 的方式启动  
minfds=1024                  ;可以打开的文件描述符的最小值,默认 1024  
minprocs=200                 ;可以打开的进程数的最小值,默认 200  

[supervisorctl]  
serverurl=unix:///tmp/supervisor.sock ;通过UNIX socket连接supervisord,路径与unix_http_server部分的file一致  
;serverurl=http://127.0.0.1:9001 ; 通过HTTP的方式连接supervisord  

; [program:xx]是被管理的进程配置参数,xx是进程的名称  
[program:xx]  
command=/opt/apache-tomcat-8.0.35/bin/catalina.sh run  ; 程序启动命令  
autostart=true       ; 在supervisord启动的时候也自动启动  
startsecs=10         ; 启动10秒后没有异常退出,就表示进程正常启动了,默认为1秒  
autorestart=true     ; 程序退出后自动重启,可选值:[unexpected,true,false],默认为unexpected,表示进程意外杀死后才重启  
startretries=3       ; 启动失败自动重试次数,默认是3  
user=tomcat          ; 用哪个用户启动进程,默认是root  
priority=999         ; 进程启动优先级,默认999,值小的优先启动  
redirect_stderr=true ; 把stderr重定向到stdout,默认false  
stdout_logfile_maxbytes=20MB  ; stdout 日志文件大小,默认50MB  
stdout_logfile_backups = 20   ; stdout 日志文件备份数,默认是10  
; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)  
stdout_logfile=/opt/apache-tomcat-8.0.35/logs/catalina.out  
stopasgroup=false     ;默认为false,进程被杀死时,是否向这个进程组发送stop信号,包括子进程  
killasgroup=false     ;默认为false,向进程组发送kill信号,包括子进程  

;包含其它配置文件  
[include]  
files = relative/directory/*.ini    ;可以指定一个或多个以.ini结束的配置文件  

include示例:

[include]
files = /opt/absolute/filename.ini /opt/absolute/*.ini foo.conf config??.ini

注:INI文件是一个无固定标准格式的配置文件。它以简单的文字与简单的结构组成,常常使用在Windows操作系统,或是其他操作系统上,许多程序也会采用INI文件做为设置程序之用。Windows操作系统后来以注册表的形式取代掉INI档。INI文件的命名来源,是取自英文“初始(Initial)”的首字缩写,正与它的用途——初始化程序相应。有时候,INI文件也会以不同的扩展名,如“.CFG”、“.CONF”、或是“.TXT”代替。

五、配置管理进程

进程管理配置参数,不建议全都写在supervisord.conf文件中,应该每个进程写一个配置文件放在include指定的目录下包含进supervisord.conf文件中。
1> 创建/etc/supervisor/config.d目录,用于存放进程管理的配置文件
2> 修改/etc/supervisor/supervisord.conf中的include参数,将/etc/supervisor/conf.d目录添加到include中

[include]
files = /etc/supervisor/config.d/*.ini

未分类

下面是配置Tomcat进程的一个例子:

[program:tomcat]
command=/opt/apache-tomcat-8.0.35/bin/catalina.sh run
stdout_logfile=/opt/apache-tomcat-8.0.35/logs/catalina.out
autostart=true
autorestart=true
startsecs=5
priority=1
stopasgroup=true
killasgroup=true

六、启动Supervisor服务

supervisord -c /etc/supervisor/supervisord.conf

七、控制进程

7.1 交互终端

supervisord启动成功后,可以通过supervisorctl客户端控制进程,启动、停止、重启。运行supervisorctl命令,不加参数,会进入supervisor客户端的交互终端,并会列出当前所管理的所有进程。

未分类

上图中的tomcat就是我们在配置文件中[program:tomcat]指定的名字。

输入help可以查看可以执行的命令列表,如果想看某个命令的作用,运行help 命令名称,如:help stop

stop tomcat  // 表示停止tomcat进程
stop all     // 表示停止所有进程
// ...

7.2 bash终端

supervisorctl status
supervisorctl stop tomcat
supervisorctl start tomcat
supervisorctl restart tomcat
supervisorctl reread
supervisorctl update

7.3 Web管理界面

未分类

出于安全考虑,默认配置是没有开启web管理界面,需要修改supervisord.conf配置文件打开http访权限,将下面的配置:

;[inet_http_server]         ; inet (TCP) server disabled by default
;port=127.0.0.1:9001        ; (ip_address:port specifier, *:port for all iface)
;username=user              ; (default is no username (open server))
;password=123               ; (default is no password (open server))

修改成:

[inet_http_server]         ; inet (TCP) server disabled by default
port=0.0.0.0:9001          ; (ip_address:port specifier, *:port for all iface)
username=user              ; (default is no username (open server))
password=123               ; (default is no password (open server))

port:绑定访问IP和端口,这里是绑定的是本地IP和9001端口
username:登录管理后台的用户名
password:登录管理后台的密码

八、开机启动Supervisor服务

8.1 配置systemctl服务

1、进入/lib/systemd/system目录,并创建supervisor.service文件

[Unit]  
Description=supervisor  
After=network.target  

[Service]  
Type=forking  
ExecStart=/usr/bin/supervisord -c /etc/supervisor/supervisord.conf  
ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown  
ExecReload=/usr/bin/supervisorctl $OPTIONS reload  
KillMode=process  
Restart=on-failure  
RestartSec=42s  

[Install]  
WantedBy=multi-user.target  

2、设置开机启动

systemctl enable supervisor.service
systemctl daemon-reload

3、修改文件权限为766

chmod 766 supervisor.service

8.2 配置service类型服务

#!/bin/bash  
#  
# supervisord   This scripts turns supervisord on  
#  
# Author:       Mike McGrath <[email protected]> (based off yumupdatesd)  
#  
# chkconfig:    - 95 04  
#  
# description:  supervisor is a process control utility.  It has a web based  
#               xmlrpc interface as well as a few other nifty features.  
# processname:  supervisord  
# config: /etc/supervisor/supervisord.conf  
# pidfile: /var/run/supervisord.pid  
#  

# source function library  
. /etc/rc.d/init.d/functions  

RETVAL=0  

start() {  
    echo -n $"Starting supervisord: "  
    daemon "supervisord -c /etc/supervisor/supervisord.conf "  
    RETVAL=$?  
    echo  
    [ $RETVAL -eq 0 ] && touch /var/lock/subsys/supervisord  
}  

stop() {  
    echo -n $"Stopping supervisord: "  
    killproc supervisord  
    echo  
    [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/supervisord  
}  

restart() {  
    stop  
    start  
}  

case "$1" in  
  start)  
    start  
    ;;  
  stop)   
    stop  
    ;;  
  restart|force-reload|reload)  
    restart  
    ;;  
  condrestart)  
    [ -f /var/lock/subsys/supervisord ] && restart  
    ;;  
  status)  
    status supervisord  
    RETVAL=$?  
    ;;  
  *)  
    echo $"Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}"  
    exit 1  
esac  

exit $RETVAL  

将上述脚本内容保存到/etc/rc.d/init.d/supervisor文件中,修改文件权限为755,并设置开机启动

chmod 755 /etc/rc.d/init.d/supervisor
chkconfig supervisor on

注意:修改脚本中supervisor配置文件路径为你的supervisor的配置文件路径

其它Linux发行版开机启动脚本:https://github.com/Supervisor/initscripts

注意:

Supervisor只能管理非daemon的进程,也就是说Supervisor不能管理守护进程。否则提示Exited too quickly (process log may have details)异常。例子中的Tomcat默认是以守护进程启动的,所以我们改成了catalina.sh run,以前台进程的方式运行。

yum方式安装

yum install epel-release
yum install -y supervisor

supervisor没有发布在标准的CentOS源在,需要安装epel源。这种方式安装的可能不是最新版本,但比较方便,安装完成之后,配置文件会自动帮你生成。
默认配置文件:/etc/supervisord.conf
进程管理配置文件放到:/etc/supervisord.d/目录下即可

默认日志文件:/tmp/supervisord.log,可以查看进程的启动信息。

centos7的服务治理-systemd

经常用到的高频命令小结

- 所有服务unit放在这里
ll /usr/lib/systemd/system

- 默认启动级别
[root@n1 ~]# ll /etc/systemd/system/default.target 
lrwxrwxrwx 1 root root 41 Mar  4 09:02 /etc/systemd/system/default.target -> /usr/lib/systemd/system/multi-user.target

- 开机启动的服务
ll /etc/systemd/system/multi-user.target.wants/

- 哪些服务开机会启动
[root@n1 ~]# systemctl list-unit-files --type service |grep enable
[email protected]                               enabled 
crond.service                                 enabled 
docker.service                                enabled 
[email protected]                                enabled 
ntpdate.service                               enabled 
rsyslog.service                               enabled 
sshd.service                                  enabled 
sysstat.service                               enabled 

- 目前哪些服务处于active状态
[root@n1 ~]# systemctl list-units --type service |grep active
crond.service                      loaded active running Command Scheduler
dbus.service                       loaded active running D-Bus System Message Bus
docker.service                     loaded active running Docker Application Container Engine
[email protected]                 loaded active running Getty on tty1

- 查看某个服务是否开机自启
systemctl is-enabled httpd.service 或
systemctl status httpd.service

systemd 有很多unit,其中service.unit是管理系统服务的.

未分类

unit的类型

/usr/lib/systemd/system

未分类

查看管理系统服务的相关的, 即 .service后缀的

[root@n1 system]# ls /usr/lib/systemd/system/*.service|more
/usr/lib/systemd/system/arp-ethers.service
/usr/lib/systemd/system/auditd.service
/usr/lib/systemd/system/[email protected]
/usr/lib/systemd/system/blk-availability.service
/usr/lib/systemd/system/brandbot.service
...

特点:
    不需要可执行权限,其内容也不能执行
    仅是systemd的调用的配置文件<img

src=”http://devops.webres.wang/wp-content/uploads/2018/03/3-20.png” alt=”” width=”388″ height=”443″ class=”alignnone size-full wp-image-19103″ />

centos6 chkconfig VS 使用systemd的service unit治理centos7服务

未分类

ls /usr/lib/systemd/system/*.service|more 下以service开头的文件,都是和系统服务有关的, 其下还有别的后缀的服务.是别的unit的配置文件.

未分类

serivice unit配置

未分类

target unit: 的含义是服务组,表示一组服务

将很多服务放在一坨, 开启启动时候加载这个文件.

启动级别

/usr/lib/systemd/system
/etc/systemd/system

runlevel0.target -> poweroff.target
runlevel2.target -> multi-user.target
runlevel3.target -> multi-user.target
runlevel4.target -> multi-user.target
runlevel5.target -> graphical.target
runlevel6.target -> reboot.target

注意: centos7里,运行级别234没区别.

查看在运行的服务

我们看ACTIVE就ok了,SUB这一列可以不用理会

[root@n1 system]# systemctl list-units --type=service
UNIT                               LOAD   ACTIVE SUB     DESCRIPTION
crond.service                      loaded active running Command Scheduler
dbus.service                       loaded active running D-Bus System Message Bus
docker.service                     loaded active running Docker Application Container Engine
[email protected]                 loaded active running Getty on tty1
httpd.service                      loaded active running The Apache HTTP Server

查看开机是否会启动

[root@n1 system]# systemctl list-unit-files --type=service
UNIT FILE                                     STATE   
arp-ethers.service                            disabled
auditd.service                                disabled
[email protected]                               enabled #开机会启动
blk-availability.service                      disabled#开机不会启动
brandbot.service                              static  #这类不用管
conntrackd.service                            disabled

systemd管理服务入门http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-part-two.html

设置开机自动启动细节

[root@n1 ~]# yum install psmisc -y
[root@n1 ~]# pstree
systemd─┬─agetty
        ├─crond
        ├─dbus-daemon
        ├─dockerd─┬─docker-containe─┬─docker-containe─┬─mysqld───20*[{mysqld}]
        │         │                 │                 └─8*[{docker-containe}]
        │         │                 └─9*[{docker-containe}]
        │         ├─docker-proxy───3*[{docker-proxy}]
        │         └─11*[{dockerd}]
        ├─httpd───8*[httpd]
        ├─lvmetad
        ├─polkitd───5*[{polkitd}]
        ├─rsyslogd───2*[{rsyslogd}]
        ├─sshd───sshd───bash───pstree
        ├─systemd-journal
        ├─systemd-logind
        └─systemd-udevd
[root@n1 system]# systemctl enable httpd
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.

相当于执行

ln -s /usr/lib/systemd/system/httpd.service /etc/systemd/system/multi-user.target.wants/httpd.service

disable相当于删除

[root@n1 system]# systemctl disable httpd
Removed symlink /etc/systemd/system/multi-user.target.wants/httpd.service.
[root@n1 system]# ll /etc/systemd/system/multi-user.target.wants
total 0
lrwxrwxrwx. 1 root root 37 Dec 27 04:44 crond.service -> /usr/lib/systemd/system/crond.service
lrwxrwxrwx  1 root root 38 Dec 26 21:05 docker.service -> /usr/lib/systemd/system/docker.service
lrwxrwxrwx  1 root root 37 Mar  4 03:39 httpd.service -> /usr/lib/systemd/system/httpd.service
lrwxrwxrwx. 1 root root 39 Dec 26 21:00 ntpdate.service -> /usr/lib/systemd/system/ntpdate.service
lrwxrwxrwx. 1 root root 40 Dec 27 04:44 remote-fs.target -> /usr/lib/systemd/system/remote-fs.target
lrwxrwxrwx. 1 root root 39 Dec 27 04:44 rsyslog.service -> /usr/lib/systemd/system/rsyslog.service
lrwxrwxrwx. 1 root root 36 Dec 27 04:44 sshd.service -> /usr/lib/systemd/system/sshd.service
lrwxrwxrwx. 1 root root 39 Dec 27 05:00 sysstat.service -> /usr/lib/systemd/system/sysstat.service

设置启动级别的命令

- 设置默认启动级别
[root@n1 ~]# systemctl set-default graphical.target 
Removed symlink /etc/systemd/system/default.target.
Created symlink from /etc/systemd/system/default.target to /usr/lib/systemd/system/graphical.target.

- 查看默认的启动级别
[root@n1 ~]# systemctl get-default 
graphical.target

- 手动修改启动级别(先将原来的rm了)
[root@n1 ~]# ln -sv /usr/lib/systemd/system/multi-user.target /etc/systemd/system/default.target
ln: failed to create symbolic link ‘/etc/systemd/system/default.target’: File exists
[root@n1 ~]# rm -rf /etc/systemd/system/default.target
[root@n1 ~]# ln -sv /usr/lib/systemd/system/multi-user.target /etc/systemd/system/default.target
‘/etc/systemd/system/default.target’ -> ‘/usr/lib/systemd/system/multi-user.target’
[root@n1 ~]# systemctl get-default 
multi-user.target

- 查看服务状态

[root@n1 ~]# systemctl is-enabled httpd.service 
disabled

systemd 编写服务管理脚本

我们运行 linux 服务器的主要目的是通过运行程序提供服务,比如 mysql、web server等。因此管理 linux 服务器主要工作就是配置并管理上面运行的各种服务程序。在 linux 系统中服务程序的管理主要由 init 系统负责。如同笔者在《初识 systemd》一文中的介绍,linux 的 init 系统已经从最初的 sysvinit 进化到了如今的 systemd。本文主要介绍在 systemd 环境中如何编写运行服务的配置文件。

unit(单元)的配置文件

Unit 是 systemd 进行任务管理的基本单位,我们在前文中已经介绍过,service 类型的 unit 代表一个后台服务进程。接下来我们就详细的介绍如何配置 service 类型的 unit。下面我们先来看一个简单的服务配置:

[Unit]
Description=Prometheus Server
Documentation=https://prometheus.io/docs/introduction/overview/
After=network.target

[Service]
User=prometheus
Restart=on-failure
WorkingDirectory=/usr/local/share/prometheus/
ExecStart=/usr/local/share/prometheus/prometheus 
          -config.file=/usr/local/share/prometheus/prometheus.yml

[Install]
WantedBy=multi-user.target

这是笔者主机上 prometheus 服务的配置文件。把上面的内容保存到文件 /lib/systemd/system/prometheus.service 中,然后就可以使用 systemctl 命令管理 prometheus 服务了。注意,服务类型的配置文件名称必须以 .service 结尾。
查看上面配置信息的详细内容,我们会发现整个配置的内容分为三个部分:
[Unit] unit 本身的说明,以及与其它有依赖关系的服务的设置,包括在什么服务之后才启动此 unit 之类的设置。
[Service] 不同的 unit 类型就得要使用相对应的设置项目,比如 timer 类型的 unit 应该是 [Timer],socket 类型的 unit 应该是 [Socket]。服务类型的 unit 就是 [Service],这个项目内主要在规范服务启动的脚本、环境配置文件文件名、重新启动的方式等等。
[Install] 这个部分主要设置把该 unit 安装到哪个 target 。

服务类型 unit 的详细配置

配置文件分为三个部分,每个部分中都可以提供详细的配置信息。为了精确的控制服务的运行方式,我们需要了解这些详细的配置选项,并最终让服务以我们期望的方式运行。

[Unit] 部分
Description 关于该 unit 的简易说明。
Documentation 文档相关的内容,如 Documentation=https://prometheus.io/docs/introduction/overview/
Documentation=man:sshd(8)
Documentation=file:/etc/ssh/sshd_config
After 说明本 unit 是在哪个服务启动之后才启动的意思。仅是说明服务启动的顺序而已,并没有强制要求 。
Before 与 After 的意义相反,在指定的服务启动前最好启动本个服务的意思。仅是说明服务启动的顺序而已,并没有强制要求 。
Requires 本 unit 需要在哪个服务启动后才能够启动!就是设置服务间的依赖性。如果在此项设置的前导服务没有启动成功,那么本 unit 就不会被启动!
Wants 与 Requires 刚好相反,规范的是这个 unit 之后还要启动什么服务,如果这 Wants 后面接的服务如果没有启动成功,其实不会影响到这个 unit 本身!
Conflicts 这个项目后面接的服务如果有启动,那么本 unit 就不能启动!如果本 unit 启动了,则指定的服务就不能启动。

[Service] 部分
Type
说明这个服务的启动方式,会影响到 ExecStart,主要有下面几种类型:
simple:默认值,这个服务主要由 ExecStart 设置的程序来启动,启动后常驻于内存中。
forking:由 ExecStart 指定的启动的程序通过 spawns 产生子进程提供服务,然后父进程退出。
oneshot:与 simple 类似,不过这个程序在工作完毕后就结束了,不会常驻在内存中。
dbus:与 simple 类似,但这个服务必须要在取得一个 D-Bus 的名称后,才会继续运行!因此设置这个项目时,通常也要设置 BusName= 才行。
idle:与 simple 类似,意思是,要执行这个服务必须要所有的工作都顺利执行完毕后才会执行。这类的服务通常是开机到最后才执行即可的服务。
notify:与 simple 类似,但这个服务必须要收到一个 sd_notify() 函数发送的消息后,才会继续运行。

ExecStart
就是实际执行此服务的程序。接受 “命令 参数 参数…” 的格式,不能接受 <, >, >>, |, & 等特殊字符,很多的 bash 语法也不支持。所以,要使用这些特殊的字符时,最好直接写入到脚本里面去!

ExecStartPreExecStartPost 分别在服务启动前后,执行额外的命令。

ExecStop 用来实现 systemctl stop 命令,关闭服务。
ExecReload 用来实现 systemctl reload 命令,重新加载服务的配置信息。

Restart 当设置为 Restart=1 时,如果服务终止,就会自动重启此服务。
RestartSec 与 Restart 配合使用,在服务终止多长时间之后才重新启动它。默认是 100ms。

KillMode
可以是 process, control-group, none 中的一种,如果是 process 则服务终止时,只会终止主要的程序(ExecStart接的后面那串指令),如果是 control-group 时,则由此 daemon 所产生的其他 control-group 的程序,也都会被关闭。如果是 none 的话,则没有程序会被关闭。

TimeoutSec
若这个服务在启动或者是关闭时,因为某些缘故导致无法顺利 “正常启动或正常结束” 的情况下,则我们要等多久才进入 “强制结束” 的状态!

RemainAfterExit
当设置为 RemainAfterExit=1 时,则当这个服务所属的所有程序都终止之后,此服务会再尝试启动。这对于 Type=oneshot 的服务很有帮助!

环境变量的设置对很多程序来说都是十分重要的,下面的配置则可以以不同的方式为服务程序设置环境变量:
Environment 用来设置环境变量,可以使用多次:

[Service]
# Client Env Vars
Environment=ETCD_CA_FILE=/path/to/CA.pem
Environment=ETCD_CERT_FILE=/path/to/server.crt

EnvironmentFile 通过文件的方式设置环境变量,可以把下面的内容保存到文件 testenv 中:

AAA_IPV4_ANCHOR_0=X.X.X.X
BBB_IPV4_PRIVATE_0=X.X.X.X
CCC_HOSTNAME=test.example.com

然后这样设置:

[Service]
EnvironmentFile=/testenv

接下来就可以在 ExecStart 配置中使用在文件中设置的环境变量,如:

ExecStart=/xxx --abc=xx${AAA_IPV4_ANCHOR_0}yy

[Install] 部分
WantedBy 这个设置后面接的大部分是 *.target unit。意思是,这个 unit 本身是附挂在哪个 target unit 下面。
Also 当目前这个 unit 被 enable 时,Also 后面接的 unit 也要 enable 的意思。
Alias 当 systemctl enable 相关的服务时,则此服务会进行链接文件的创建!

Timer 类型 unit 的详细配置

Timer 类型的 unit 主要用来执行定时任务,并有可能取代 cron 服务。由于 timer 类型的 unit 经常与服务类型的 unit 一起使用,所以本文也附带介绍一下 timer unit 的配置。与服务类型的 unit 不同,timer unit 配置文件中的主要部分是 [Timer],下面是其主要的配置项:
OnActiveSec 当 timers.target 启动后多久才执行这个 unit。
OnBootSec 当开机后多久才执行这个 unit。
OnStartupSec 当 systemd 第一次启动后多久才执行这个 unit。
OnUnitActiveSec 这个 timer 配置文件所管理的那个 unit 服务在最后一次启动后,隔多久后再执行一次。
OnUnitInactiveSec 这个 timer 配置文件所管理的那个 unit 服务在最后一次停止后,隔多久后再执行一次。
Unit 一般不需要设置,基本上我们设置都是 服务名称.server + 服务名称.timer。如果你的服务名称和 timer 名称不相同,就需要在 .timer 文件中通过 Unit 项指定服务的名称。
OnCalendar 使用实际时间(非循环时间)的方式来启动服务。
Persistent 当使用 OnCalendar 的设置时,指定该功能要不要持续执行。

通过上面的介绍,相信大家对 systemd 服务类型和 timer 类型的 unit 配置已经有了基本的理解,下面让就让我们配置两个实际的例子。

配置 redis 服务

在 ubuntu 上我们一般会手动编译并安装 redis。在安装完成后需要把 redis 配置为 systemd 管理的服务,下面介绍具体的配置过程。

添加 redis 配置文件

首先手动创建 /etc/redis 目录并添加配置文件:

$ sudo mkdir /etc/redis

并把代码目录中的配置文件 redis.conf 拷贝到 /etc/redis 目录中:

$ sudo cp /tmp/redis-4.0.0/redis.conf /etc/redis/

然后修改配置文件 /etc/redis/redis.conf 中的 supervised 为 systemd:
supervised systemd

未分类

接着继续在配置文件 /etc/redis/redis.conf 中配置工作目录,把 dir ./ 修改为:
dir /var/lib/redis

未分类

配置由 systemd 管理 redis 服务

创建 /etc/systemd/system/redis.service 文件

$ sudo vim /etc/systemd/system/redis.service

编辑其内容如下:

[Unit]
Description=Redis In-Memory Data Store
After=network.target

[Service]
User=redis
Group=redis
ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf
ExecStop=/usr/local/bin/redis-cli shutdown
Restart=always

[Install]
WantedBy=multi-user.target

启动服务并配置为开机启动:

$ sudo systemctl start redis
$ sudo systemctl enable redis
$ sudo systemctl status redis

未分类

通过脚本定时备份文件

备份文件的 bash 脚本:

#!/bin/bash
mydate()
{
        date "+%Y%m%d%H%M%S"
}
backupdate=$(mydate)
tar -zcf /tmp/backup.${backupdate}.tar.gz /home/nick/learn

把上面的代码保存到文件 /usr/local/bin/backupdir.sh,并添加可执行权限:

$ sudo chmod +x /usr/local/bin/backupdir.sh

然后创建 service unit 配置文件:

[Unit]
Description=nick backup learn dir service

[Service]
User=nick
Group=nick
Type=simple
ExecStart=/usr/local/bin/backupdir.sh

[Install]
WantedBy=multi-user.target

把上面的 unit 配置保存到文件 /etc/systemd/system/nickbak.service。
然后执行下面的命令测试服务的执行情况:

$ sudo systemctl daemon-reload
$ sudo systemctl start nickbak.service

这样的备份任务只会在执行 sudo systemctl start nickbak.service 时执行一次。下面我们通过 timer unit 把它配置为定时执行。
创建 timer unit 配置文件:

[Unit]
Description=nick backup learn dir timer

[Timer]
OnCalendar=*:0/15
Persistent=true
Unit=nickbak.service

[Install]
WantedBy=multi-user.target

把上面的 unit 配置保存到文件 /etc/systemd/system/nickbak.timer。配置中 OnCalendar=*:0/15 表示每 15 分钟执行一次 nickbak.service 服务。

执行下面的命令把 nickbak.timer 设置为开机启动,并启动 nickbak.timer:

$ sudo systemctl daemon-reload
$ sudo systemctl enable nickbak.timer
$ sudo systemctl start nickbak.timer

现在来看看 nickbak.timer 的状态:

$ sudo systemctl status nickbak.timer

未分类

从现在开始 nickbak.timer 会每隔 15 分钟执行一次 nickbak.service 服务。

总结

systemd 提供了服务管理(其实是 unit 管理)的方方面面,我们需要做的就是写好服务 unit 的配置文件,然后利用 systemd 来管理我们的服务。这是一个看似简单实则繁琐的任务(很多的配置项其实需要我们在实践中不断的调整并优化)。希望本文对大家来说是个简单的入门。

Linux中crontab定时任务不执行

最近在linux中遇到了个crontab定时任务不执行的case,在这给大家分享一下,避免踩到我遇到的坑。

先贴脚本吧

为了方便展示,把脚本入参,都写死了

#!/usr/bin/env bash
# 1输出文件,到log 例如: bg 
# 2 目标文件目录  不带最后的/ 例如:/opt/flume/home/hdp_lbg_ectech/rawdata/xxx/web_vip_bg
# 3 执行的时候选择前几天的日志  例如:1

LAST_DAY=$(date +"%Y-%m-%d" -d "1 days ago")
LAST_HOUR_DAY=$(date +"%Y%m%d" -d "1 days ago")
#执行jar获取bg日志
 java -jar /opt/script/xxx/vipbg/vip-bg-job-1.0-SNAPSHOT-shaded.jar  /opt/script/xxx/vipbg/bg.log

#具体到文件名
SRC_FILE=/opt/script/xxx/vipbg/bg.log

#指定目标目录,按日期创建目录
DEST_DIR_NAME=/opt/flume/home/hdp_lbg_ectech/rawdata/xxx/web_vip_bg/$LAST_HOUR_DAY
DEST_FILE_NAME=$(basename $SRC_FILE)
#FLUME会忽略隐藏文件,所以可直接拷贝过去
TMP_FILE=$DEST_DIR_NAME/.$DEST_FILE_NAME
DEST_FILE=$DEST_DIR_NAME/$DEST_FILE_NAME.$SRC_IP
#判断源文件是否非空,空文件Flume会直接删除的,且目标文件不存在,避免重复拷贝数据
if [ -s "$SRC_FILE" ] && [ ! -f "$DEST_FILE" ];then
    #使Flume具有删除该目录下文件的权限,不然FLUME收集不上去
    mkdir -p $DEST_DIR_NAME && chmod 777 $DEST_DIR_NAME
    #必须先cp到一个临时文件再mv过去,直接cp过去会造成数据丢失
    cp $SRC_FILE $TMP_FILE && mv $TMP_FILE $DEST_FILE
fi
#删除tmp中转文件
rm -rf  /opt/script/xxx/vipbg/bg.log
echo "删除源文件成功"

有些目录用了xxx代表
这个脚本单独考出来可以执行,放到crontab里面就不执行了, 百度了下,大多都说需要使用绝对路径,看了下我们的脚本,就是下面这句有问题:

java -jar /opt/script/xxx/vipbg/vip-bg-job-1.0-SNAPSHOT-shaded.jar  /opt/script/xxx/vipbg/bg.log

初步判断是java这需要使用jdk的目录路径,做了两个实验测试了下。

crontab中加上一个 java -jar xxxx.jar的定时任务

代码如下:

10 16 * * *  java -jar /opt/script/xxx/vipbg/vip-bg-job-1.0-SNAPSHOT-shaded.jar  /opt/script/xxx/vipbg/bg.log

果然,这个没有执行

crontab中加上一个 jdk目录/bin/java -jar xxxx.jar的定时任务

代码如下:

20 16 * * *  /opt/soft/jdk/jdk1.6.0_45/bin/java -jar /opt/script/xxx/vipbg/vip-bg-job-1.0-SNAPSHOT-shaded.jar  /opt/script/xxx/vipbg/bg.log

这次执行了,没有执行的原因就是执行jar的时候,需要加上jdk的路径

你们是否也遇到了类似的问题,欢迎大家来交流,指出文中一些说错的地方,让我加深认识,分享自己遇到的坑,让大家一起没有bug,谢谢大家!