项目维护中服务会不定时的出现异常, 比如 502,404,101 等等, 当工作任务繁重时又不能实时监测, 而 Linux 的运维者, 逃脱不了定时任务的命题, 最常用和快捷简单的是 crontab, 在少量机器的情况下, crontab 效率还是比较高和比较便捷. 但当机器越多, 应用越多的情况下, 继续使用 crontab 进行定时任务的管理配置, 那严重影响工作效率. 但 crontab 执行后结果如何如果不登录服务器一般不能实施感知, 此时我们可以借助 python 的邮件机制进行实时通知也可以定时监测服务发出告警信息以便及时处理.
邮件机制相关知识简介
SMTP (Simple Mail Transfer Protocol) 邮件传送代理 (Mail Transfer Agent,MTA) 程序使用 SMTP 协议来发送电邮到接收者的邮件服务器. SMTP 协议只能用来发送邮件, 不能用来接收邮件. 大多数的邮件发送服务器 (Outgoing Mail Server) 都是使用 SMTP 协议. SMTP 协议的默认 TCP 端口号是 25. SMTP 协议的一个重要特点是它能够接力传送邮件. 它工作在两种情况下: 一是电子邮件从客户机传输到服务器; 二是从某一个服务器传输到另一个服务器.
POP3 (Post Office Protocol) & IMAP (Internet Message Access Protocol) POP 协议和 IMAP 协议是用于邮件接收的最常见的两种协议. 几乎所有的邮件客户端和服务器都支持这两种协议. POP3 协议为用户提供了一种简单, 标准的方式来访问邮箱和获取电邮. 使用 POP3 协议的电邮客户端通常的工作过程是: 连接服务器, 获取所有信息并保存在用户主机, 从服务器删除这些消息然后断开连接. POP3 协议的默认 TCP 端口号是 110. IMAP 协议也提供了方便的邮件下载服务, 让用户能进行离线阅读. 使用 IMAP 协议的电邮客户端通常把信息保留在服务器上直到用户显式删除. 这种特性使得多个客户端可以同时管理一个邮箱. IMAP 协议提供了摘要浏览功能, 可以让用户在阅读完所有的邮件到达时间, 主题, 发件人, 大小等信息后再决定是否下载. IMAP 协议的默认 TCP 端口号是 143. 邮件格式 (RFC 2822) 每封邮件都有两个部分: 邮件头和邮件体, 两者使用一个空行分隔. 邮件头每个字段 (Field) 包括两部分: 字段名和字段值, 两者使用冒号分隔. 有两个字段需要注意: From 和 Sender 字段. From 字段指明的是邮件的作者, Sender 字段指明的是邮件的发送者. 如果 From 字段包含多于一个的作者, 必须指定 Sender 字段; 如果 From 字段只有一个作者并且作者和发送者相同, 那么不应该再使用 Sender 字段, 否则 From 字段和 Sender 字段应该同时使用. 邮件体包含邮件的内容, 它的类型由邮件头的 Content-Type 字段指明. RFC 2822 定义的邮件格式中, 邮件体只是单纯的 ASCII 编码的字符序列. MIME (Multipurpose Internet Mail Extensions) (RFC 1341) MIME 扩展邮件的格式, 用以支持非 ASCII 编码的文本, 非文本附件以及包含多个部分 (multi-part) 的邮件体等.
Python 邮件处理机制
Python smtplib 模块 该模块定义了一个 SMTP 客户端会话对象, 可用于使用 SMTP 或 ESMTP 侦听器守护程序向任何互联网机器发送邮件. 用来创建一个 SMTP 对象, 稍后将演示如何用它来发送电子邮件
- import smtplib
- smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )
这里是上面语法的参数细节
host - 这是运行 SMTP 服务器的主机. 可以指定主机的 IP 地址或类似 yiibai.com 的域名. 这是一个可选参数.
port - 如果提供主机参数, 则需要指定 SMTP 服务器正在侦听的端口. 通常这个端口默认值是: 25.
local_hostname - 如果 SMTP 服务器在本地计算机上运行, 那么可以只指定 localhost 选项.
SMTP 对象有一个 sendmail 的实例方法, 该方法通常用于执行邮件发送的工作. 它需要三个参数
sender - 具有发件人地址的字符串.
receivers - 字符串列表, 每个收件人一个.
message - 作为格式如在各种 RFC 中指定的字符串.
Python email 模块
class email.message.Message getitem,__setitem__实现 obj[key] 形式的访问. Msg.attach(playload): 向当前 Msg 添加 playload. Msg.set_playload(playload): 把整个 Msg 对象的邮件体设成 playload. Msg.add_header(_name, _value, **_params): 添加邮件头字段.
class email.mime.base.MIMEBase(_maintype, _subtype, **_params) 所有 MIME 类的基类, 是 email.message.Message 类的子类.
class email.mime.multipart.MIMEMultipart() 在 3.0 版本的 email 模块 (Python 2.3-Python 2.5) 中, 这个类位于 email.MIMEMultipart.MIMEMultipart. 这个类是 MIMEBase 的直接子类, 用来生成包含多个部分的邮件体的 MIME 对象.
class email.mime.text.MIMEText(_text) 使用字符串_text 来生成 MIME 对象的主体文本.
邮件发送实例
- # -*- coding=utf-8 -*-
- from email.mime.text import MIMEText
- from email.header import Header
- from smtplib import SMTP_SSL
- #163smtp 服务器, 需要设置 POP3 端口并设置授权码
- host_server = 'smtp.163.com'
- #sender_user 为发件人邮箱号
- sender_user = 'xxx@163.com'
- #pwd 为发件人邮箱的授权码
- pwd = 'xxxx'
- # 发件人的邮箱
- sender_user_mail = 'xxx@163.com'
- # 收件人邮箱
- receiver = 'xxx@qq.com'
- # 邮件的正文内容
- mail_content = '你好, 这是使用 python 登录并验证 mail 模块功能发邮件的测试'
- # 邮件标题
- mail_title = 'TEST 邮件'
- #ssl 登录
- def send_mail(mail_content,mail_tile):
- smtp = SMTP_SSL(host_server)
- #set_debuglevel() 是用来调试的. 参数值为 1 表示开启调试模式, 参数值为 0 关闭调试模式
- smtp.ehlo(host_server)
- smtp.login(sender_user, pwd)
- msg = MIMEText(mail_content, "plain", 'utf-8')
- msg["Subject"] = Header(mail_title, 'utf-8')
- msg["From"] = sender_user_mail
- msg["To"] = receiver
- smtp.sendmail(sender_user_mail, receiver, msg.as_string())
- smtp.quit()
检测服务是否正常实例
- def test_server_status():
- apiUrl = 'www.baidu.com'
- try :
- # message = "OK"
- res = requests.get(apiUrl, verify = False)
- return str(res.status_code),str(res.content.decode("utf-8"))
- except Exception as e:
- import re
- m = re.search(r'(\[*[0-9]+\])', str(e), re.M | re.I)
- if m:
- status_code = m.group().split(']')[0]
- return status_code,e
crontab 定时监测任务
添加定时任务, 实时监测服务状态, 当服务状态出现错误时, 发送邮件并告知维护人员简单信息. 至此一个简单的定时监测服务告警任务就大功告成了.
来源: https://juejin.im/post/5b9bce89f265da0ad947bccd