目录
- 项目介绍和源码;
- 拿来即用的bootstrap模板;
- 服务器SSH服务配置与python中paramiko的使用;
- 用户登陆与session;
- 最简单的实践之修改服务器时间;
- 查看和修改服务器配置与数据库的路由;
- 基于websocket的实时日志实现;
- 查看服务器中的日志与前端的datatable的利用;
- 重启服务器的进程。
前言
相当于前面的文章而言,这篇文章就比较简短了。关于服务器中进程需要经常批量的重启,一般会在服务器中写个shell脚本去统一执行,网页的功能仅仅是用paramiko函数调用服务器中的shell脚本就好,然后把失败和成功的重启记录在前端记录下来。页面如图1所示。
功能实现
页面显示
- 页面html函数
页面仅仅由一个执行重启操作的模块和记录重启次数的模块构成。当然A在重启时,B进入网站是不能执行重启的,html代码中的{{taskor}}变量中记录的就是后台重启时当下操作人,具体的实现在操作互斥中会说说。
{% extends "./base.html" %} {% block css %}{% endblock %} {% block title %}{{ title }}{% endblock %} {% block log %}{{ title }}{% endblock %} {% block username %}{{ username }}{% endblock %} {% block mainbody %} <section class="wrapper site-min-height"> <div class="fakeloader"></div> <h3><i class="fa fa-angle-right"></i> 服务器重启 <i class="fa fa-refresh"></i></h3> <div class="row mt"> <div class="col-lg-12"> <div class="form-panel"> <h4 class="mb"> 服务器重启</h4> {% if taskor != '' %} <div class="col-sm-12"> <div class="alert alert-danger" id="loading-tips"><b>稍等~</b> 【{{taskor}}】正在重启进程...</div> </div> <div><br><br><br><br></div> {% else %} <div class="col-sm-12"> <div class="alert alert-danger" id="pre-tips"><b>注意!</b> 此操作将会导致进程重启。</div> <div class="alert alert-danger" style="display:none;" id="loading-tips"><b>稍等~</b> 进程正在重启...</div> <div class="progress progress-striped active" style="display:none;" id="loading"> <div class="progress-bar" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div> </div> </div> <div><br><br><br><br></div> <div class="col-sm-12" style="text-align: right"> <button type="button" id="restart" class="btn btn-theme04">重启服务器</button> </div> <div><br><br><br></div> {% endif %} </div> </div> </div> <div class="row mt"> <div class="col-lg-12"> <div class="form-panel"> <h4 class="mb"> 重启服务器的记录</h4> <table class="table table-hover"> <thead> <tr> <th style="width:10%;">重启时间</th> <th style="width:10%;">重启人</th> <th style="width:10%;">重启是否成功</th> </tr> </thead> <tbody id="tab"> {% for item in reboot %} <tr> <td>{{ item.reboottime }}</td> <td>{{ item.rebooter }}</td> <td>{{ item.rebootresult }}</td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </section> {% endblock %}
- 页面javascript函数
页面用到的javascript函数也仅仅是对图1中唯一一个按钮批量重启进程作用(函数中的swal只是一个模态框插件,每当点击按钮时唤起,如图2,关于它的引用文章用户登陆与session提到过),函数通过ajax请求到后端处理。
{% block scripts %} <script> $(document).ready(function(){ $("#restart").click(function(){ swal({ title: '您确定要重启吗?', type: 'warning', confirmButtonColor: '#DD6B55', confirmButtonText:"是的,我要重启!", cancelButtonText:"让我再考虑一下…", showLoaderOnConfirm: true, //加载按钮是否可见 showCancelButton: true, preConfirm: function() { return new Promise(function(resolve) { setTimeout(function(){ $("#restart").hide(); $("#pre-tips").hide(); $("#loading-tips").show(); $("#loading").show(); resolve(); }, 3000); }); }, allowOutsideClick: false, //弹框外是否可点 }).then(function(res){ if (res){ $.ajax({ url:"restartserver", type:'GET', success: function(arg){ ret = eval(arg); if(ret.status){ swal({ type: 'success', title: '重启完成!', confirmButtonText: '确定', confirmButtonColor: '#4cd964' }).then(function(){ window.location.reload(); }); }else{ swal({ type: 'error', title: '重启失败!', confirmButtonText: '确定', confirmButtonColor: '#4cd964' }).then(function(){ window.location.reload(); }); } }}); }}) }); }); </script> {% endblock %}
- 创建model函数
这里会创建两个model函数,一个在最简单的实践之修改服务器时间中提到过的taskinbackground,它可以将正在进行的事件记录在数据库中,另外一个是记录重启操作的表rebootserver。
# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.db import models class taskinbackground(models.Model): taskname = models.CharField(max_length=50) taskor = models.CharField(max_length=100) class Meta: db_table = 'task' app_label = "server" class rebootserver(models.Model): rebooter = models.CharField(max_length=100) reboottime = models.CharField(max_length=200, default="") rebootresult = models.CharField(max_length=200, default="") class Meta: db_table = 'reboot' app_label = "server"
- 增加url和view函数
server/urls.py中添加reboot和restartserver,前者用来渲染页面的,后者是用来实现重启的功能。
from django.conf.urls import url import views urlpatterns = [ url(r'^reboot', views.rebootserver), url(r'^restartserver', views.restartserver), ]
server/views.py中添加渲染页面的函数rebootserver,和重启的功能函数restartserver。
# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.contrib.auth import logout from django.shortcuts import render_to_response from django.http import JsonResponse from django.contrib.auth.decorators import login_required import json import time # 服务器的名字 htmltitle = '服务器工具' # 渲染页面 @login_required(login_url='/loginpage') def rebootserver(request): from server import models username = request.session.get('username') # 取出数据库后10条重启的数据 reboot = models.rebootserver.objects.all()[::-1][0:10] taskor = '' try: # 后台是否有其他人在重启 taskor = models.taskinbackground.objects.get(taskname='reboot').taskor except Exception as e: print e pagedict = {'reboot': reboot, 'title': htmltitle, 'taskor': taskor, 'username': username} return render_to_response("servermaterial/reboot.html", pagedict) # 重启进程 def restartserver(request): if request.method == 'GET': ret = {'status': False} from WebTool.functions import rebootserver from server import models username = request.session.get('username') models.taskinbackground.objects.filter(taskname='reboot').delete() # 将重启进程的任务写进数据库 models.taskinbackground.objects.create(taskname='reboot', taskor=username) res = rebootserver() local_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) if res == 'Successful Rebooted!': ret['status'] = True # 重启成功记录写入rebootserver中 models.rebootserver.objects.create(rebooter=username, reboottime=local_time, rebootresult='重启成功') # 从taskinbackground中删除后台正在执行的重启任务 models.taskinbackground.objects.filter(taskname='reboot').delete() return JsonResponse(ret) elif res == 'Unsuccessful Rebooted!': # 重启失败记录写入rebootserver中 models.rebootserver.objects.create(rebooter=username, reboottime=local_time, rebootresult='重启失败') # 从taskinbackground中删除后台正在执行的重启任务 models.taskinbackground.objects.filter(taskname='reboot').delete() ret['status'] = False return JsonResponse(ret) else: models.rebootserver.objects.create(rebooter=username, reboottime=local_time, rebootresult='重启失败') models.taskinbackground.objects.filter(taskname='reboot').delete() ret['status'] = False return JsonResponse(ret)
看到这里,我们的重启进程的paramiko函数rebootserver写在functions(WebTool/WebTool/functions.py)中,由于自己的Linux没有环境,当时只好写了一个shell脚本模拟进程重启。具体内容请移步至文章服务器SSH服务配置与python中paramiko的使用。
操作互斥
文章最简单的实践之修改服务器时间提到过,当A修改时间时,其他人没法修改时间,这里用的方法也是同理,将重启进程看成一个后台任务,任务执行时写在model中的taskinbackground中,其他人打开页面时,页面渲染函数会在数据库中查一查有没有对应名字的任务taskor = models.taskinbackground.objects.get(taskname='reboot').taskor
如果有就不提供重启的功能,其效果如图3所示。
{% if taskor != '' %} <div class="col-sm-12"> <div class="alert alert-danger" id="loading-tips"><b>稍等~</b> 【{{taskor}}】正在重启进程...</div> </div> <div><br><br><br><br></div> {% else %} <div class="col-sm-12"> <div class="alert alert-danger" id="pre-tips"><b>注意!</b> 此操作将会导致进程重启。</div> <div class="alert alert-danger" style="display:none;" id="loading-tips"><b>稍等~</b> 进程正在重启...</div> <div class="progress progress-striped active" style="display:none;" id="loading"> <div class="progress-bar" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div> </div> </div> <div><br><br><br><br></div> <div class="col-sm-12" style="text-align: right"> <button type="button" id="restart" class="btn btn-theme04">重启服务器</button> </div> <div><br><br><br></div> {% endif %}
这个互斥的逻辑可以用下面的逻辑图图4描述。通俗点说,其实就相当于用数据库做了一个互斥量,一次只准一个线程执行任务。
结语
这篇文章简单的说了下怎么去用网站调用后台去批量执行进程重启,然后用数据库的表做一个简单的互斥量,防止多个用户同时操作。