python小白系列2

监控的目的

  • 报告系统运行状况:
    — 每一部分必须同时监控
    — 内容包括吞吐量、反应时间、使用率等

  • 提前发现问题
    — 进行服务器性能调整前,知道调整什么
    — 找出系统的瓶颈在什么地方

监控的资源类别

  • 公开数据
    — web、ftp、ssh、数据库等应用服务
    — tcp或udp端口

  • 私有数据
    — cpu、内存、磁盘、网卡流量等使用信息
    — 用户、进程等运行信息

常用系统监控命令:

[root@zabbix ~]# free -m		//查看内存信息
[root@zabbix ~]# df -h		//查看磁盘挂载信息
[root@zabbix ~]# swapon -s		//查看交换分区
[root@zabbix ~]# iostat		//查看磁盘信息
[root@zabbix ~]# uptime		//查看cpu负载
[root@zabbix ~]# ifconfig		//查看网卡信息
[root@zabbix ~]# netstat -ntulap		//查看端口信息
[root@zabbix ~]# ping		//查看网络连接信息
[root@zabbix ~]# ps aux		//查看进程信息

自动化监控系统

  • Cacti:基于snmp协议的监控软件,强大的绘图能力
  • Nagios:基于Agent监控,强大的状态检查与报警机制,插件多,自己编写监控键本潜入到Nagios非常方便
  • Zabbix:基于多种监控机制,支持分布式监控

Zabbix简介

  • 一个高度集成的监控解决方案
  • 可以实现企业级的开源分布式监控
  • 通过C/S模式采集监控数据
  • 通过B/S模式实现web管理

zabbix监控拓扑
在这里插入图片描述

  • 监控服务器
    — 监控服务器可以通过snmp或agent采集数据
    — 数据可以写入mysql、oracle等数据库
    — 服务器使用lnmp实现web前端的管理

  • 被监控主机
    — 被监控主机需要安装agent
    — 常见的网络设备一般支持snmp

一、部署zabbix
1 服务端部署LNMP环境

[root@zabbix ~]# yum  -y install gcc pcre-devel openssl-devel zlib-devel  //安装依赖包
[root@zabbix ~]# ls
anaconda-ks.cfg                         
php-bcmath-5.4.16-42.el7.x86_64.rpm    
initial-setup-ks.cfg                    
php-fpm-5.4.16-42.el7.x86_64.rpm       
libevent-devel-2.0.21-4.el7.x86_64.rpm  
php-mbstring-5.4.16-42.el7.x86_64.rpm  
nginx-1.12.2.tar.gz                     
zabbix.tar.gz 
[root@zabbix ~]# tar -xf nginx-1.12.2.tar.gz
[root@zabbix ~]# cd nginx-1.12.2/
[root@zabbix nginx-1.12.2]# ./configure --with-http_ssl_module
[root@zabbix nginx-1.12.2]# make
[root@zabbix nginx-1.12.2]# make install
[root@zabbix nginx-1.12.2]# ls /usr/local/nginx/
conf  html  logs  sbin
[root@zabbix nginx-1.12.2]# yum -y install php php-mysql mariadb
[root@zabbix nginx-1.12.2]# yum -y install mariadb-server mariadb-devel
[root@zabbix nginx-1.12.2]# cd ..
[root@zabbix ~]# yum -y install php-fpm-5.4.16-42.el7.x86_64.rpm
#检查安装环境
[root@zabbix ~]# rpm -q php php-mysql mariadb mariadb-server
php-5.4.16-42.el7.x86_64
php-mysql-5.4.16-42.el7.x86_64
mariadb-5.5.56-2.el7.x86_64
mariadb-server-5.5.56-2.el7.x86_64
[root@zabbix ~]# rpm -q php-fpm
php-fpm-5.4.16-42.el7.x86_64
[root@zabbix ~]# rpm -q mariadb-devel 
mariadb-devel-5.5.56-2.el7.x86_64
[root@zabbix ~]# ls /usr/local/nginx/
conf  html  logs  sbin

2 配置nginx

[root@zabbix ~]# vim /usr/local/nginx/conf/nginx.conf
17 http {
18     fastcgi_buffers 8 16k;       #缓存php生成的页面内容,8个16k
19     fastcgi_buffer_size 32k;     #缓存php生产的头部信息
20     fastcgi_connect_timeout 300; #连接PHP的超时时间
21     fastcgi_send_timeout 300;    #发送请求的超时时间
22     fastcgi_read_timeout 300;    #读取请求的超时时间
65         location ~ \.php$ {		#开启解释php代码
66             root           html;
67             fastcgi_pass   127.0.0.1:9000;
68             fastcgi_index  index.php;
69         #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
70             include        fastcgi.conf
71         }
[root@zabbix ~]# /usr/local/nginx/sbin/nginx -t		//检查配置文件是否修改正确
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

3 开启服务

[root@zabbix ~]# systemctl start mariadb
[root@zabbix ~]# netstat -ntulp| grep :3306
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      9099/mysqld         
[root@zabbix ~]# systemctl start php-fpm
[root@zabbix ~]# netstat -ntulp| grep :9000
tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      9157/php-fpm: maste 
[root@zabbix ~]# /usr/local/nginx/sbin/nginx 
[root@zabbix ~]# netstat -ntulp| grep :80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      9167/nginx: master 

4 测试php页面

[root@zabbix ~]# vim /usr/local/nginx/html/test.php
<?php
$i=33;
echo $i;
?>
[root@zabbix ~]# curl http://localhost/test.php
33

5 安装zabbix源码

[root@zabbix ~]# yum -y install libevent-devel-2.0.21-4.el7.x86_64.rpm
[root@zabbix ~]# yum -y install net-snmp-devel curl-devel
[root@zabbix ~]# tar -xf zabbix-3.4.4.tar.gz 
[root@zabbix ~]# cd zabbix-3.4.4/
[root@zabbix zabbix-3.4.4]# ./configure --enable-server --enable-proxy  \
--enable-agent --with-mysql=/usr/bin/mysql_config \
--with-net-snmp --with-libcurl
[root@zabbix zabbix-3.4.4]# make install
[root@zabbix zabbix-3.4.4]# ls /usr/local/etc/		//查看配置文件
zabbix_agentd.conf    zabbix_proxy.conf    zabbix_server.conf
zabbix_agentd.conf.d  zabbix_proxy.conf.d  zabbix_server.conf.d
[root@zabbix zabbix-3.4.4]# ls /usr/local/bin/		//查看命令
zabbix_get  zabbix_sender

6 初始化zabbix

[root@zabbix zabbix-3.4.4]# mysql
MariaDB [(none)]> creat database zabbix character set utf8;
MariaDB [(none)]> grant all on zabbix.* to zabbix@'localhost' identified by 'zabbix';
[root@zabbix zabbix-3.4.4]# cd database/
[root@zabbix database]# ls
ibm_db2  Makefile  Makefile.am  Makefile.in  mysql  oracle  postgresql  sqlite3
[root@zabbix mysql]# mysql -uzabbix -pzabbix zabbix
MariaDB [zabbix]> show tables;
[root@zabbix mysql]# cd ../..
[root@zabbix zabbix-3.4.4]# cp -a frontends/php/* /usr/local/nginx/html/
[root@zabbix zabbix-3.4.4]# chmod -R 777 /usr/local/nginx/html

7 修改配置文件,启动服务

[root@zabbix zabbix-3.4.4]# vim /usr/local/etc/zabbix_server.conf		//修改监控服务端配置文件
38 LogFile=/tmp/zabbix_server.log		//日志文件
85 DBHost=localhost			//数据库主机(本机)
95 DBName=zabbix		//设置数据库名称
111 DBUser=zabbix		//设置数据库账户
119 DBPassword=zabbix		//设置数据库密码
[root@zabbix zabbix-3.4.4]# useradd zabbix
[root@zabbix zabbix-3.4.4]# zabbix_server 
[root@zabbix zabbix-3.4.4]# netstat -ntulp |grep :10051
tcp        0      0 0.0.0.0:10051           0.0.0.0:*               LISTEN      19134/zabbix_server
[root@zabbix zabbix-3.4.4]# vim /usr/local/etc/zabbix_agentd.conf		//修改i监控客户端配置文件(这里指本机)
30 LogFile=/tmp/zabbix_agentd.log		//设置日志文件
93 Server=127.0.0.1, 192.168.2.55		//主动监控服务器IP
134 ServerActive=127.0.0.1:10051		//监控服务器ip地址端口号
145 Hostname=Zabbix server			//设置本机主机名
280 UnsafeUserParameters=1```	//启用自定义key
[root@zabbix zabbix-3.4.4]# zabbix_agentd 
[root@zabbix zabbix-3.4.4]# netstat -ntulp |grep :10050
tcp        0      0 0.0.0.0:10050           0.0.0.0:*               LISTEN      22395/zabbix_agentd

8 初始化访问zabbix监控页面
在这里插入图片描述
第二步检查配置环境时报错,根据错误提示修改相应配置文件,并安装依赖包

[root@zabbix zabbix-3.4.4]# vim /etc/php.ini
384 max_execution_time = 300		    //最大执行时间
394 max_input_time = 300		        //服务器接收数据的时间限制
672 post_max_size = 16M		            //POST数据最大容量
878 date.timezone = Asia/Shanghai		//设置时区
[root@zabbix zabbix-3.4.4]# systemctl restart php-fpm
[root@zabbix ~]# yum -y install php-bcmath-5.4.16-42.el7.x86_64.rpm
[root@zabbix ~]# yum -y install php-mbstring-5.4.16-42.el7.x86_64.rpm
[root@zabbix ~]# yum -y install php-gd php-xml php-ldap
[root@zabbix ~]# systemctl restart php-fpm

刷新页面,没有提示错误,配置生效
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

[root@zabbix ~]# ls /usr/local/nginx/html/conf/zabbix.conf.php		//安装完成后的配置文件
/usr/local/nginx/html/conf/zabbix.conf.php

在这里插入图片描述
初始登录用户名和密码:admin,zabbix
登录后,修改管理员密码和语言
基本使用:
(1)查看监控模板(配置—>模板)
(2)查看已监控的主机(配置—>主机—>启用)
(3)查看监控信息(监测中—>最新数据—>主机—>zabbix server)

9 配置zabbix监控服务(监控web33和web44主机)
(1)安裝zabbix客戶端zabbix_agentd

[root@web33 ~]# yum -y install httpd		//以web33主机为例
[root@web33 ~]# echo web33  > /var/www/html/test.html
[root@web33 ~]# systemctl start httpd
[root@web33 ~]# curl http://localhost/test.html
[root@web33 ~]# vim mount_zabbix.sh
#!/bin/bash
useradd -s /sbin/nologin zabbix
yum -y install gcc pcre-devel
tar -xf zabbix-3.4.4.tar.gz
cd zabbix-3.4.4/
./configure --enable-agent
make && make install
[root@web33 ~]# ./mount_zabbix.sh		//安装zabbix源码包
[root@web33 ~]# ls /usr/local/sbin/
zabbix_agentd
[root@web33 ~]# ls /usr/local/etc/
zabbix_agentd.conf  zabbix_agentd.conf.d
[root@web33 ~]# vim /usr/local/etc/zabbix_agentd.conf		//修改配置文件
30 LogFile=/tmp/zabbix_agentd.log
93 Server=127.0.0.1, 192.168.2.55		//允许哪些主机监控本机
134 ServerActive=192.168.2.55:10051		//监控服务器ip和端口
145 Hostname=web33		                //被监控主机的名称
280 UnsafeUserParameters=1		        //允许自定义监控脚本
[root@web33 ~]# zabbix_agentd 
[root@web33 ~]# netstat -ntulp |grep :10050
tcp        0      0 0.0.0.0:10050           0.0.0.0:*               LISTEN      20859/zabbix_agentd

(2)监控网站服务器web33和web44
访问http://192.168.2.55/index.php
a. 配置 —>主机—>创建主机—>主机名称、可见的名称、群组、ip地址—>模板—>链接指示器:选择相应模板,添加
b. 配置—>主机—>可用性
(3)自定义监控命令

[root@web33 ~]# sed -n '280p' /usr/local/etc/zabbix_agentd.conf
UnsafeUserParameters=1		
[root@web33 ~]# grep -n 'Include' /usr/local/etc/zabbix_agentd.conf
255:### Option: Include
261:# Include=
263:# Include=/usr/local/etc/zabbix_agentd.userparams.conf
264:# Include=/usr/local/etc/zabbix_agentd.conf.d/
265:# Include=/usr/local/etc/zabbix_agentd.conf.d/*.conf
[root@web33 ~]# sed -i '265s/^#//' /usr/local/etc/zabbix_agentd.conf		//去掉265行注释
[root@web33 ~]# grep -n 'Include' /usr/local/etc/zabbix_agentd.conf
255:### Option: Include
261:# Include=
263:# Include=/usr/local/etc/zabbix_agentd.userparams.conf
264:# Include=/usr/local/etc/zabbix_agentd.conf.d/
265: Include=/usr/local/etc/zabbix_agentd.conf.d/*.conf
########################################################################
[root@web33 ~]# vim /usr/local/etc/zabbix_agentd.conf
265 Include=/usr/local/etc/zabbix_agentd.conf.d/*.conf		//自定义监控配置文件
280 UnsafeUserParameters=1		//开启自定义监控
[root@web33 ~]# wc -l /etc/passwd |awk '{print $1}'		//统计用户数
42
[root@web33 ~]# vim /usr/local/etc/zabbix_agentd.conf.d/get_sum_users.conf
UserParameter=getusers,wc -l /etc/passwd |awk '{print $1}'		//自定义监控格式:命令名,命令
[root@web33 ~]# killall -9 zabbix_agentd		//杀死进程
[root@web33 ~]# killall -9 zabbix_agentd
zabbix_agentd: no process found
[root@web33 ~]# zabbix_agentd		//重启zabbix_agentd服务
[root@web33 ~]# netstat -ntulp |grep :10050
tcp        0      0 0.0.0.0:10050           0.0.0.0:*               LISTEN      5300/zabbix_agentd
[root@web33 ~]# zabbix_get -s 127.0.0.1 -p 10050 -k getusers		//测本机试自定义监控命令
42
[root@zabbix ~]# zabbix_get -s 192.168.2.33 -p 10050 -k getusers		//监控服务器远程测试被监控端自定义命令
42

(4)登陆管理页面配置自定义监控、

  • 创建新监控模板:配置—>模板—>创建模板
  • 创建应用集:配置—>模板—>新建模板中应用集—>创建应用集
  • 创建监控项:配置—>模板—>新建模板中监控项—>创建监控项(键值与客户端自定义的监控命令绑定)
  • 调用新监控模板监控web33主机:配置—>主机—>选择要监控主机(web33)—>链接指示器,添加自定义模板

10、zabbix报警配置
概念介绍

  • 触发器(trigger)
    — 表达式,如内存不足300M,用户超过100个等
    — 当触发条件发生后,会导致一个触发事件
    — 触发事件会执行某个动作
  • 动作(action)
    — 触发器的条件被触发后的行为
    — 可以是发送邮件、也可以是重启某个服务等

(1)创建触发器:配置—>模板—>选择对应模板中触发器—>创建触发器
—>表达式:添加—>选择监控项,设置功能—>底部添加
(2)指定触发器触发后要执行的动作方式(这里选择发送邮件的方式):管理—>报警媒介类型—>Email—>配置后点击更新
在这里插入图片描述
检查本机邮件服务器25端口是否开启

[root@zabbix ~]# netstat -ntulp |grep :25
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1124/master         
tcp6       0      0 ::1:25                  :::*                    LISTEN      1124/master

若没有25端口,则需要安装并启动postfix

[root@zabbix ~]# yum -y install postfix
[root@zabbix ~]# systemctl start postfix
[root@zabbix ~]# systemctl enable postfix

测试给本机给zabbix用户发送邮件

[root@zabbix ~]# mail -s "testmail" zabbix < /etc/hosts
[root@zabbix ~]# mail -u zabbix
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/mail/zabbix": 1 message
>   1 root                  Thu May 23 21:35  20/750   "testmail"

(3)为账户添加Media(指定收件人邮箱)
管理—>用户—>Admin—>报警媒介—>添加—>收件人:zabbix@localhost—>添加—>更新
(4)创建执行动作
配置—>动作—>事件源选择触发器,创建动作—>动作:定义名称(dongzuo1),新的触发条件选择触发器,选择web33: chufaqi1_web33_users,添加—>操作:默认接收人(定义标题),点击“新的”,发送到用户:添加Admin,仅送到Email,点击小字体“添加”,最后点击最下方添加
(5)测试触发器,发送报警邮件

[root@web33 ~]# useradd tom1
[root@web33 ~]# useradd tom2
[root@web33 ~]# useradd tom3
##############################################################
[root@zabbix ~]# mail -u zabbix		//查看邮件(收到报警邮件2)
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/mail/zabbix": 2 messages 1 new
    1 root                  Thu May 23 21:35  20/750   "testmail"
>N  2 [email protected]  Thu May 23 23:00  20/819   "big33"
& 2
Message  2:
From [email protected]  Thu May 23 23:00:06 2019
Return-Path: <[email protected]>
X-Original-To: zabbix@localhost
Delivered-To: [email protected]
From: <[email protected]>
To: <[email protected]>
Date: Thu, 23 May 2019 23:00:06 +0800
Subject: big33
Content-Type: text/plain; charset="UTF-8"
Status: R

Problem started at 23:00:03 on 2019.05.23
Problem name: chufaqi1_web33_users
Host: web33
Severity: Disaster

Original problem ID: 164

Django简介
• Django是一个开放源代码的Web应用框架,由Python写成

框架介绍
• Django 框架的核心组件有:
– 用于创建模型的对象关系映射
– 为最终用户设计的完美管理界面
– 一流的 URL 设计
– 设计者友好的模板语言
– 缓存系统

MTV模式
• Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同
– M 代表模型(Model):负责业务对象和数据库的关系映射(ORM)
– T 代表模板 (Template):负责如何把页面展示给用户(html)
– V 代表视图(View):负责业务逻辑,并在适当时候调用Model和Template
• 除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template

MTV响应模式
• Web服务器(中间件)收到一个http请求
• Django在URLconf里查找对应的视图(View)函数来处理http请求
• 视图函数调用相应的数据模型来存取数据、调用相应的模板向用户展示页面
• 视图函数处理结束后返回一个http的响应给Web服务器
• Web服务器将响应发送给客户端

在这里插入图片描述

虚拟环境
虚拟环境可以理解为就是一个目录,克隆python到这个目录,安装模块到虚拟环境,将来不用的时候,可以直接把虚拟环境的目录删除。

安装django

[root@room9pc01 exercise]# mkdir day17
[root@room9pc01 exercise]# cd day17
[root@room9pc01 day17]# ls
[root@room9pc01 day17]# python3 -m venv /opt/djenv/		//创建python虚拟环境目录
[root@room9pc01 day17]# ls /opt/djenv/		
bin  include  lib  lib64  pyvenv.cfg
[root@room9pc01 day17]# source /opt/djenv/bin/activate		//激活python虚拟环境
(djenv) [root@room9pc01 day17]# cd /root/桌面/python/zzg_pypkgs/dj_pkgs
(djenv) [root@room9pc01 dj_pkgs]# ls
asn1crypto-0.24.0-py2.py3-none-any.whl
cffi-1.11.5-cp36-cp36m-manylinux1_x86_64.whl
cryptography-2.3.1-cp34-abi3-manylinux1_x86_64.whl
Django-1.11.6-py2.py3-none-any.whl
idna-2.7-py2.py3-none-any.whl
pycparser-2.18.tar.gz
PyMySQL-0.9.2-py2.py3-none-any.whl
pytz-2018.5-py2.py3-none-any.whl
six-1.11.0-py2.py3-none-any.whl
(djenv) [root@room9pc01 dj_pkgs]# pip install *		//安装django
###########################################################################
(djenv) [root@room9pc01 dj_pkgs]# pip install django==1.11.6			//在线安装django

创建项目
• Djanog可以自动生成一些代码,这些代码创建一个Django项目:一个Django实例的设置集合,包括数据库的配置、Django有关的选项和应用有关的选项

(djenv) [root@room9pc01 dj_pkgs]# cd -
(djenv) [root@room9pc01 day17]# ls
(djenv) [root@room9pc01 day17]# django-admin startproject mysite		//创建项目mysite
(djenv) [root@room9pc01 day17]# ls
mysite
(djenv) [root@room9pc01 day17]# tree mysite/
mysite/				# 项目的根目录
├── manage.py		# 项目管理工具
└── mysite			# 项目配置目录
    ├── __init__.py
    ├── settings.py		# 配置文件
    ├── urls.py			# 程序的入口文件 URLConf
    └── wsgi.py		# 将项目部署到Web服务器时应用

项目文件说明
• 外层的mysite/根目录仅仅是项目的一个容器。 它的名字与Django无关;可以将其重命名为你喜欢的任何内容
• manage.py:一个命令行工具,可以使用多种方式对Django项目进行交互。 可以在django-admin和manage.py中读到关于manage.py的所有细节
• 内层的mysite/目录是项目的真正的Python包。 它是导入任何东西时将需要使用的Python包的名字(例如 mysite.urls)
• mysite/init.py:一个空文件,它告诉Python这个目录应该被看做一个Python包
• mysite/settings.py:该Django 项目的设置/配置。Django settings 将告诉你这些设置如何工作。
• mysite/urls.py:此Django项目的URL声明;Django驱动的网站的“目录”
• mysite/wsgi.py:用于项目的与WSGI兼容的Web服务器入口

开发服务器
• Django自带一个开发服务器,默认运行于8000端口
• 该开发服务器不要应用在生产环境下
测试站点

(djenv) [root@room9pc01 day17]# cd mysite/
(djenv) [root@room9pc01 mysite]# python manage.py runserver  //django提供了一个测试服务器,功能简单,不能用于生产环境

浏览器访问http://127.0.0.1:8000/
在这里插入图片描述
配置pycharm
(1)File -> Settings -> Project: day03 -> Project Interpreter -> 点右上角齿轮 -> add Local -> Existing environment (勾选Make available to all project) -> 点右侧… -> /opt/djenv/bin/python
(2)File -> Settings -> Languages & Frameworks -> django -> Enable django support -> django project root 填写外层mysite目录 -> settings 选择mysite/settings.py

配置项目数据库

(djenv) [root@room9pc01 mysite]# mysql -uroot -p123456
MariaDB [(none)]> CREATE DATABASE dj1812 DEFAULT CHARSET UTF8;

修改django设置

# mysite/settings.py(#开头表示配置该文件,下同)
28 ALLOWED_HOSTS = '*'		//允许所有主机访问
77 DATABASES = {		//数据库访问设置
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'dj1812',
        'USER': '   root'
        'PASSWORD': '123456'
        'HOST': '127.0.0.1'
        'PORT': '3306'
    }
}
111 LANGUAGE_CODE = 'zh-hans'		//中文
113 TIME_ZONE = 'Asia/Shanghai'		//上海时区
119 USE_TZ = False
############################################################################
# mysite/__init__.py
import pymysql
pymysql.install_as_MySQLdb()
############################################################################
(djenv) [root@room9pc01 mysite]# ls
db.sqlite3  manage.py  mysite
(djenv) [root@room9pc01 mysite]# systemctl stop httpd
(djenv) [root@room9pc01 mysite]# python manage.py runserver 0:80

在这里插入图片描述
生成数据库
• Django生成的项目,使用了很多预先编写好的应用,这些应用需要用到数据
• 只要执行以下语句,即可自动生成数据库生成内建应用的表

(djenv) [root@room9pc01 mysite]# python manage.py makemigrations
(djenv) [root@room9pc01 mysite]# python manage.py migrate
(djenv) [root@room9pc01 mysite]# mysql -uroot -p123456
MariaDB [(none)]> use dj1812
MariaDB [dj1812]> show tables;		#查看上一步生成的表

创建管理员账户
• 访问后台需要有超级用户身份
• 超级用户需要单独创建
• 用户将写到数据库中

(djenv) [root@room9pc01 mysite]# python manage.py createsuperuser
依次输入:管理员用户名(默认root),邮箱地址,密码(必须大于8个字符,且不能全为数字)
(djenv) [root@room9pc01 mysite]# python manage.py runserver 0:80

浏览器访问后台管理页面 :http://127.0.0.1/admin

在这里插入图片描述

创建应用

  • 软件开发也希望能实现即插即用一样的功能,在编写python程序时,本着DRY(Don’t Repeat Yourself)原则。
  • 可以把一个项目拆解成很多应用。每一个应用编写好后,还可以集成到其他项目。

应用简介
• 应用是一个Web应用程序,它完成具体的事项 ——比如一个博客系统、一个存储公共档案的数据库或者一个简单的投票应用
• 项目是特定网站的配置和应用程序的集合
• 一个项目可以包含多个应用
• 一个应用可以运用到多个项目中去

创建应用
• 应用可以放在Python path上的任何位置
• 可以在manage.py文件同级目录创建应用,以便可以将它作为顶层模块导入,而不是mysite的子模块

案例:创建网页投票结果统计项目

(djenv) [root@room9pc01 mysite]# python manage.py startapp polls		//创建应用polls

集成应用到项目

# mysite/settings.py
33 INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'polls',		#激活应用polls
]

配置URLconf
• 为了整洁起见,用户与polls相关的url都交给polls应用进行路由

url规划

  • http://127.0.0.1/polls/:投票首页,列出全部的问题
  • http://127.0.0.1/polls/1/:1号问题投票详情
  • http://127.0.0.1/polls/1/result/:1号问题的投票结果

授权

  • 项目的入口是mysite/urls.py,如果所有应用涉及到的网址全部写到这个文件,文件内容将会非常多,不便于管理。
  • 为了方便管理,将某一应用的URL交给应用处理。比如投票应用的url都以polls/开头,所以将以polls/开头的URL交给polls应用处理。
# mysite/urls.py
from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^polls/', include('polls.urls')),
]

一、创建首页
1、配置urll

# mysite/polls/urls.py
from django.conf.urls import url
from . import views

urlpatterns = [
    # url(正则, 函数, name=该url的名字),
    url(r'^$', views.index, name='index'),		//正则匹配首页(http://127.0.0.1/polls/,后续所有网页的url配置均从http://127.0.0.1/polls/之后的字符开始匹配)
]

创建视图
• 视图是URLconf路由到某一URL时执行的函数
• 为上一步polls主页编写简单视图,编辑polls/views.py如下:
2、编写函数

# mysite/polls/views.py
from django.shortcuts import render

def index(request):		//首页函数
    return render(request, 'index.html')		

函数至少需要有一个参数,用户的请求会传给该参数。返回值是通过render函数调用一个模板,将模板文件发送给用户。
3、创建模板文件index.html

(djenv) [root@room9pc01 polls]# mkdir templates		//模板文件目录名必须为templates
(djenv) [root@room9pc01 polls]# ls
admin.py  __init__.py  models.py    templates  urls.py
#############################################################################
# mysite/polls/templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>投票首页</title>
</head>
<body>
<div class="container">
    <h1>投票首页</h1>
</div>
</body>
</html>

4、测试

(djenv) [root@room9pc01 polls]# cd ..
(djenv) [root@room9pc01 mysite]# ls
db.sqlite3  manage.py  mysite  polls
(djenv) [root@room9pc01 mysite]# python manage.py runserver 0:80
浏览器访问http://127.0.0.1/出现404是正常的,因为确实没有定义;访问http://127.0.0.1/polls/才能显示应用的首页。

二、创建投票详情页
1、配置url

# mysite/polls/urls.py
from django.conf.urls import url
from . import views

urlpatterns = [
    #url(正则,函数,name=该url的名字)
    url(r'^$', views.index, name='index'),		//正则匹配首页(http://127.0.0.1/polls/)
    url(r'^(?P<question_id>\d+)/$', views.detail, name='detail'),		正则匹配投票详情页(http://127.0.0.1/polls/num/,注num表示任意整数)
]

2、编写函数

# mysite/polls/views.py
from django.shortcuts import render

# Create your views here.
def index(request):		//首页函数
    return render(request, 'index.html')

def detail(request, question_id):		//投票详情页函数
    return render(request, 'detail.html', {'qid': question_id})

3、创建模板文件index.html

# mysite/polls/templates/detail.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>投票详情</title>
</head>
<body class="container">
    <h1>{{ qid }}号投票详情</h1>		//{{ qid }}变量接收投票详情页函数传递过来的question_id的值
</body>
</html>

4、测试访问

(djenv) [root@room9pc01 mysite]# python manage.py runserver 0:80
浏览器访问http://127.0.0.1/polls/1/

三、创建投票结果页
1、配置url

from django.conf.urls import url
from . import views

urlpatterns = [
    #url(正则,函数,name=该url的名字)
    url(r'^$', views.index, name='index'),		//正则匹配首页(http://127.0.0.1/polls/)
    url(r'^(?P<question_id>\d+)/$', views.detail, name='detail'),		//正则匹配投票详情页(http://127.0.0.1/polls/num/)
    url(r'^(?P<question_id>\d+)/result/$', views.result, name='result'),		//正则匹配投票结果页(http://127.0.0.1/polls/num/result/)
]

2、编写函数

# mysite/polls/views.py
from django.shortcuts import render

# Create your views here.
def index(request):		//首页函数
    return render(request, 'index.html')

def detail(request, question_id):		//投票详情页函数
    return render(request, 'detail.html', {'qid': question_id})

def result(request, question_id):		//投票结果页函数
    return render(request, 'result.html', {'qid': question_id})

四、django模型
模型理念
• 模型指出了数据的唯一、明确的真实来源
• 它包含了正在存储的数据的基本字段和行为
• Django遵循DRY(Do not Repeat Yourself) 原则
• 这个原则的目标是在一个地方定义你的数据模型,并自动从它获得需要的信息

模型说明
• 每个模型都用一个类表示,该类继承自django.db.models.Model
• 每个模型都有一些类变量,在模型中每个类变量都代表了数据库中的一个字段
• 每个字段通过Field类的一个实例表示 —— 例如字符字段CharField和日期字段DateTimeField。 这种方法告诉Django,每个字段中保存着什么类型的数据
• 每个Field 实例的名字就是字段的名字,并且是机器可读的格式
• 在Python代码中将使用到它的值,并且数据库将把它用作表的列名

本项目polls应用模型构思

  • 模型对应数据库。投票应用需要的字段有:问题ID、问题内容、选项、票数。
  • 经过分析,需要两张表:问题表,选项表
    • 在这个简单的投票应用中,我们将创建两个模型:Question和Choice
    • Question对象具有一个question_text(问题)属性和一个publish_date(发布时间)属性
    • Choice有两个字段:选择的内容和选择的得票统计
    • 每个Choice与一个Question关联
    (1)问题表:
ID 内容
1 期待的工资?
2 希望进入的公司?

(2)选项表:

ID 内容 问题ID 票数
1 百度 2 0
5000-8000 1 0
3 华为 2 0
> 10000 1 0

1.1、编写问题模型

# mysite/polls/models.py
from django.db import models

class Question(models.Model):		//定义问题模型的类
    question_text = models.CharField(max_length=200, unique=True, null=False)
    pub_date = models.DateTimeField()

    def __str__(self):
        return '问题: %s' % self.question_text

1.2、生成问题表
迁移Django储存模型
• polls应用建立了新的模型,该模型需要反馈到数据库中
• 通过运行makemigrations告诉Django,已经对模型做了一些更改,并且会将这些更改记录为迁移文件
• 迁移文件位于polls/migrations/目录下

生成数据库
• makemigrations只是生成了迁移文件,并未真正的反馈到数据中
• migrate才是真正生成数据库

(djenv) [root@room9pc01 mysite]# python manage.py makemigrations
(djenv) [root@room9pc01 mysite]# python manage.py migrate
MariaDB [(none)]> use dj1812
MariaDB [dj1812]> show tables;
#会发现多了一个表:polls_question,命名规则为polls_类名(小写)
MariaDB [dj1812]> desc polls_question;
+---------------+--------------+------+-----+---------+----------------+
| Field         | Type         | Null | Key | Default | Extra          |
+---------------+--------------+------+-----+---------+----------------+
| id            | int(11)      | NO   | PRI | NULL    | auto_increment |
| question_text | varchar(200) | NO   | UNI | NULL    |                |
| pub_date      | datetime     | NO   |     | NULL    |                |
+---------------+--------------+------+-----+---------+----------------+

2.1、编写选项模型

#mysite/polls/models.py
from django.db import models

# Create your models here.
class Question(models.Model):		//定义问题模型的类
    question_text = models.CharField(max_length=200, unique=True, null=False)
    pub_date =models.DateTimeField()

    def __str__(self):
        return '问题: %s' % self.question_text

class Choice(models.Model):		//定义选项模型的类
    choice_text = models.CharField(max_length=200, null=False)
    votes = models.IntegerField(default=0)
    question = models.ForeignKey(Question, on_delete=models.CASCADE)

    def __str__(self):
        return '%s => %s' % (self.question, self.choice_text)

2.2、生成选项表

(djenv) [root@room9pc01 mysite]# python manage.py makemigrations
(djenv) [root@room9pc01 mysite]# python manage.py migrate
(djenv) [root@room9pc01 mysite]# mysql -uroot -p123456```
MariaDB [(none)]> use dj1812
MariaDB [dj1812]> show tables;
会发现多了一个表:polls_choice
MariaDB [dj1812]> desc polls_choice;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| choice_text | varchar(200) | NO   |     | NULL    |                |
| votes       | int(11)      | NO   |     | NULL    |                |
| q_id        | int(11)      | NO   | MUL | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+

因为Question和Choice是有主外键约束的,也就是说一个问题可以对应多个选项。但是一个选项只能对应一个问题。在Choice中,q是外键,数据库自动为它加上_id,成为外键字段,如果Choice中用的是question,那么外键字段的名字就是question_id。

将Choice类中的q改为question。完成之后更新数据库:

(djenv) [root@room9pc01 mysite]# python manage.py makemigrations
Did you rename choice.q to choice.question (a ForeignKey)? [y/N] y
(djenv) [root@room9pc01 mysite]# python manage.py migrate
MariaDB [dj1812]> desc polls_choice;
MariaDB [dj1812]> desc polls_choice;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| choice_text | varchar(200) | NO   |     | NULL    |                |
| votes       | int(11)      | NO   |     | NULL    |                |
| question_id | int(11)      | NO   | MUL | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
发现q_id变成了question_id

3、将模型注册到后台管理界面
注册管理后台
• 投票的问题和选项,可以通过后台进行录入、编辑
• 只要把模型注册到后台管理界面即可

# mysite/polls/admin.py
from django.contrib import admin
from .models import Question, Choice

# Register your models here.
admin.site.register(Question)
admin.site.register(Choice)

4、启动开发服务器

(djenv) [root@room9pc01 mysite]# python manage.py runserver 0:80

浏览器访问后台http://127.0.0.1/admin/,添加一些问题和选项,如下图所示:
在这里插入图片描述
接下一篇博客《python:django API、视图、模板和表单使用》

注:续上一篇博客《zabbix监控部署》

一、 自动发现
— 当Zabbix需要监控的设备越来越多,手动添加监控设备越来越有挑战,此时,可以考虑使用自动发现功能
— 需要批量一次性添加一组监控主机,也可以使用自动发现功能

  • 自动发现可以实现:
    — 自动发现、添加主机,自动添加主机到组
    — 自动连接模板到主机,自动创建项目与图形等
  • 自动发现流程:
    — 创建自动发现规则
    — 创建Action动作,说明发现主机后自动执行什么动作
    — 通过动作,执行添加主机,连接模板到主机等操作

1、配置自动发现规则:
配置—>自动发现—>创建发现规则—>规则名称,ip范围(192.168.2.100-254),更新间隔(设为1m)—>新的:检查类型—http,80端口—>添加

2、配置自动发现后触发的动作:
配置—>事件源:自动发现,创建动作—>动作:动作名称,ip范围(192.168.2.100-254),添加—>操作:新的,操作类型—添加主机到群组(webgrp),添加;新的,操作类型—与模板关联(Template App HTTP Service,Template OS Linux),添加,点击最下面的添加,完成动作创建

测试自动发现
开启两台虚拟机192.168.2.101和192.168.2.102,均开启httpd服务,安装并开启zabbix_agentd服务
一段时间后,zabbix监测到以上两台虚拟机的httpd和os系统服务,如下图所示:
在这里插入图片描述
二、主被动监控

  • 主动和被动都是对被监控端主机而言的

  • zabbix默认采用的是被动监控
    — 被动监控:Server向Agent发起连接,发送监控项(key),Agent接受请求,响应监控数据
    — 主动监控:Agent向Server发起连接,Agent请求需要监测的监控项目列表,Server响应Agent发送一个items列表,Agent确认收到监控列表,tcp连接完成,绘画关闭,Agent开始周期性地收集数据

  • 主动被动监控区别:
    — Server不用每次需要数据都连接Agent,Agent会自己收集数据并处理数据,Server仅需要保存数据即可

  • 当监控主机达到一定量级后,zabbix服务器会越来越慢,此时可以ikaolv使用主动监控,释放服务器压力

  • 另外,zabbix也支持分布式监控,也是可以考虑的方案
    1、配置主动监控(web102主机为例演示)

[root@web102 ~]# netstat -ntulp |grep 10050
tcp        0      0 0.0.0.0:10050           0.0.0.0:*               LISTEN      10947/zabbix_agentd 
[root@web102 ~]# 
[root@web102 ~]# killall -p zabbix_agentd		//关闭zabbix_agent服务
[root@web102 ~]# killall -p zabbix_agentd
zabbix_agentd: no process found
[root@web102 ~]# netstat -ntulp |grep 10050
[root@web102 ~]# vim /usr/local/etc/zabbix_agentd.conf		//修改配置文件
93 # Server=127.0.0.1, 192.168.2.55		//主动模式下,注释该行
118 StartAgents=0		//只启动agent进程,没有端口号
134 ServerActive=192.168.2.55		//允许监控本机的监控服务器ip,默认端口10051
145 Hostname=web102		//向Server发送连接时标示本机身份的主机名
183 RefreshActiveChecks=120		//主动连接Server的时间间隔(s)
280 # UnsafeUserParameters=1		//不启用自定义监控
[root@web102 ~]# zabbix_agentd 		//启动进程
[root@web102 ~]# netstat -ntulp |grep 10050		//主动模式下没有端口号
[root@web102 ~]# ps -C zabbix_agentd		//主动模式下,仅有zabbix_agentd进程
  PID TTY          TIME CMD
 9070 ?        00:00:00 zabbix_agentd
 9071 ?        00:00:00 zabbix_agentd
 9072 ?        00:00:00 zabbix_agentd

2、克隆模板,修改监控项模式
配置—>模板—>过滤器:linux,应用,选择Template OS Linux—>全克隆—>模板名称:A_Template OS Linux,添加—>选择克隆出来的A_Template OS Linux模板下的监控项—>选中所有监控项,批量更新—>类型:Zabbix客户端(主动式),更新—>禁用类型中不支持主动式的监控项

3、添加监控主机
配置—>主机—>创建主机—>主机名称:web102,可见的名称:web102,群组:Linux servers,ip地址:0.0.0.0,端口:0—>模板,链接指示器:A_Template OS Linux,依次点击上下的添加按钮

4、查看监测数据
方式1:监测中—>最新数据:过滤web102主机
方式2:监测中—>图形:群组,主机,图形

三、拓扑图与聚合图形
1、拓扑图:绘制拓扑图可以快速了解服务器架构
监测中—>拓扑图,创建拓扑图—>名称:web,添加—>选择web—>编辑拓扑图—>图标:添加—>双击图标,修改图标样式:标签,图标—>ctrl+要连接的两台主机—>链接:添加
拓扑图效果如下:
在这里插入图片描述
2、聚合图形:在一个页面显示多个数据图标,方便了解多组数据
监测中—>聚合图形—>名称:juhetu1,设置列数和行数,添加—>聚合图形后面的构造函数—>更改—>图形:选择,监控主机,监控项—>设置图形宽度和高度,对齐位置—>添加
添加完4张监控图的效果如下:
在这里插入图片描述
四、利用脚本自定义监控命令

监控案例一:利用监控脚本自定义监控nginx状态
1、准备虚拟机(192.168.2.200)环境

[root@web200 ~]# ls
anaconda-ks.cfg       
nginx-1.12.2.tar.gz  
mount_zabbix.sh
initial-setup-ks.cfg  
zabbix-3.4.4.tar.gz
[root@web200 ~]# ./mount_zabbix.sh		//利用脚本安装zabbix
[root@web200 ~]# tar -xf nginx-1.12.2.tar.gz 
[root@web200 ~]# cd nginx-1.12.2/
[root@web200 nginx-1.12.2]# yum -y install zlib-devel		//安装依赖包
[root@web200 nginx-1.12.2]# ./configure --with-http_stub_status_module		//配置nginx,加载状态模块
[root@web200 nginx-1.12.2]# make && make install
[root@web200 nginx-1.12.2]# vim /usr/local/nginx/conf/nginx.conf
...
35     server {
 36         location /status {
 37                 stub_status on;		//启用状态模块
 38         }
 39         listen       80;
 40         server_name  localhost;
 ...
[root@web200 nginx-1.12.2]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@web200 nginx-1.12.2]# /usr/local/nginx/sbin/nginx 
[root@web200 nginx-1.12.2]# netstat -ntulp |grep :80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      14937/nginx: master
[root@web200 nginx-1.12.2]# curl http://192.168.2.200/status		//查看nginx状态
Active connections: 1 		//实时连接数量
server accepts handled requests
 1 1 1 		//三个数字分别表示历史连接总数、处理的连接数量、处理的请求数量
Reading: 0 Writing: 1 Waiting: 0		//依次为读处理数量、写处理数量、等待处理数量

2、编写监控脚本

[root@web200 nginx-1.12.2]# vim /usr/local/bin/nginx_status.sh
#!/bin/bash
case $1 in
active)
    curl -s http://127.0.0.1/status |awk '/Active/{print $NF}';;		//NF为awk内置变量,记录当前处理行的字段个数(列数)
waiting)
    curl -s http://127.0.0.1/status |awk '/Waiting/{print $NF}';;		
accepts)
    curl -s http://127.0.0.1/status |awk 'NR==3{print $2}';;		//NF为awk内置变量,记录当前已读入行的数量(行数)
esac
[root@web200 nginx-1.12.2]# chmod +x /usr/local/bin/nginx_status.sh
[root@web200 nginx-1.12.2]# /usr/local/bin/nginx_status.sh active		//测试脚本执行情况
1
[root@web200 nginx-1.12.2]# /usr/local/bin/nginx_status.sh waiting
0
[root@web200 nginx-1.12.2]# /usr/local/bin/nginx_status.sh accepts
14

3、利用监控脚本自定义监控命令

[root@web200 nginx-1.12.2]# vim /usr/local/etc/zabbix_agentd.conf
93 Server=127.0.0.1, 192.168.2.55		
134 ServerActive=192.168.2.55:10051
145 Hostname=web33
265 Include=/usr/local/etc/zabbix_agentd.conf.d/*.conf
280 UnsafeUserParameters=1
[root@web200 nginx-1.12.2]# vim /usr/local/etc/zabbix_agentd.conf.d/nginx_status.conf		//创建自定义监控命令
UserParameter=nginx.status[*],/usr/local/bin/nginx_status.sh $1		//监控命令nginx.status[*]匹配脚本传递的参数
[root@web200 nginx-1.12.2]# zabbix_agentd 		//启动zabbix_agent服务
[root@web200 nginx-1.12.2]# netstat -ntulp |grep :10050
tcp        0      0 0.0.0.0:10050           0.0.0.0:*               LISTEN      16827/zabbix_agentd
[root@web200 nginx-1.12.2]# zabbix_get -s 127.0.0.1 -p 10050 -k nginx.status[active]		//本机测试自定义监控命令
1
[root@web200 nginx-1.12.2]# zabbix_get -s 127.0.0.1 -p 10050 -k nginx.status[waiting]
0
[root@web200 nginx-1.12.2]# zabbix_get -s 127.0.0.1 -p 10050 -k nginx.status[accepts]
16
[root@zabbix ~]# zabbix_get -s 192.168.2.200 -p 10050 -k nginx.status[accepts]		//监控服务器测试200主机的自定义监控命令
18
[root@zabbix ~]# zabbix_get -s 192.168.2.200 -p 10050 -k nginx.status[active]
1
[root@zabbix ~]# zabbix_get -s 192.168.2.200 -p 10050 -k nginx.status[waiting]
0

4、登陆zabbix监控页面配置自定义监控
配置—>模板—>模板名称和可见的名称:B_nginx,群组:webgrp—>添加—>选择B_nginx模板下的应用集—>创建应用集—>名称:nginx,添加—>选择应用集nginx后面的监控项—>创建监控项(键值绑定自定义监控命令)—>名称:active,键值:nginx.status[active],应用集:nginx,选择底部添加,继续创建另外两个监控项nginx.status[waiting]和nginx.status[accepts]

5、调用自定义监控模板监控web200主机
配置—>主机—>创建主机,主机名称和可见的名称:web200,群组:webgrp,ip地址:192.168.2.200,端口:10050—>模板,链接指示器:B_nginx,依次点击上下的添加按钮

6、查看web200主机监控情况
监测中—>最新数据—>过滤选择web200主机,应用—>获取最新数据

监控案例二:利用脚本自定义监控web200主机TCP网络连接状态
在这里插入图片描述
在这里插入图片描述
1、编写监控脚本

[root@web200 nginx-1.12.2]# vim /usr/local/bin/net_status.sh
#!/bin/bash
case $i in
estab)
    ss -antp | awk '/^ESTAB/{x++} END{print x}';;
close_wait)
    ss -antp | awk '/^CLOSE-WAIT/{x++} END{print x}';;
time_wait)
    ss -antp | awk '/^TIME-WAIT/{x++} END{print x}';;
esac
[root@web200 nginx-1.12.2]# chmod +x /usr/local/bin/net_status.sh
[root@web200 nginx-1.12.2]# /usr/local/bin/net_status.sh estab		//测试监控脚本运行情况
1
[root@web200 nginx-1.12.2]# /usr/local/bin/net_status.sh close_wait

[root@web200 nginx-1.12.2]# /usr/local/bin/net_status.sh time_wait
12

2、自定义监控命令,重启服务

[root@web200 nginx-1.12.2]# vim /usr/local/etc/zabbix_agentd.conf.d/nginx_status.conf		//在案例一自定义监控配置文件基础上添加监控命令
UserParameter=nginx.status[*],/usr/local/bin/nginx_status.sh $1
UserParameter=net.status[*],/usr/local/bin/net_status.sh $1
[root@web200 nginx-1.12.2]# killall -9 zabbix_agentd
[root@web200 nginx-1.12.2]# killall -9 zabbix_agentd
zabbix_agentd: no process found
[root@web200 nginx-1.12.2]# zabbix_agentd
[root@web200 nginx-1.12.2]# netstat -ntulp | grep :10050
tcp        0      0 0.0.0.0:10050           0.0.0.0:*               LISTEN      24029/zabbix_agentd
[root@web200 nginx-1.12.2]# zabbix_get -s 127.0.0.1 -p 10050 -k net.status[close_wait]		//zabbix_agent测试自定义监控命令

[root@web200 nginx-1.12.2]# zabbix_get -s 127.0.0.1 -p 10050 -k net.status[time_wait]
13
[root@web200 nginx-1.12.2]# zabbix_get -s 127.0.0.1 -p 10050 -k net.status[estab]
3
[root@zabbix ~]# zabbix_get -s 192.168.2.200 -p 10050 -k net.status[estab]		//监控服务器测试脚本自定义监控命令
2
[root@zabbix ~]# zabbix_get -s 192.168.2.200 -p 10050 -k net.status[close_wait]		//无数据输出,监控页面该监控项会显示灰色

[root@zabbix ~]# zabbix_get -s 192.168.2.200 -p 10050 -k net.status[time_wait]
14

3、在已有模板基础上创建应用集和监控项
配置—>模板—>B_nginx,应用集—>创建应用集—>名称:net—>监控项—>创建监控项—>名称:net_estab,键值(绑定自定义监控命令):net.status[estab],应用集:net,点击底部添加,继续创建另外两个监控项net_close_wait和net_time_wait

五、常见监控需求

1、mysql

  • 并发连接数
  • 慢查询数量
  • 增、删、改、查数量等

2、NoSQL数据库(数据库状态)
3、php-fpm:并发、队列、进程数量等
4、tomcat服务器状态
5、硬件设备(交换机、路由等,一般通过snmp协议监控)

注:续上一篇博客《python:django部署》
在python shell中运行指令

(djenv) [root@room9pc01 mysite]# python manage.py shell
Python 3.6.7 (default, May 20 2019, 13:24:03) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> 
  • 使用上述命令而不是简单地键入“python”进入python环境
  • 因为manage.py 设置了DJANGO_SETTINGS_MODULE 环境变量,该环境
    变量告诉Django导入mysite/settings.py文件的路径

导入前面编写的模型

>>> from polls.models import Question, Choice

创建问题实例

>>> q1 = Question(question_text='你期待哪家公司给你发offer?', pub_date='2019-05-27 9:00:00')
>>> q1.save()

使用objects管理器
django为每一个ORM类都创建了名为objects的管理器,可以通过这个管理器的方法实现对表的管理。

>>> q2 = Question.objects.create(question_text='从学校毕业后,你希望去哪个城市工作?', pub_date='2019-06-01 12:00:00')

创建选项实例

c1 = Choice(choice_text='腾讯', question=q1)		//由于存在外键关系,django通过Question对象可以反向得到Choice对象集
>>> c1.save()

使用管理器创建选项实例

>>> c2 = Choice.objects.create(choice_text='华为', question=q1)

通过问题实例的管理器创建选项

问题和选项有主外键约束,这是一对多的关系,即一个问题可以有多个选项。每个问题的实例都有一个xxx_set管理器。问题的选项是Choice,那么管理器就是choice_set,如果选项的类名是XuanXiang,那么管理器的名称是xuanxiang_set。

>>> c3 = q1.choice_set.create(choice_text='阿里巴巴')

删除选项

>>> c3.delete()

修改问题

>>> q2.question_text = '从学校毕业后,你打算去哪个城市工作?'
>>> q2.save()

查询所有问题

>>> Question.objects.all()
<QuerySet [<Question: 问题: 从大学毕业后,你期望的新水是多少?>, <Question: 问题: 放假后打算去哪里玩?>, <Question: 问题: 你期待哪家公司给你发offer?>, <Question: 问题: 从学校毕业后,你打算去哪个城市工作?>]>
#########################################################################
Question.objects.all()		//查询所有问题
>>> for q in Question.objects.all():
...    print(q.pub_date)
... 
2019-05-25 17:29:00
2019-06-07 12:00:00
2019-05-27 09:00:00
2019-06-01 12:00:00
>>> Question.objects.order_by('pub_date')
>>> for q in Question.objects.order_by('pub_date'):		//根据发布时间升序排列
...    print(q.pub_date)
... 
2019-05-25 17:29:00
2019-05-27 09:00:00
2019-06-01 12:00:00
2019-06-07 12:00:00
>>> for q in Question.objects.order_by('pub_date'):
...    print(q.pub_date, q.question_text)
... 
2019-05-25 17:29:00 从大学毕业后,你期望的新水是多少?
2019-05-27 09:00:00 你期待哪家公司给你发offer?
2019-06-01 12:00:00 从学校毕业后,你打算去哪个城市工作?
2019-06-07 12:00:00 放假后打算去哪里玩?
>>> for q in Question.objects.order_by('-pub_date'):		//根据发布时间降序排列
...    print(q.pub_date, q.question_text)
... 
2019-06-07 12:00:00 放假后打算去哪里玩?
2019-06-01 12:00:00 从学校毕业后,你打算去哪个城市工作?
2019-05-27 09:00:00 你期待哪家公司给你发offer?
2019-05-25 17:29:00 从大学毕业后,你期望的新水是多少?

获取某一个问题的实例
get必须得到一个实例,否则报错

>>> Question.objects.get(id=1)		//返回1号问题
<Question: 问题: 从大学毕业后,你期望的新水是多少?>
>>> Question.objects.get(id=10)		//如果不存在,则报错
>>> Question.objects.get(id__gt=1)		//id>1的问题,不止一项,报错

获取多个实例
filter可以得到0到多个实例的集合

>>> Question.objects.filter(id=1)		//具有一项的查询集
<QuerySet [<Question: 问题: 从大学毕业后,你期望的新水是多少?>]>
>>> Question.objects.filter(id=10)		//查询集为空
<QuerySet []>
>>> Question.objects.filter(id__gt=1)		//查询集有多项
<QuerySet [<Question: 问题: 放假后打算去哪里玩?>, <Question: 问题: 你期待哪家公司给你发offer?>, <Question: 问题: 从学校毕业后,你打算去哪个城市工作?>]>

查询条件
查询条件采用的形式是“属性__操作符=值”,id=1实际上是id_exact=1的简写

>>> Question.objects.filter(id__exact=1)	//等于1
>>> Question.objects.filter(id__gt=1)		//大于1
>>> Question.objects.filter(id__gte=1)		//大于等于1
>>> Question.objects.filter(id__lt=1)		//小于1
>>> Question.objects.filter(id__lte=1)		//小于等于1

其他属性与数值属性类似,也是使用__

>>> Question.objects.filter(question_text__startswith='从学校')
<QuerySet [<Question: 问题: 从学校毕业后,你打算去哪个城市工作?>]>
>>> Question.objects.filter(pub_date__month=5)
<QuerySet [<Question: 问题: 从大学毕业后,你期望的新水是多少?>, <Question: 问题: 你期待哪家公司给你发offer?>]>

视图基础
• 在Django中,网页的页面和其他内容都是由视图来传递的(视图对WEB请求进行回应)
• 每个视图都是由一个简单的Python函数(或者是基于类的视图的方法)表示的
• Django通过检查请求的URL(准确地说,是URL里域名之后的那部分)来选择使用哪个视图

编写URLCONF
• 将视图和polls.urls模块关联
• 当客户端向你的网站请求一个页面 ( 例如“/polls/34/”)时,Django将加载mysite.urls
Python模块
• 因为它被指向ROOT_URLCONF设置, 它寻找名为urlpatterns 的变量并按顺序匹配其中的正则表达式
•在‘^polls/’找到匹配后,它将取消匹配的文本(“polls/”),并发送剩余的文本 ( “34/” )
到’polls.urls’URLconf进行进一步处理

模板概述
• 前面的例子,HTML是硬编码在python代码中的。这会带来不少问题:
– 任何页面的改动会牵扯到Python代码的改动
– 写后台Python代码与设计HTML是不同的工作,更专业的Web开发应该将两者分开
– 程序员写Python代码同时页面设计者写HTML模板会更高效,而不是一个人等待另一个人编辑同样的文件

• 为了解决硬码的这些问题,可以模板:
– 网站的设计改动会比Python代码改动更频繁,所以如果我们将两者分离开会更方便
– 页面设计者和HTML/CSS程序员不应该编辑Python代码,他们应该与HTML打交道
– 使用Django的模板系统分离设计和Python代码会更干净更易维护

创建模板工作目录
• 默认的设置文件settings.py配置了一个DjangoTemplates后端,其中将APP_DIRS选项设置为True
• DjangoTemplates在 INSTALLED_APPS所包含的每个应用的目录下查找名为"templates"子目录
• 模板应该位于polls/templates/polls/目录下

• 当模板系统遇到变量名里有小数点时会按以下顺序查找:
– 字典查找,如foo[“bar”]
– 属性查找,如foo.bar
– 方法调用,如foo.bar()
– 列表的索引查找,如foo[bar]

• 模板中可以使用的元素有:
– 变量,使用 {{ variable }} 的格式
– 标签/指令,使用 {% … %}的格式
– 字符串:{ } 之外的任何东西,都当做字符串处理

表单说明
• 在detail网页模板中,我们为Question对应的每个Choice都添加了一个单选按钮用于选择。 每个单选按钮的value属性是对应的各个Choice的ID。
• 每个单选按钮的name是“choice”。 这意味着,当选择一个单选按钮并提交表单提交时,它将发送一个POST数据choice=#,其中#为选择的Choice的ID
• 由于我们创建一个POST表单(它具有修改数据的作用),所以我们需要小心跨站点请求伪造
• Django已经拥有一个用来防御它的非常容易使用的系统
•简而言之,所有针对内部URL的POST表单都应该使用{% csrf_token %}模板标签

投票视图说明
• request.POST 是一个类似字典的对象,可以通过关键字的名字获取提交的数据
• request.POST[‘choice’] 以字符串形式返回选择的Choice的ID。request.POST 的值永远是字符串
• 如果在POST数据中没有提供request.POST[‘choice’],choice将引发一个KeyError
##################################################################
完善投票首页

修改视图函数,取出所有问题
pycharm设置:右击外层mysite—>Mark Directory as—>Sources Root

# polls/views.py
from django.shortcuts import render
from polls.models import Question		//导入模块

# Create your views here.
def index(request):
    questions = Question.objects.order_by('-pub_date')
    return render(request, 'index.html', {'questions': questions})		//修改首页返回内容

def detail(request, question_id):
    return render(request, 'detail.html', {'qid': question_id})

def result(request, question_id):
    return render(request, 'result.html', {'qid': question_id})

修改首页模板,显示所有问题

# templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>投票首页</title>
</head>
<body>
<div class="container">
    <h1>投票首页</h1>
    <div>
        <ol>
            {% for question in questions %}
                <li>
                    <a href="">{{ question.question_text }}</a>
                    {{ question.pub_date }}
                </li>
            {% endfor %}
        </ol>
    </div>
</div>
</body>
</html>

说明:{{var}}表示变量,{% %}是模板语法标签,在{}以外的是html语法。
在这里插入图片描述
为首页中的超链接加上具体的url

# templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<div class="container">
    <h1>投票首页</h1>
    <div>
        <ol>
            {% for question in questions %}
                <li>
                    <a href="http://127.0.0.1/polls/{{ question.id }}">{{ question.question_text }}</a>		//添加url
                    {{ question.pub_date }}
                </li>
            {% endfor %}
        </ol>
    </div>
</div>
</body>
</html>

修改首页中超链接的url

# templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<div class="container">
    <h1>投票首页</h1>
    <div>
        <ol>
            {% for question in questions %}
                <li>
                    <a href="{% url 'detail' question_id=question.id %}" target="_blank">
                        {{ question.question_text }}
                    </a>
                    {{ question.pub_date }}
                </li>
            {% endfor %}
        </ol>
    </div>
</div>
</body>
</html>

将网页制作用到的static目录拷贝到polls目录下
[root@room8pc16 mysite]# cp -r …/…/day16/static/ polls/
修改index.html首页,使用boostrap

# templates/index.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">		//适应屏幕
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">		//调用css
</head>
<body>
<div class="container">
    <div id="linux-carousel" class="carousel slide">		//添加轮播图部分
        <ol class="carousel-indicators">
            <li class="active" data-target="#linux-carousel" data-slide-to="0"></li>
            <li data-target="#linux-carousel" data-slide-to="1"></li>
            <li data-target="#linux-carousel" data-slide-to="2"></li>
        </ol>
        <div class="carousel-inner">
            <div class="item active">
                <a href="http://www.sogou.com" target="_blank">
                    <img src="{% static 'imgs/fj1.jpg' %}">		//轮播图1
                </a>
            </div>
            <div class="item">
                <img src="{% static 'imgs/fj2.jpg' %}">		//轮播图2
            </div>
            <div class="item">
                <img src="{%  static 'imgs/fj3.jpg' %}">		//轮播图3
            </div>
        </div>
        <a href="#linux-carousel" data-slide="prev" class="carousel-control left">
            <span class="glyphicon glyphicon-chevron-left"></span>
        </a>
        <a href="#linux-carousel" data-slide="next" class="carousel-control right">
            <span class="glyphicon glyphicon-chevron-right"></span>
        </a>
    </div>				//以上为轮播图部分
    <h1 class="text-center text-warning">投票首页</h1>
    <div class="h4">
        <ol>
            {% for question in questions %}
                <li>
                    <a href="{% url 'detail' question_id=question.id %}" target="_blank">
                        {{ question.question_text }}
                    </a>
                    {{ question.pub_date }}
                </li>
            {% endfor %}
        </ol>
    </div>
    <div class="footer text-center h3">
        <a href="">星空旅游</a>
    </div>
</div>
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<script type="text/javascript">
    $('#linux-carousel').carousel({
        interval : 3000
    });
</script>
</body>
</html>

首页效果图如下:
在这里插入图片描述
使用模板继承

  • 把共性的内容,写到基础模板中
  • 在基础模板添加block占位符
  • 创建html页面,继承模板,将个性内容写到block中

拷贝index.html为base.html
cp index.html base.html
将base.html中的个性内容用block替代

# templates/base.html		//base.html保存共性内容
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %}</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
</head>
<body>
<div class="container">
    <div id="linux-carousel" class="carousel slide">
        <ol class="carousel-indicators">
            <li class="active" data-target="#linux-carousel" data-slide-to="0"></li>
            <li data-target="#linux-carousel" data-slide-to="1"></li>
            <li data-target="#linux-carousel" data-slide-to="2"></li>
        </ol>
        <div class="carousel-inner">
            <div class="item active">
                <a href="http://www.sogou.com" target="_blank">
                    <img src="{% static 'imgs/fj1.jpg' %}">
                </a>
            </div>
            <div class="item">
                <img src="{% static 'imgs/fj2.jpg' %}">
            </div>
            <div class="item">
                <img src="{%  static 'imgs/fj3.jpg' %}">
            </div>
        </div>
        <a href="#linux-carousel" data-slide="prev" class="carousel-control left">
            <span class="glyphicon glyphicon-chevron-left"></span>
        </a>
        <a href="#linux-carousel" data-slide="next" class="carousel-control right">
            <span class="glyphicon glyphicon-chevron-right"></span>
        </a>
    </div>
    <div>
       {% block content %}{% endblock %}		//index.html中个性内容用block代替
    </div>
    <div class="footer text-center h3">
        <a href="">星空旅游</a>
    </div>
</div>
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<script type="text/javascript">
    $('#linux-carousel').carousel({
        interval : 3000
    });
</script>
</body>
</html>

将index.html中的共性删除,将个性内容写到block中

# templates/index.html		//index.html中保存个性内容
{% extends 'base.html' %}		//扩展连接base.html中共性内容
{% load static %}
{% block title %}投票首页{% endblock %}
{% block content %}
    <h1 class="text-center text-warning">投票首页</h1>
    <div class="h4">
        <ol>
            {% for question in questions %}
                <li>
                    <a href="{% url 'detail' question_id=question.id %}" target="_blank">
                        {{ question.question_text }}
                    </a>
                    {{ question.pub_date }}
                </li>
            {% endfor %}
        </ol>
    </div>
{% endblock %}

页面效果和之前一样
在这里插入图片描述
实现投票详情页

修改投票详情页函数

# polls/views.py
from django.shortcuts import render
from polls.models import Question

# Create your views here.
def index(request):
    questions = Question.objects.order_by('-pub_date')
    return render(request, 'index.html', {'questions': questions})

def detail(request, question_id):		//修改投票详情页函数
    question = Question.objects.get(id=question_id)
    return render(request, 'detail.html', {'question': question})

def result(request, question_id):
    return render(request, 'result.html', {'qid': question_id})

修改投票详情页模板文件

# templates/detail.html
{% extends 'base.html' %}
{% load static %}
{% block title %}投票详情{% endblock %}
{% block content %}
    <h1 class="text-center text-warning">{{ question.id }}号问题投票详情</h1>
    <h3>{{ question.question_text }}</h3>
    <form action="" method="post">
        {% for choice in question.choice_set.all %}
            <div class="radio">
                <label>
                    <input type="radio" name="choice_id" value="{{ choice.id }}">
                    {{ choice.choice_text }}
                </label>
            </div>
        {% endfor %}
        <div class="form-group">
            <input class="btn btn-primary" type="submit" value="投 票">
        </div>
    </form>
{% endblock %}

投票详情页效果
在这里插入图片描述
实现投票功能

  • 在投票详情页选择某一项后,投票
  • 投票需要修改数据库。数据库通过调用函数进行修改
  • 访问某一URL,触发函数调用

为投票函数定义URL

# polls/urls.py
from django.conf.urls import url
from . import views

urlpatterns = [
    #url(正则,函数,name=该url的名字)
    url(r'^$', views.index, name='index'),
    url(r'^(?P<question_id>\d+)/$', views.detail, name='detail'),
    url(r'^(?P<question_id>\d+)/result/$', views.result, name='result'),
    url(r'^(?P<question_id>\d+)/vote/$', views.vote, name='vote'),		//投票函数url
]

定义投票函数

# polls/views.py
from django.shortcuts import render
from polls.models import Question
from django.shortcuts import render, redirect

# Create your views here.
def index(request):
    questions = Question.objects.order_by('-pub_date')
    return render(request, 'index.html', {'questions': questions})

def detail(request, question_id):
    question = Question.objects.get(id=question_id)
    return render(request, 'detail.html', {'question': question})

def vote(request, question_id):		//定义投票函数
    # 取出问题
    question = Question.objects.get(id=question_id)
    if request.method == 'POST':
        # 取出用户的选择
        choice_id = request.POST.get('choice_id')
        # 取出选项实例
        choice = question.choice_set.get(id=choice_id)
        choice.votes += 1
        choice.save()

    # redirect相当于打开一个新窗口,访问网址。
    # 如果仍然采用render,将会把request的数据继续向result传递
    return redirect('result', question_id=question_id)

def result(request, question_id):
    return render(request, 'result.html', {'qid': question_id})

修改投票详情页表单的action行为

{% extends 'base.html' %}
{% load static %}
{% block title %}投票详情{% endblock %}
{% block content %}
    <h1 class="text-center text-warning">{{ question.id }}号问题投票详情</h1>
    <h3>{{ question.question_text }}</h3>
    <form action="{% url 'vote' question_id=question.id %}" method="post">		//投票表单行为
    {% csrf_token %}		//防止跨站攻击
        {% for choice in question.choice_set.all %}
            <div class="radio">
                <label>
                    <input type="radio" name="choice_id" value="{{ choice.id }}">
                    {{ choice.choice_text }}
                </label>
            </div>
        {% endfor %}
        <div class="form-group">
            <input class="btn btn-primary" type="submit" value="投 票">
        </div>
    </form>
{% endblock %}

##################################################################
pycharm中项目mysite虚拟环境的目录结构
在这里插入图片描述
##################################################################

模拟客户端投票(从大学毕业后,你期望的新水是多少?选择10000+两次)
在这里插入图片描述
查看后端投票结果
在这里插入图片描述
实现投票结果页

修改函数

from django.shortcuts import render
from polls.models import Question
from django.shortcuts import render, redirect

# Create your views here.
def index(request):
    questions = Question.objects.order_by('-pub_date')
    return render(request, 'index.html', {'questions': questions})

def detail(request, question_id):
    question = Question.objects.get(id=question_id)
    return render(request, 'detail.html', {'question': question})

def vote(request, question_id):
    # 取出问题
    question = Question.objects.get(id=question_id)
    if request.method == 'POST':
        # 取出用户的选择
        choice_id = request.POST.get('choice_id')
        # 取出选项实例
        choice = question.choice_set.get(id=choice_id)
        choice.votes += 1
        choice.save()

    # redirect相当于打开一个新窗口,访问网址。
    # 如果仍然采用render,将会把request的数据继续向result传递
    return redirect('result', question_id=question_id)

def result(request, question_id):		//修改投票结果页函数
    question = Question.objects.get(id=question_id)
    return render(request, 'result.html', {'question': question})

修改投票结果页模板

# templates/result.html
{% extends 'base.html' %}
{% load static %}
{% block title %}投票结果{% endblock %}
{% block content %}
    <h1 class="text-center text-warning">{{ question.id }}号问题投票结果</h1>
    <h3>{{ question.question_text }}</h3>
    <table class="table table-bordered table-striped table-hover h4">
        <tr class="info text-center">
            <td>选项</td>
            <td>票数</td>
        </tr>
        {% for choice in question.choice_set.all %}
            <tr>
                <td>{{ choice.choice_text }}</td>
                <td>{{ choice.votes }}</td>
            </tr>
        {% endfor %}
    </table>
{% endblock %}

再次投票3次
在这里插入图片描述
自动跳到投票结果详情页
在这里插入图片描述
至此一个简单的投票系统就搞定啦!

发布了96 篇原创文章 · 获赞 100 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43395428/article/details/90717831
今日推荐