◆潘春華
(北京林業(yè)大學(xué)信息中心 北京 100083)
基于PowerShell腳本和輕量級(jí)Web服務(wù)的IT系統(tǒng)運(yùn)維監(jiān)控Agent設(shè)計(jì)與實(shí)現(xiàn)
◆潘春華
(北京林業(yè)大學(xué)信息中心 北京 100083)
WindowsPowerShell是一款擁有Shell和腳本能力的可管理工具,可以用來(lái)調(diào)用WMI、COM組件和.NET庫(kù)。本文利用PowerShell腳本語(yǔ)言,結(jié)合Microsoft .NET Framework中的System.Net.HttpListener類(lèi)實(shí)現(xiàn)了一個(gè)基于輕量級(jí)Web服務(wù)的系統(tǒng)運(yùn)維監(jiān)控Agent。該Agent易于使用,具有較好的靈活性和擴(kuò)展性。
PowerShell;輕量級(jí)Web服務(wù)器;Agent;運(yùn)維監(jiān)控
隨著信息化建設(shè)的快速發(fā)展,各類(lèi)應(yīng)用系統(tǒng)以及網(wǎng)絡(luò)系統(tǒng)的規(guī)模不斷加大,各種操作系統(tǒng)、數(shù)據(jù)庫(kù)、應(yīng)用軟件、中間件的數(shù)量和類(lèi)型也不斷增多,IT信息系統(tǒng)越來(lái)越復(fù)雜,很多企業(yè)意識(shí)到IT運(yùn)維監(jiān)控的重要性。目前常用的 IT運(yùn)維監(jiān)控有諸如 Cacti、Nagios、Zabbix等優(yōu)秀的開(kāi)源監(jiān)控軟件,以及以HPOpen View、IBM Tivoli等為代表的國(guó)外收費(fèi)運(yùn)維監(jiān)控軟件,以北塔、廣通信達(dá)、摩卡、網(wǎng)強(qiáng)、天元等為代表的國(guó)內(nèi)收費(fèi)運(yùn)維監(jiān)控軟件。這些IT運(yùn)維監(jiān)控軟件,多采用SNMP、RMON協(xié)議或Agent技術(shù)來(lái)實(shí)現(xiàn)監(jiān)控端與被監(jiān)控端之間的消息通訊,而且多采用 Socket方式[1][2]。雖然這些運(yùn)維監(jiān)控軟件在不同程度上解決了復(fù)雜 IT環(huán)境的監(jiān)控,但是這些產(chǎn)品使用很復(fù)雜,需要一個(gè)專(zhuān)業(yè)團(tuán)隊(duì)的項(xiàng)目實(shí)施才能把產(chǎn)品用起來(lái)。就其被監(jiān)控端的Agent而言,安裝和配置較為繁瑣,無(wú)法擴(kuò)展自定義監(jiān)控運(yùn)維功能。針對(duì)上述問(wèn)題,本文采用PowerShell腳本語(yǔ)言實(shí)現(xiàn)了一個(gè)系統(tǒng)運(yùn)維監(jiān)控Agent。該Agent是一個(gè)超輕量級(jí)WEB服務(wù)器,并能執(zhí)行PowerShell腳本。它具有使用簡(jiǎn)單,功能擴(kuò)展方便,通過(guò)REST API方式直接調(diào)用等優(yōu)點(diǎn)。
PowerShell是一款擁有Shell和腳本能力的可管理工具??梢杂?來(lái) 調(diào) 用 Windows 管 理 規(guī) 范 ( Windows Management Instrumentation,WMI)、COM組件和.NET庫(kù)。PowerShell在一代一代的微軟產(chǎn)品中變得更加突出。在大量的微軟產(chǎn)品中,對(duì)于它的支持是捆綁式的,并有所加強(qiáng)。Windows Server及其Hyper-V、Exchange、Active Directory、SharePoint,甚至SQL Server所有這些都添加了 PowerShell支持和 cmdlet。甚至一些供應(yīng)商如VMWare、Citrix、Cisco和 Quest提供了允許他們的產(chǎn)品被PowerShell訪(fǎng)問(wèn)的方法[3]。通過(guò)安裝SSH.NET組件,Windows用戶(hù)可以使用SSH安全地連接到其它Windows和Linux機(jī)器,并運(yùn)行終端命令。PowerShell與 SSH的結(jié)合將為遠(yuǎn)程管理 Linux和Windows系統(tǒng)提供一個(gè)健壯安全的解決方案[4]。
2.1 Web服務(wù)器工作原理及輕量級(jí)Web服務(wù)器
Web服務(wù)器是一種可以向客戶(hù)端提供服務(wù)的程序,它運(yùn)行在服務(wù)器端,當(dāng)監(jiān)聽(tīng)到客戶(hù)端的服務(wù)請(qǐng)求時(shí),服務(wù)器程序會(huì)響應(yīng)請(qǐng)求并向客戶(hù)端反饋信息。其基本業(yè)務(wù)流程如下:WEB服務(wù)器創(chuàng)建一個(gè)監(jiān)聽(tīng)socket然后開(kāi)始循環(huán)接受新連接??蛻?hù)端初始化一個(gè)TCP連接,在連接成功后,客戶(hù)端發(fā)送HTTP請(qǐng)求到服務(wù)器,服務(wù)器端對(duì)請(qǐng)求進(jìn)行處理,并響應(yīng)一個(gè)顯示給用戶(hù)的HTTP響應(yīng)??蛻?hù)端和服務(wù)器都使用socket建立TCP連接。
圖1 Web服務(wù)器基本業(yè)務(wù)流程圖
目前廣泛被使用的 web服務(wù)器有以 Apache、IIS、Bea WebLogic、Jboss等性能優(yōu)良、安全性高、能實(shí)現(xiàn)虛擬主機(jī)、能與應(yīng)用程序集成等為代表的大型Web服務(wù)器,也有以L(fǎng)ighttpd、Nginx、Nodejs等為代表的小型Web服務(wù)器。這種小型Web服務(wù)器通常被稱(chēng)為輕量級(jí)Web服務(wù)器。
輕量級(jí)Web服務(wù)器與一些大型的Web服務(wù)器相比具有很多優(yōu)勢(shì)。其占用資源低、營(yíng)運(yùn)成本低、復(fù)雜度低、運(yùn)行速度快、部署方便,并在一些特定的環(huán)境得到廣泛的應(yīng)用[5]。如在網(wǎng)絡(luò)路由器中嵌入一個(gè)輕量級(jí)的 Web服務(wù)器并定制相關(guān)配置功能,就可以實(shí)現(xiàn)基于Web頁(yè)面方式的路由器配置。
2.2 .NET對(duì)Web服務(wù)的支持
Microsoft .NET Framework中的System.Net.HttpListener類(lèi)可以實(shí)現(xiàn)輕量級(jí)的 Web服務(wù)。System.Net.HttpListener提供一個(gè)簡(jiǎn)單的、可通過(guò)編程方式控制的 HTTP 協(xié)議偵聽(tīng)器。使用它可以很容易提供HTTP服務(wù),而無(wú)需啟動(dòng)IIS這類(lèi)大型服務(wù)程序[6]。使用HttpListener的方法流程很簡(jiǎn)單,主要分為以下幾步:(1)創(chuàng)建一個(gè)HTTP偵聽(tīng)器對(duì)象并初始化;(2)添加需要監(jiān)聽(tīng)的URI 前綴;(3)開(kāi)始偵聽(tīng)來(lái)自客戶(hù)端的請(qǐng)求;(4)處理客戶(hù)端的 HTTP請(qǐng)求;(5)關(guān)閉HTTP偵聽(tīng)器。
建立HttpListener后,執(zhí)行Start就開(kāi)始處理客戶(hù)端輸入請(qǐng)求。HttpListener中GetContext在沒(méi)有請(qǐng)求準(zhǔn)備好處理的時(shí)候處于被阻塞狀態(tài)。GetContext返回一個(gè)對(duì)象 HttpListenerContext。HttpListenerContext對(duì)象的屬性Request屬性提供了許多關(guān)于客戶(hù)機(jī)的一些請(qǐng)求信息。Response則返回一個(gè) HttpListenerResponse對(duì)象,該對(duì)象可以用來(lái)響應(yīng)客戶(hù)機(jī)的請(qǐng)求。
2.3 Agent設(shè)計(jì)
本文結(jié)合上述Web服務(wù)器的工作流程,用PowerShell調(diào)用System.Net.HttpListener類(lèi),實(shí)現(xiàn)一個(gè)輕量級(jí)Web服務(wù)模式的系統(tǒng)運(yùn)維監(jiān)控Agent。該Agent采用.NET的資源池來(lái)實(shí)現(xiàn)多線(xiàn)程模式的用戶(hù)請(qǐng)求處理。每次用戶(hù)的請(qǐng)求都對(duì)應(yīng)一項(xiàng)系統(tǒng)運(yùn)維監(jiān)控功能。系統(tǒng)運(yùn)維監(jiān)控功能采用PowerShell的自定義函數(shù)編寫(xiě),自定義函數(shù)為REST風(fēng)格的API。所有的自定義函數(shù)在接收用戶(hù)請(qǐng)求之前加載到資源池中。基本思路如下:
初始化相關(guān)參數(shù)(如URL、用戶(hù)身份認(rèn)證方案等),并啟動(dòng)HttpListener;
初始化會(huì)話(huà)狀態(tài),創(chuàng)建資源池及其 runspace個(gè)數(shù)。每個(gè)runspace為一個(gè)線(xiàn)程,用來(lái)處理多個(gè)并發(fā)的客戶(hù)端請(qǐng)求。
創(chuàng)建一個(gè)PowerShell實(shí)例,綁定資源池;
PowerShell實(shí)例調(diào)用相關(guān)方法把用戶(hù)請(qǐng)求處理過(guò)程添加到資源池的runspace中,接收并處理用戶(hù)請(qǐng)求。多個(gè)runspace之間采用異步模式。
Runspace中用戶(hù)處理請(qǐng)求的過(guò)程如下:
(1)用戶(hù)身份認(rèn)證。(2)如果身份認(rèn)證通過(guò),則從用戶(hù)請(qǐng)求的查詢(xún)參數(shù)中獲取 PowerShell命令或自定義函數(shù)名稱(chēng)。(3)PowerShell執(zhí)行用戶(hù)請(qǐng)求的命令或函數(shù)。(4)根據(jù)用戶(hù)需要返回的格式,把命令執(zhí)行結(jié)果(response stream)返回給用戶(hù)。
圖2 Agent結(jié)構(gòu)圖
2.4 系統(tǒng)運(yùn)維監(jiān)控腳本設(shè)計(jì)
PowerShell內(nèi)置了若干命令。這些命令與操作系統(tǒng),特別是與文件系統(tǒng)交互,能夠啟動(dòng)應(yīng)用程序,甚至操縱應(yīng)用程序。另外,PowerShell能夠充分利用.Net類(lèi)型和COM對(duì)象,來(lái)簡(jiǎn)單地與各種系統(tǒng)交互,完成各種復(fù)雜的、自動(dòng)化的操作。因此PowerShell具有強(qiáng)大的系統(tǒng)管理功能,它不僅能管理服務(wù)器操作系統(tǒng)、數(shù)據(jù)庫(kù)系統(tǒng)、中間件、應(yīng)用系統(tǒng)等,而且借助SNMP命令還可以獲取軟硬件系統(tǒng)的運(yùn)行狀態(tài)。
PowerShell可以用單個(gè)的命令來(lái)完成簡(jiǎn)單的系統(tǒng)管理任務(wù),也可以把多個(gè)命令放到腳本塊(Script Block)中或者自定義函數(shù)中,按照一定的邏輯執(zhí)行這些命令來(lái)完成復(fù)雜的系統(tǒng)管理任務(wù)。在用PowerShell進(jìn)行一項(xiàng)系統(tǒng)管理時(shí),通常需要輸入命令所需要的參數(shù),因此本文的系統(tǒng)運(yùn)維監(jiān)控腳本統(tǒng)一采用能攜帶參數(shù)的自定義函數(shù)的形式來(lái)實(shí)現(xiàn)。函數(shù)的返回值即為命令執(zhí)行結(jié)果。
2.5 Agent實(shí)現(xiàn)
本文設(shè)計(jì)的輕量級(jí)Web服務(wù)模式的系統(tǒng)運(yùn)維監(jiān)控Agent采用PowerShell的模塊編程[7]實(shí)現(xiàn)。PowerShell模塊是一個(gè)包(Package),它可以包含Windows PowerShell命令,別名,函數(shù),變量等等。該模塊主要處理過(guò)程如下:
第一步:初始化參數(shù),如runspace個(gè)數(shù),監(jiān)聽(tīng)端口等等;
第 二 步 : 調(diào) 用 System.Net.AuthenticationSchemes、System.Net.HttpListener等方法實(shí)現(xiàn)用戶(hù)身份認(rèn)證方案、啟動(dòng)Http監(jiān)聽(tīng)、初始化會(huì)話(huà)狀態(tài)、初始化資源池等工作;
第三步:定義用戶(hù)請(qǐng)求句柄(Request Handler)腳本塊,實(shí)現(xiàn)請(qǐng)求處理。該腳本塊邏輯如下:若干系統(tǒng)運(yùn)維監(jiān)控自定義函數(shù),對(duì)用戶(hù)請(qǐng)求的URL參數(shù)($request.QueryString.Item)處理,獲取用戶(hù)需要執(zhí)行的命令名稱(chēng)及其參數(shù),調(diào)用$ExecutionContext.InvokeCommand.NewScriptBlock(...)方法裝載用戶(hù)需要執(zhí)行的命令對(duì)應(yīng)的自定義函數(shù),執(zhí)行自定義函數(shù),將自定義函數(shù)執(zhí)行結(jié)果作為響應(yīng)對(duì)象,并對(duì)其處理后返回給用戶(hù);
第四步:構(gòu)造會(huì)話(huà)請(qǐng)求監(jiān)聽(tīng)器,等待用戶(hù)請(qǐng)求。監(jiān)聽(tīng)器調(diào)用HttpListener中GetContext方法阻塞線(xiàn)程,直到請(qǐng)求到達(dá)。同時(shí)監(jiān)聽(tīng)器裝載第三步定義的請(qǐng)求句柄腳本塊;
第五步:創(chuàng)建PowerShell實(shí)例,并根據(jù)資源池的運(yùn)行機(jī)制和異步執(zhí)行機(jī)制動(dòng)態(tài)創(chuàng)建runspace。在runspace中實(shí)現(xiàn)請(qǐng)求處理。實(shí)現(xiàn)方法如下:(1)封裝相關(guān)自定義參數(shù);(2)把(1)中的參數(shù)及第四步定義好的監(jiān)聽(tīng)器載入 runspace中;(3)調(diào)用BeginInvoke方法啟動(dòng)異步調(diào)用;(4)處理完畢后回收runspace。
服務(wù)器端測(cè)試。本次測(cè)試在運(yùn)行Windows Server 2008 R2操作系統(tǒng)的服務(wù)器上測(cè)試。在測(cè)試時(shí),先打開(kāi)系統(tǒng)中自帶的PowerShell工具,然后導(dǎo)入模塊(httpd.psm1),再啟動(dòng)web服務(wù)。步驟如下(并假設(shè)httpd.psm1文件位于D:PSS目錄):
Import-Module .httpd.psm1
httpd Verbose
在PowerShell中顯示為:
圖3 web服務(wù)啟動(dòng)方法及輸出信息
從圖3可以看出,Web服務(wù)已經(jīng)啟動(dòng),正等待客戶(hù)請(qǐng)求。
客戶(hù)端測(cè)試。本次測(cè)試在運(yùn)行Windows 7 PC機(jī)上測(cè)試。在客戶(hù)端的網(wǎng)頁(yè)瀏覽器中打開(kāi)http://202.204.112.82:9998/?cmd=server RunTimeTotal¶m=,則在瀏覽器中顯示:
圖4 瀏覽器訪(fǎng)問(wèn)web服務(wù)的輸出結(jié)果
從圖4可以看出,運(yùn)行本文設(shè)計(jì)的Agent服務(wù)器自上次啟動(dòng)到執(zhí)行上述請(qǐng)求,共運(yùn)行了9天6小時(shí)44分52秒。
在服務(wù)器端PowerShell中顯示為:
圖5 web服務(wù)處理用戶(hù)請(qǐng)求的輸出信息
從圖5可以看出,在Web服務(wù)器端顯示客戶(hù)端請(qǐng)求的命令,客戶(hù)端 IP及端口號(hào),以及命令執(zhí)行結(jié)果,即服務(wù)器共計(jì)運(yùn)行時(shí)間為9天6小時(shí)44分52秒。
本測(cè)試案例采用匿名方式進(jìn)行用戶(hù)身份認(rèn)證,因此在客戶(hù)端瀏覽器中不需要輸入運(yùn)行Agent服務(wù)器的賬號(hào)和密碼就能直接顯示執(zhí)行結(jié)果。本次執(zhí)行的命令是一個(gè)名為ServerRunTimeTotal的自定義函數(shù),其作用是計(jì)算出服務(wù)器運(yùn)行的總時(shí)間。結(jié)構(gòu)如下:
Function SysRunTimeTotal{
Param()
$Server=Get_IPAddr
$Uptime = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $Server
$LastBootUpTime = $Uptime.ConvertToDateTime($Uptime.LastBootUpTime)
$Time = (Get-Date) - $LastBootUpTime
$timeInfo= '{0:00} 天, {1:00} 小時(shí), {2:00} 分鐘, {3:00} 秒' -f $Time.Days, $Time.Hours, $Time.Minutes, $Time.Seconds
return "服務(wù)器運(yùn)行時(shí)間:$timeInfo"
}
本文結(jié)合 PowerShell強(qiáng)大的系統(tǒng)管理功能,以及.Net Framework對(duì)HTTP服務(wù)的支持,設(shè)計(jì)并實(shí)現(xiàn)了一個(gè)基于輕量級(jí)Web服務(wù)的系統(tǒng)運(yùn)維監(jiān)控Agent。該Agent完全基于PowerShell實(shí)現(xiàn)。運(yùn)行時(shí),只需要導(dǎo)入該P(yáng)owerShell模塊文件,并啟動(dòng)Web服務(wù)就行,而不需要安裝其它相關(guān)組件。通過(guò)REST API 接口方式能方便集成到IT運(yùn)維監(jiān)控系統(tǒng)中。由于該Agent基于腳本實(shí)現(xiàn),因此在增加相關(guān)系統(tǒng)監(jiān)控運(yùn)維功能時(shí),只需要在該腳本文件中增加滿(mǎn)足于這些功能的自定義函數(shù)即可。通過(guò)安裝SSH.NET能通過(guò)該Agent管理Llinux服務(wù)器。通過(guò)安裝SNMP程序,能在PowerShell中執(zhí)行snmpget、snmpwalk等命令,從而能用該Agent以SNMP方式獲取其他軟硬件設(shè)備及系統(tǒng)的相關(guān)信息。因此Agent具有較好的靈活性和可擴(kuò)展性。在實(shí)際系統(tǒng)監(jiān)控運(yùn)維中,由于監(jiān)控端請(qǐng)求不會(huì)太頻繁,因此輕量級(jí)Web服務(wù)能滿(mǎn)足監(jiān)控運(yùn)維要求。
[1]周三琦.基于Agent網(wǎng)絡(luò)監(jiān)控系統(tǒng)的研究[J].信息安全與技術(shù),2014.
[2]盧彥兆.信息中心IT運(yùn)維監(jiān)控系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[D].北京:北京航空航天大學(xué),2015.
[3]Donabel Santos,著.許昌永,譯。PowerShell V3--SQL Server 2012數(shù)據(jù)庫(kù)自動(dòng)化運(yùn)維權(quán)威指南[M].人民郵電出版社,2016.
[4]謝麗.微軟宣布 PowerShell將支持 SSH [EB/OL],2015.http://www.infoq.com/cn/news/2015/06/micro-power-s hell-ssh.
[5]馬毅.輕量級(jí) Web 服務(wù)器的實(shí)現(xiàn)與應(yīng)用[D].西安:西北大學(xué),2008.
[6]https://msdn.microsoft.com/zh-cn/magazine/system.net. httplistener.aspx.
[7]Ed Wilson. Windows PowerShell Best Practices[M]. Microsoft Press,2013.