1. 需求概述
當我們在Windows Server環境中部署XX系統的實際應用中,往往會遇到一些運維管理的挑戰。為了確保系統的持續穩定運行,特別是在服務程序因各種原因突然關閉的情況下,我們可以借助Python的強大生態系統來構建一個監控與自動重啟的管理工具。
在這個場景中,我使用了psutil
第三方庫,它提供了跨平臺的系統進程和系統利用率信息。結合apscheduler
用于定時任務的管理,以及subprocess
用于啟動和監控服務程序,我打造了一個簡單而有效的監控系統。
首先,我使用psutil
來獲取并篩選出系統中我們所關心的服務程序的進程。通過定時任務,我定期檢查該進程是否在運行,如果不存在,那么就啟動一個新的進程,確保服務不會因意外關閉而中斷。
下面是一個簡單的Python代碼示例,演示了如何使用這些庫來實現監控與自動重啟:
import psutil
import subprocess
from apscheduler.schedulers.blocking import BlockingScheduler# 設置服務程序的命令和路徑
service_command = "py_monitor TestMonitor.py"
service_path = "D:/03study/Test/App"def monitor_service():# 獲取所有進程all_processes = psutil.process_iter(attrs=['pid', 'name'])# 檢查服務程序是否在運行service_running = any(process.info['name'] == "python.exe"for process in all_processes)if not service_running:# 服務程序不存在,啟動新的進程subprocess.Popen(service_command, cwd=service_path, shell=True)print("Service restarted.")# 創建定時任務
scheduler = BlockingScheduler()
scheduler.add_job(monitor_service, 'interval', minutes=5)try:print("Monitoring and auto-restarting service...")scheduler.start()
except KeyboardInterrupt:# 用戶手動終止任務pass
注:此代碼參考自chatgpt,在windows平臺上,有些權限限制,process.cmdline()報錯,去掉。
請注意,這只是一個簡單的示例,實際中你可能需要根據具體情況進行更復雜的異常處理、日志記錄等。此外,確保你的系統允許定時任務的執行,例如在Linux中,可以使用cron等工具。
2. python監控技術
2.1. Python在系統監控中的應用
系統監控是保證計算機系統正常運轉的基礎,也是運維工作的核心之一。Python在系統監控中的應用非常廣泛,例如:
- 監控進程和系統資源:Python可以通過內置的psutil模塊來監控運行中的進程以及系統資源的使用情況,如CPU、內存、磁盤等。
- 監控網絡流量:Python可以通過scapy等第三方庫來監控網絡流量、分析流量內容、抓包等,有時還可以用來檢測網絡攻擊。
- 自定義監控:Python可以通過自定義實現各種監控項,如監控服務、網站、日志等,自定義監控項可以更貼合具體業務需求。例如,可以通過發送ping包來檢測服務器是否能夠正常響應。
- 報警處理:Python可以將監控數據通過郵件、短信等方式發送給管理員,一旦監控數據異常,可以及時觸發報警機制。這些報警機制可以在Python中用一些庫來實現,如smtplib、email、twilio等。
用Python來編寫腳本簡化日常的運維工作是Python的一個重要用途。在Linux下,有許多系統命令可以讓我們時刻監控系統運行的狀態,如ps,top,free等等。要獲取這些系統信息,Python可以通過subprocess模塊調用并獲取結果。但這樣做顯得很麻煩,尤其是要寫很多解析代碼。
在Python中獲取系統信息的另一個好辦法是使用psutil這個第三方 模塊。顧名思義,psutil = process and system utilities,它不僅可以通過一兩行代碼實現系統監控,還可以跨平臺使用,支持Linux/UNIX/OSX/Windows等,是系統管理員和運維小伙伴不可或缺的必備模塊。
2.2. psutil
psutil是一個跨平臺庫,能夠輕松實現獲取系統運行的進程和系統運行的信息(包括CPU、內存、磁盤、網絡等)。它主要用來做系統監控,性能分析,進程管理。它實現了同等命令行工具提供的功能,如ps、top、lsof、netstat、ifconfig、who、df、kill、free、nice、ionice、iostat、iotop、uptime、pidof、tty、taskset、pmap等。目前支持32位和64位的Linux、Windows、OS X、FreeBSD和Sun Solaris等操作系統.
2.3. 任務調度與啟動服務程序
2.3.1 APScheduler
APScheduler是一個用于任務調度和定時任務管理的Python庫。它提供了一個簡單而靈活的方式來定義、調度和執行任務。
2.3.2. subprocess 模塊
subprocess 模塊允許我們啟動一個新進程,并連接到它們的輸入/輸出/錯誤管道,從而獲取返回值。
subprocess 模塊首先推薦使用的是它的 run 方法,更高級的用法可以直接使用 Popen 接口。
run 方法語法格式如下:
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)
- args:表示要執行的命令。必須是一個字符串,字符串參數列表。
- stdin、stdout 和 stderr:子進程的標準輸入、輸出和錯誤。
- timeout:設置命令超時時間。如果命令執行時間超時,子進程將被殺死,并彈出 TimeoutExpired 異常。
- check:如果該參數設置為 True,并且進程退出狀態碼不是 0,則彈 出 CalledProcessError 異常。
- encoding: 如果指定了該參數,則 stdin、stdout 和 stderr 可以接收字符串數據,并以該編碼方式編碼。否則只接收 bytes 類型的數據。
- shell:如果該參數為 True,將通過操作系統的 shell 執行指定的命令。
- returncode: 執行完子進程狀態,通常返回狀態為0則表明它已經運行完畢,若值為負值 “-N”,表明子進程被終。
3. 實踐過程
3.1. psutil庫的安裝
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple psutil
3.2. 常用方法
3.2.1. 獲取系統信息示例
# coding:utf-8
import psutil
import datetime
import timenow_time = time.strftime('%Y-%m-%d-%H:%M:%S', time.localtime(time.time()))
print('當前時間', now_time)
# 獲取系統啟動時間
print("系統啟動時間: %s" % datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S"))print('----------------------------系統CPU信息---------------------------------------')
# 查看cpu物理個數的信息
print("物理CPU個數: %s" % psutil.cpu_count(logical=False))
# 查看cpu邏輯個數的信息
print("邏輯CPU個數: %s" % psutil.cpu_count(logical=True))
# cpu的使用率
cpu = (str(psutil.cpu_percent(1))) + '%'
print('當前1s內系統cup使用率: %s' % cpu)print('----------------------------系統內存信息---------------------------------------')
# 查看內存信息
total = str(round(psutil.virtual_memory().total / (1024.0 * 1024.0 * 1024.0), 2))
free = str(round(psutil.virtual_memory().free / (1024.0 * 1024.0 * 1024.0), 2))
used = str(round(psutil.virtual_memory().used / (1024.0 * 1024.0 * 1024.0), 2))
memory = int(psutil.virtual_memory().total - psutil.virtual_memory().free) / float(psutil.virtual_memory().total)
print("物理總內存: %s G" % total)
print("已使用物理內存: %s G" % used)
print("剩余物理內存: %s G" % free)
print("物理內存使用率: %s %%" % int(memory * 100))print('----------------------------系統用戶信息---------------------------------------')
# 獲取系統用戶
users_count = len(psutil.users())
users_list = ", ".join([u.name for u in psutil.users()])
print("當前有 %s 個用戶,分別是 %s" % (users_count, users_list))print('----------------------------系統網卡信息---------------------------------------')
# 獲取網卡信息,可以得到得到網卡屬性,連接數,當前數據等信息
net = psutil.net_io_counters()
bytes_sent = '{0:.2f} Mb'.format(net.bytes_recv / 1024 / 1024)
bytes_recv = '{0:.2f} Mb'.format(net.bytes_sent / 1024 / 1024)
print("網卡接收數據 %s 網卡發送數據 %s" % (bytes_recv, bytes_sent))print('-----------------------------系統磁盤信息---------------------------------------')
# 獲取磁盤數據信息
io = psutil.disk_partitions()
print('系統當前所有的磁盤信息:{}'.format(io))
for i in io:try:o = psutil.disk_usage(i.device)print('磁盤名:{}'.format(i.device), end='\t')print("總容量:" + str(int(o.total / (1024.0 * 1024.0 * 1024.0))) + "G", end='\t')print("已用容量:" + str(int(o.used / (1024.0 * 1024.0 * 1024.0))) + "G", end='\t')print("可用容量:" + str(int(o.free / (1024.0 * 1024.0 * 1024.0))) + "G")except PermissionError:continueprint('-----------------------------系統進程信息-------------------------------------')
# 查看系統全部進程
for pid in psutil.pids():p = psutil.Process(pid)print("進程名 %-20s 內存利用率 %-18s 進程狀態 %-10s 創建時間 %-10s " % (p.name(), p.memory_percent(), p.status(), p.create_time()))
輸出結果截取片段:
3.2.2. 獲取網絡信息
獲取主機名與IP地址
import socket
hostname = socket.gethostname()
print(hostname)
print(socket.gethostbyname(hostname))
3.3. 應用實踐
import psutil
import time
import subprocessimport pytz
from apscheduler.schedulers.blocking import BlockingScheduler
from loguru import logger# 按進程名稱查詢進行
def find_procs_by_name(name):#"Return a list of processes matching 'name'."ls = []for p in psutil.process_iter(['name']):if p.info['name'] == name:ls.append(p)return ls# 監控進程列表
def monitorprocss():processname = [ 'pvforecast_py.exe','pvweather24_py.exe']cmdbat = ['D:\Python\PVMicrogrid\PVSystem\PVForecastAPScheduler.bat','D:\Python\PVMicrogrid\PVSystem\PVAPScheduler.bat']processe_command = [('start ' + processname[0] + ' PVForecastAPScheduler.py','D:\Python\PVMicrogrid\PVSystem' ),('start ' + processname[1] + ' PVAPScheduler.py','D:\Python\PVMicrogrid\PVSystem'),('start ' + processname[2] + ' PVTrainAPScheduler.py','D:\Python\PVMicrogrid\PVSystem')]for i in range(len(processname)):ls = find_procs_by_name(processname[i])if len(ls)>0:p = ls[0]# 獲取進程創建時間createtime = time.strftime('%Y-%m-%d %X', time.localtime(p.create_time())) #print('進程創建時間:', createtime) if p.is_running():# 獲取該進程的內存利用率rate = p.memory_percent() logger.info(processname[i] + ',該進程的內存利用率:' + str(round(rate,2)))else:# 殺掉進程p.terminate()logger.info(processname[i] + ',進程創建時間:' + createtime) else:# 重新啟動進行# 運行批處理文件,并獲取返回值#result = subprocess.run(cmdbat[i], shell=True)print('啟動服務程序:', processe_command[i][0])subprocess.Popen(processe_command[i][0], cwd=processe_command[i][1], shell=True)if __name__ == '__main__':logger.add("MonitorProcess_{time}.log")print('監控程序開始運行!')#monitorprocss()scheduler = BlockingScheduler(timezone=pytz.timezone("Asia/Shanghai") )#scheduler.add_job(monitorprocss, 'cron', minute = '00,10,20,30,40,50', second='00', misfire_grace_time=60, id='job1')scheduler.add_job(monitorprocss, 'interval', minutes = 1, id='job1')try:scheduler.start()except (KeyboardInterrupt, SystemExit):pass
4. 總結
使用python開發系統監控工具,能快速實現個性化需求,短小而且精悍。其中,服務程序自啟動功能,可以替代“Windows環境中Python應用服務自啟動及其監控解決方法“所描述多個啟動批處理文件,直接使用此一個批處理文件”MonitorProcess.bat“,可以完全勝任。
@echo off
D:
cd D:\Python\PVMicrogrid\utils
start python Monitorprocess.py
部署代碼buildw.bat修改為:
chcp 65001copy D:\Python\PVMicrogrid\MonitorProcess.bat "%userprofile%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\MonitorProcess.bat"
注意:需要把…\Startup\MonitorProcess.bat文件加入安全防護白名單中。
通過這樣的監控與自動重啟工具,我們可以更好地保障應用服務系統的穩定性,及時應對各種潛在問題,確保服務始終處于可用狀態。
參考:
肖永威. Windows環境中Python應用服務自啟動及其監控解決方法. CSDN博客. 2023.11
習久性成. python第三方庫psutil(process and system utilities)庫詳解:獲取系統運行的進程和系統利用率(包括CPU、內存、磁盤、網絡等)信息