專案維護中服務會不定時的出現異常,比如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 定時監測任務
新增定時任務,實時監測服務狀態,當服務狀態出現錯誤時,傳送郵件並告知維護人員簡單資訊。至此一個簡單的定時監測服務告警任務就大功告成了。