Python&&分布式监控系统开发实战&&学习笔记

Python&&分布式监控系统开发实战&&学习笔记

  • Python&&分布式监控系统开发实战&&学习笔记
    • 使用python开发类Nagios监控软件
      • 知识点
      • SNMP了解
      • SNMP命令
      • 监控软件开发需求
      • redis的使用
      • redis windows 安装
      • redis订阅和发布功能
      • 配置环境变量
    • 未完待续!!

Python&&分布式监控系统开发实战&&学习笔记

使用python开发类Nagios监控软件

知识点

  1. 使用Redis发布、订阅功能做服务器和客户端的通信通道
  2. 利用面向对象思想开发监控模板
  3. 实现监控项目插件化,允许用户自行开发监控插件

SNMP了解

简单网络管理协议
当机器上启动了SNMP协议时,机器上会出现一个161的UDP端口。该端口可以用于对外监听,通过SNMP的命令行可以发送指令到该端口,以此获取机器的基础状态信息(CPU、内存等)。类UDP的socket。
Python&&分布式监控系统开发实战&&学习笔记_第1张图片
使用环境
使用SNMP适合对中小型(一万以内)的机房机器做基础信息监控。对于更大型的机房机器数量,必须要由agent实现。
agent的优点
4. agent可以帮忙减轻服务器端的压力。agent客户端可以主动的向监控服务器端汇报基础信息数据。
5. agent比SNMP监控的信息种类更多。网络设备(如交换机、路由器)由于不适合安装agent,因此适合使用SNMP获取其机器基础状态信息。

SNMP命令

Python&&分布式监控系统开发实战&&学习笔记_第2张图片
参考资料:
MIB Browser

监控软件开发需求

需求:

  1. 每个客户端需要监控的服务不同
  2. 每个服务的监控间隔不同
  3. 允许模板的形式批量修改监控指标
  4. 不同设备的监控阈值不同
  5. 可自定义的最近n分钟内hit、max、avg、last等指标超过阈值
  6. 报警策略、报警等级的自动升级,通知不同的人
  7. 监控的历史数据的存储和优化
  8. 被动监控,agent一段时间不汇报状态信息时,服务器主动去获取
  9. 代理实现监控服务器集群、分布式监控等。跨机房、区域代理服务器。

top命令中cpu的iowait在%10左右较为正常。%40左右代表忙碌状态。

redis的使用

原生socket的底层是基于select实现的,twisted封装的socket的底层是基于epoll实现的

  1. redis 是key-value类型的数据库
  2. redis是缓存数据库,一般用于存储不需要长久保存数据(如热点事件、热门文章、热门贴等),缓存是存在内存里面的,读取速度极快。
    操作命令:
#进入redis命令行
root@ubuntu:/etc/redis# /usr/bin/redis-cli 
#查看帮助
127.0.0.1:6379> help set

  SET key value [EX seconds] [PX milliseconds] [NX|XX]
  summary: Set the string value of a key
  since: 1.0.0
  group: string
#存储一个简单的键值对
127.0.0.1:6379> set name 'alex'
OK
127.0.0.1:6379> help get

  GET key
  summary: Get the value of a key
  since: 1.0.0
  group: string
#以key获取存储的value值。以相同的key存储,value值会被覆盖
127.0.0.1:6379> get name
"alex"
#设置存储超时时间,超时后存储的数据被自动删除
127.0.0.1:6379> set name 'delete automatically after 10 seconds' EX 10 
OK
127.0.0.1:6379> get name
"delete automatically after 10 seconds"
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> help lpush

  LPUSH key value [value ...]
  summary: Prepend one or multiple values to a list
  since: 1.0.0
  group: list
#存储一个key对应的多个value值
127.0.0.1:6379> lpush nameList 'alex' 'jack' 'dfq'
(integer) 3
127.0.0.1:6379> help lrange

  LRANGE key start stop
  summary: Get a range of elements from a list
  since: 1.0.0
  group: list
#按先进后出规则,以key从redis里面获取最后存储的选定范围内的value值
127.0.0.1:6379> lrange nameList 0 2
1) "dfq"
2) "jack"
3) "alex"
#使用rpush可以将value值插入到之前存储的value值往前
127.0.0.1:6379> rpush nameList 'alexR' 'jackR' 'dfqR'
(integer) 6
127.0.0.1:6379> lrange nameList 0 5
1) "dfq"
2) "jack"
3) "alex"
4) "alexR"
5) "jackR"
6) "dfqR"
127.0.0.1:6379> lrange nameList 0 2
1) "dfq"
2) "jack"
3) "alex"
127.0.0.1:6379> 

redis存储的数据是放置于内存中的,内存中的数据容易丢失。若对数据有长期存储的需求,需要对数据做持久化处理,可以通过改配置文件令其定期自动持久化,也可以执行’save’命令手动对数据实现持久化。
执行save命令可以将redis在内存中的数据全部保存到硬盘。执行save命令时应尽量避开高峰期。

redis windows 安装

参考资料1:
https://www.runoob.com/redis/redis-install.html
参考资料2:
https://www.cnblogs.com/javabg/p/9133206.html
twisted参考资料1:
https://twistedmatrix.com/trac/

redis订阅和发布功能

redisHelper.py

#!/usr/bin/env python
#coding:utf-8
import redis

class RedisHelper:
    def __init__(self):
        self.__conn = redis.Redis(host='127.0.0.1')
        #定义订阅频道,接收87.7兆赫频道内广播的消息(所有客户端均把消息发送到87.7兆赫频道内)
        self.chan_sub = 'fm87.7'
        self.chan_pub = 'fm87.7'
    #以key读redis内相应value
    def get(self,key):
        return self.__conn.get(key)
    #以(key,value)形式存储到redis内
    def set(self,key,value):
        self.__conn.set(key,value)
    #定义发布方法,使用redis对象的publish方法用('fm104.5', msg)形式的参数发布终端消息
    def public(self,msg):
        self.__conn.publish(self.chan_pub, msg)
        return True
    #定义订阅方法,
    def subscribe(self):
        #定义发布订阅对象
        pub = self.__conn.pubsub()
        #订阅'fm87.7'频道
        pub.subscribe(self.chan_sub)
        #等待接收频道内消息
        pub.parse_response()
        #返回接收自频道的消息
        return pub
    
if __name__ == "__main__":
    t = RedisHelper()
    #发布消息
    t.public('test 11')
    #订阅消息
    recvMsg = t.subscribe()
    #recvMsgOne = recvMsg.get_message()
    recvMsgTwo = recvMsg.parse_response()
    #print('非阻塞状态获取消息:',recvMsgOne)
    print('阻塞状态获取消息:',recvMsgTwo)

配置环境变量

#!/usr/bin/env python
#coding:utf-8
import os,sys
#为项目添加环境变量
#当前执行脚本的绝对路径,去掉文件名仅保留目录
base_dir = os.path.dirname(os.path.dirname(__file__))
sys.path.append(base_dir)
print(base_dir)

未完待续!!

你可能感兴趣的:(python)