对于刚接触linux的同学,可能有这样的体验:
-
使用ssh登录到服务器后,执行了一个耗时较长的脚本,有时因为网络不稳定或者手滑导致ssh远程连接断开,导致程序执行失败。
-
需要长时间稳定跑的脚本。我们希望能够在linux后台跑,关闭远程连接也没事,且可以随时查看输出信息或者操作
-
tips: 以下操作基于centos7
举栗子看一下
- 在服务器设置ssh 登录时长为2分钟 可以参考这篇文章
# vi /etc/ssh/sshd_config
ClientAliveInterval 2m # 2 minutes
ClientAliveCountMax 0 # 0 次
#重启ssh服务
# service sshd restart
- 编写shell 脚本,循环往一个文件里面写入数字,到120s 会断开连接
#!/bin/bash
for((i=1;i<=100000;i++));
do
echo "$i " >>num.log;
sleep 1
done
-
超时断开
- 超时断开
-
进程已经被关闭
进程已经关闭
这里简单介绍一下ps -ef 每列的含义
字段含义如下:
UID PID PPID C STIME TTY TIME CMD
root 18887 18828 0 08:09 pts/0 00:00:00 grep ApacheJetspeed
ps:将某个进程显示出来
-A 显示所有程序。
-e 此参数的效果和指定”A”参数相同。
-f 显示UID,PPIP,C与STIME栏位。
grep命令是查找
中间的|是管道命令 是指ps命令与grep同时执行
UID PID PPID C STIME TTY TIME CMD
root 18887 18828 0 08:09 pts/0 00:00:00 grep ApacheJetspeed
各相关信息的意义:
UID 程序被该 UID 所拥有
PID 就是这个程序的 ID
PPID 则是其上级父程序的ID
C CPU 使用的资源百分比
STIME 系统启动时间
TTY 登入者的终端机位置
TIME 使用掉的 CPU 时间。
CMD 所下达的指令为何
-
共写入了120次,即120s
共写入了120次 - 原因:
在linux 里面,所有的进程都有父进程,当ssh连接到服务器上时,打开的shell就是你所有执行命令的父进程,因为你所有的命令都是基于shell里面去执行的。那么当shh断开连接的时候,父进程就退出了,由于我们没有做特殊处理,系统收到父进程的sigterm信号,父进程下面的子进程会被全部kill掉
解决方案:
- nohup
[root@localhost ~]# nohup ./for.sh &
[1] 6326
[root@localhost ~]# nohup: ignoring input and appending output to ‘nohup.out’
- screen
# 使用yum安装screen
yum install screen
# 创建一个名为test的会话窗口
screen -S test
# 暂离窗口
Ctrl+a d(即按住Ctrl,依次再按a,d)
# 查看存在的会话窗口
screen -ls
# 进入窗口
screen -r test
screen -r 进程ID
# 关闭窗口
exit
# 窗口切换
Ctrl+a c :在当前screen会话中创建窗口
Ctrl+a w :窗口列表
Ctrl+a n :下一个窗口
Ctrl+a p :上一个窗口
Ctrl+a 0-9 :在第0个窗口和第9个窗口之间切换
- tmux 相关参考
Tmux是一个优秀的终端复用软件,类似GNU Screen,但来自于OpenBSD,采用BSD授权。使用它最直观的好处就是,通过一个终端登录远程主机并运行tmux后,在其中可以开启多个控制台而无需再“浪费”多余的终端来连接这台远程主机。是BSD实现的Screen替代品,相对于Screen,它更加先进:支持屏幕切分,而且具备丰富的命令行参数,使其可以灵活、动态的进行各种布局和操作。
ctrl+b ? 显示快捷键帮助
ctrl+b 空格键 采用下一个内置布局,这个很有意思,在多屏时,用这个就会将多有屏幕竖着展示
ctrl+b ! 把当前窗口变为新窗口
ctrl+b " 模向分隔窗口
ctrl+b % 纵向分隔窗口
ctrl+b q 显示分隔窗口的编号
ctrl+b o 跳到下一个分隔窗口。多屏之间的切换
ctrl+b 上下键 上一个及下一个分隔窗口
ctrl+b C-方向键 调整分隔窗口大小
ctrl+b & 确认后退出当前tmux
ctrl+b [ 复制模式,即将当前屏幕移到上一个的位置上,其他所有窗口都向前移动一个。
ctrl+b c 创建新窗口
ctrl+b n 选择下一个窗口
ctrl+b l 最后使用的窗口
ctrl+b p 选择前一个窗口
ctrl+b w 以菜单方式显示及选择窗口
ctrl+b s 以菜单方式显示和选择会话。这个常用到,可以选择进入哪个tmux
ctrl+b t 显示时钟。然后按enter键后就会恢复到shell终端状态
ctrl+b d 脱离当前会话;这样可以暂时返回Shell界面,输入tmux attach能够重新进入之前的会话
- linux 设置定时任务开启脚本
- cron介绍
我们经常使用的是crontab命令是cron table的简写,它是cron的配置文件,也可以叫它作业列表,我们可以在以下文件夹内找到相关配置文件。
1./var/spool/cron/ 目录下存放的是每个用户包括root的crontab任务,每个任务以创建者的名字命名
2./etc/crontab 这个文件负责调度各种管理和维护任务。
3./etc/cron.d/ 这个目录用来存放任何要执行的crontab文件或脚本。
4.我们还可以把脚本放在/etc/cron.hourly、/etc/cron.daily、/etc/cron.weekly、/etc/cron.monthly目录中,让它每小时/天/星期、月执行一次。
- cron介绍
我们上面介绍的这些,只能保证脚本的常驻运行,但是并不能保证脚本异常终止后的自动重启。接下来我们聊一聊supervisor
- supervisor
Supervisor 是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。
cd /usr/local/src
cd /usr/local/src
wget https://pypi.python.org/packages/7b/17/88adf8cb25f80e2bc0d18e094fcd7ab300632ea00b601cbbbb84c2419eae/supervisor-3.3.2.tar.gz
tar -zxvf supervisor-3.3.2.tar.gz
cd supervisor-3.3.2
python setup.py install
Tips:错误1:ImportError: No module named setuptools
## 下载pip
wget https://files.pythonhosted.org/packages/c2/f7/c7b501b783e5a74cf1768bc174ee4fb0a8a6ee5af6afa92274ff964703e0/setuptools-40.8.0.zip
unzip setuptools-40.8.0.zip
cd setuptools-40.8.0
python setup.py install
Tips:错误2:error: Could not find suitable distribution for Requirement.parse(‘meld3>=0.6.5‘),安装meld扩展
wget https://pypi.python.org/packages/45/a0/317c6422b26c12fe0161e936fc35f36552069ba8e6f7ecbd99bbffe32a5f/meld3-1.0.2.tar.gz#md5=3ccc78cd79cffd63a751ad7684c02c91
tar zxvf meld3-1.0.2.tar.gz
cd meld3-1.0.2
python setup.py install
安装完毕
[root@localhost ~]# supervisord -v --查看版本号
3.3.2
[root@localhost ~]# echo_supervisord_conf > /etc/supervisord.conf --生成配置文件
[root@localhost ~]# supervisord -c /etc/supervisord.conf --启动
[root@localhost ~]# ps aux | grep supervisord --查看进程
root 9214 0.0 0.9 215256 9804 ? Ss 06:41 0:00 /usr/bin/python /usr/bin/supervisord -c /etc/supervisord.conf
root 9216 0.0 0.0 112808 964 pts/0 R+ 06:41 0:00 grep --color=auto supervisord
[root@localhost ~]#
# 查看最终配置文件
[root@localhost etc]# cat supervisord.conf |grep -v '^;' |grep -v '^$'
[unix_http_server]
file=/tmp/supervisor.sock ; the path to the socket file
[inet_http_server] ; inet (TCP) server disabled by default
# 注意ip的配置,后面说的很明白 如果需要局域网访问 需要写成 *:port
port=*:9001 ; ip_address:port specifier, *:port for all iface
username=admin ; default is no username (open server)
[supervisord]
logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log
logfile_maxbytes=50MB ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10 ; # of main logfile backups; 0 means none, default 10
loglevel=info ; log level; default info; others: debug,warn,trace
pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid
nodaemon=false ; start in foreground if true; default false
minfds=1024 ; min. avail startup file descriptors; default 1024
minprocs=200 ; min. avail process descriptors;default 200
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
[include]
files = /etc/supervisord.conf.d/*.conf
[root@localhost etc]#
通过浏览器访问一下(此处注意,如果是centos7 需要关闭防火墙systemctl stop firewalld
或者加入ip白名单均可)
- supervisorctl的用法
supervisord : 启动supervisor
supervisorctl reload :修改完配置文件后重新启动supervisor
supervisorctl status :查看supervisor监管的进程状态
supervisorctl start all | 进程名 :启动全部或某进程
supervisorctl stop all | 进程名 :停止全部或某进程
supervisorctl stop all:停止进程,注:start、restart、stop都不会载入最新的配置文件。
supervisorctl update:根据最新的配置文件,启动新配置或有改动的进程,配置没有改动的进程不会受影响而重启
# 读取有更新(增加)的配置文件,不会启动新添加的程序
$supervisorctl reread
# 重启配置文件修改过的程序
$supervisorctl update
# 查看程序状态
$supervisorctl status
# 启动程序 App_name
$supervisorctl start App_name
# 关闭程序 App_name
$supervisorctl stop App_name
# 重启程序 App_name
supervisorctl -c /etc/supervisord.conf restart App_name:
supervisorctl -c /etc/supervisord.conf start App_name:App_name_01
#supervisord **重载配置要用update ,不要用reload!
$supervisorctl restart App_name
以上命令也可以在supervisorctl Shell中执行:
$supervisorctl
supervisor>reread
supervisor> update
supervisor> status
supervisor> start App_name
supervisor> stop App_name
supervisor> restart App_name
- 创建一个任务
[root@localhost supervisord.conf.d]# vi for.conf
; 设置进程的名称,使用 supervisorctl 来管理进程时需要使用该进程名
[program:fornumber]
command=/bin/sh /root/for.sh ;具体命令
;numprocs=1 ; 默认为1
;process_name=%(program_name)s ; 默认为 %(program_name)s,即 [program:x] 中的 x
;directory=/home/python/tornado_server ; 执行 command 之前,先切换到工作目录
user=root ; 使用 oxygen 用户来启动该进程
; 程序崩溃时自动重启,重启次数是有限制的,默认为3次
autorestart=true
redirect_stderr=true ; 重定向输出的日志
stdout_logfile = /var/log/supervisord/tornado_server.log
loglevel=info
重载配置文件supervisorctl reload
启动服务supervisord -c /etc/supervisord.conf
在conf目录下,生成了num.log 文件,我刚开始也疑惑了一下,为什么日志打到了这个目录,一瞬间明白了,for.sh 里面有echo "$i " >>num.log;
就是输出当前目录,但是命令执行的时候就是以配置文件为脚本运行的目录了。所以我们写的时候最好写绝对路径。
[root@localhost supervisord.conf.d]# ls
for.conf num.log
在这里插入图片描述
- 设置开机自启
# vi supervisord.service
#supervisord.service
[Unit]
Description=Supervisor daemon
[Service]
Type=forking
ExecStart=/usr/bin/supervisord -c /etc/supervisord.conf
ExecStop=/usr/bin/supervisorctl shutdown
ExecReload=/usr/bin/supervisorctl reload
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
将文件拷贝到/usr/lib/systemd/system/(注意文件的权限要可执行) cp supervisord.service /usr/lib/systemd/system/
[root@localhost init.d]# systemctl enable supervisord
Failed to execute operation: Access denied
# 如果出现denied 输入下面命令
[root@localhost init.d]# setenforce 0
[root@localhost init.d]# systemctl enable supervisord
Created symlink from /etc/systemd/system/multi-user.target.wants/supervisord.service to /usr/lib/systemd/system/supervisord.service.
[root@localhost init.d]# systemctl is-enabled supervisord
enabled
网友评论