◆潘春華
(北京林業大學信息中心 北京 100083)
基于PowerShell腳本和輕量級Web服務的IT系統運維監控Agent設計與實現
◆潘春華
(北京林業大學信息中心 北京 100083)
WindowsPowerShell是一款擁有Shell和腳本能力的可管理工具,可以用來調用WMI、COM組件和.NET庫。本文利用PowerShell腳本語言,結合Microsoft .NET Framework中的System.Net.HttpListener類實現了一個基于輕量級Web服務的系統運維監控Agent。該Agent易于使用,具有較好的靈活性和擴展性。
PowerShell;輕量級Web服務器;Agent;運維監控
隨著信息化建設的快速發展,各類應用系統以及網絡系統的規模不斷加大,各種操作系統、數據庫、應用軟件、中間件的數量和類型也不斷增多,IT信息系統越來越復雜,很多企業意識到IT運維監控的重要性。目前常用的 IT運維監控有諸如 Cacti、Nagios、Zabbix等優秀的開源監控軟件,以及以HPOpen View、IBM Tivoli等為代表的國外收費運維監控軟件,以北塔、廣通信達、摩卡、網強、天元等為代表的國內收費運維監控軟件。這些IT運維監控軟件,多采用SNMP、RMON協議或Agent技術來實現監控端與被監控端之間的消息通訊,而且多采用 Socket方式[1][2]。雖然這些運維監控軟件在不同程度上解決了復雜 IT環境的監控,但是這些產品使用很復雜,需要一個專業團隊的項目實施才能把產品用起來。就其被監控端的Agent而言,安裝和配置較為繁瑣,無法擴展自定義監控運維功能。針對上述問題,本文采用PowerShell腳本語言實現了一個系統運維監控Agent。該Agent是一個超輕量級WEB服務器,并能執行PowerShell腳本。它具有使用簡單,功能擴展方便,通過REST API方式直接調用等優點。
PowerShell是一款擁有Shell和腳本能力的可管理工具。可以用 來 調 用 Windows 管 理 規 范 ( Windows Management Instrumentation,WMI)、COM組件和.NET庫。PowerShell在一代一代的微軟產品中變得更加突出。在大量的微軟產品中,對于它的支持是捆綁式的,并有所加強。Windows Server及其Hyper-V、Exchange、Active Directory、SharePoint,甚至SQL Server所有這些都添加了 PowerShell支持和 cmdlet。甚至一些供應商如VMWare、Citrix、Cisco和 Quest提供了允許他們的產品被PowerShell訪問的方法[3]。通過安裝SSH.NET組件,Windows用戶可以使用SSH安全地連接到其它Windows和Linux機器,并運行終端命令。PowerShell與 SSH的結合將為遠程管理 Linux和Windows系統提供一個健壯安全的解決方案[4]。
2.1 Web服務器工作原理及輕量級Web服務器
Web服務器是一種可以向客戶端提供服務的程序,它運行在服務器端,當監聽到客戶端的服務請求時,服務器程序會響應請求并向客戶端反饋信息。其基本業務流程如下:WEB服務器創建一個監聽socket然后開始循環接受新連接。客戶端初始化一個TCP連接,在連接成功后,客戶端發送HTTP請求到服務器,服務器端對請求進行處理,并響應一個顯示給用戶的HTTP響應。客戶端和服務器都使用socket建立TCP連接。

圖1 Web服務器基本業務流程圖
目前廣泛被使用的 web服務器有以 Apache、IIS、Bea WebLogic、Jboss等性能優良、安全性高、能實現虛擬主機、能與應用程序集成等為代表的大型Web服務器,也有以Lighttpd、Nginx、Nodejs等為代表的小型Web服務器。這種小型Web服務器通常被稱為輕量級Web服務器。
輕量級Web服務器與一些大型的Web服務器相比具有很多優勢。其占用資源低、營運成本低、復雜度低、運行速度快、部署方便,并在一些特定的環境得到廣泛的應用[5]。如在網絡路由器中嵌入一個輕量級的 Web服務器并定制相關配置功能,就可以實現基于Web頁面方式的路由器配置。
2.2 .NET對Web服務的支持
Microsoft .NET Framework中的System.Net.HttpListener類可以實現輕量級的 Web服務。System.Net.HttpListener提供一個簡單的、可通過編程方式控制的 HTTP 協議偵聽器。使用它可以很容易提供HTTP服務,而無需啟動IIS這類大型服務程序[6]。使用HttpListener的方法流程很簡單,主要分為以下幾步:(1)創建一個HTTP偵聽器對象并初始化;(2)添加需要監聽的URI 前綴;(3)開始偵聽來自客戶端的請求;(4)處理客戶端的 HTTP請求;(5)關閉HTTP偵聽器。
建立HttpListener后,執行Start就開始處理客戶端輸入請求。HttpListener中GetContext在沒有請求準備好處理的時候處于被阻塞狀態。GetContext返回一個對象 HttpListenerContext。HttpListenerContext對象的屬性Request屬性提供了許多關于客戶機的一些請求信息。Response則返回一個 HttpListenerResponse對象,該對象可以用來響應客戶機的請求。
2.3 Agent設計
本文結合上述Web服務器的工作流程,用PowerShell調用System.Net.HttpListener類,實現一個輕量級Web服務模式的系統運維監控Agent。該Agent采用.NET的資源池來實現多線程模式的用戶請求處理。每次用戶的請求都對應一項系統運維監控功能。系統運維監控功能采用PowerShell的自定義函數編寫,自定義函數為REST風格的API。所有的自定義函數在接收用戶請求之前加載到資源池中。基本思路如下:
初始化相關參數(如URL、用戶身份認證方案等),并啟動HttpListener;
初始化會話狀態,創建資源池及其 runspace個數。每個runspace為一個線程,用來處理多個并發的客戶端請求。
創建一個PowerShell實例,綁定資源池;
PowerShell實例調用相關方法把用戶請求處理過程添加到資源池的runspace中,接收并處理用戶請求。多個runspace之間采用異步模式。
Runspace中用戶處理請求的過程如下:
(1)用戶身份認證。(2)如果身份認證通過,則從用戶請求的查詢參數中獲取 PowerShell命令或自定義函數名稱。(3)PowerShell執行用戶請求的命令或函數。(4)根據用戶需要返回的格式,把命令執行結果(response stream)返回給用戶。

圖2 Agent結構圖
2.4 系統運維監控腳本設計
PowerShell內置了若干命令。這些命令與操作系統,特別是與文件系統交互,能夠啟動應用程序,甚至操縱應用程序。另外,PowerShell能夠充分利用.Net類型和COM對象,來簡單地與各種系統交互,完成各種復雜的、自動化的操作。因此PowerShell具有強大的系統管理功能,它不僅能管理服務器操作系統、數據庫系統、中間件、應用系統等,而且借助SNMP命令還可以獲取軟硬件系統的運行狀態。
PowerShell可以用單個的命令來完成簡單的系統管理任務,也可以把多個命令放到腳本塊(Script Block)中或者自定義函數中,按照一定的邏輯執行這些命令來完成復雜的系統管理任務。在用PowerShell進行一項系統管理時,通常需要輸入命令所需要的參數,因此本文的系統運維監控腳本統一采用能攜帶參數的自定義函數的形式來實現。函數的返回值即為命令執行結果。
2.5 Agent實現
本文設計的輕量級Web服務模式的系統運維監控Agent采用PowerShell的模塊編程[7]實現。PowerShell模塊是一個包(Package),它可以包含Windows PowerShell命令,別名,函數,變量等等。該模塊主要處理過程如下:
第一步:初始化參數,如runspace個數,監聽端口等等;
第 二 步 : 調 用 System.Net.AuthenticationSchemes、System.Net.HttpListener等方法實現用戶身份認證方案、啟動Http監聽、初始化會話狀態、初始化資源池等工作;
第三步:定義用戶請求句柄(Request Handler)腳本塊,實現請求處理。該腳本塊邏輯如下:若干系統運維監控自定義函數,對用戶請求的URL參數($request.QueryString.Item)處理,獲取用戶需要執行的命令名稱及其參數,調用$ExecutionContext.InvokeCommand.NewScriptBlock(...)方法裝載用戶需要執行的命令對應的自定義函數,執行自定義函數,將自定義函數執行結果作為響應對象,并對其處理后返回給用戶;
第四步:構造會話請求監聽器,等待用戶請求。監聽器調用HttpListener中GetContext方法阻塞線程,直到請求到達。同時監聽器裝載第三步定義的請求句柄腳本塊;
第五步:創建PowerShell實例,并根據資源池的運行機制和異步執行機制動態創建runspace。在runspace中實現請求處理。實現方法如下:(1)封裝相關自定義參數;(2)把(1)中的參數及第四步定義好的監聽器載入 runspace中;(3)調用BeginInvoke方法啟動異步調用;(4)處理完畢后回收runspace。
服務器端測試。本次測試在運行Windows Server 2008 R2操作系統的服務器上測試。在測試時,先打開系統中自帶的PowerShell工具,然后導入模塊(httpd.psm1),再啟動web服務。步驟如下(并假設httpd.psm1文件位于D:PSS目錄):
Import-Module .httpd.psm1
httpd Verbose
在PowerShell中顯示為:

圖3 web服務啟動方法及輸出信息
從圖3可以看出,Web服務已經啟動,正等待客戶請求。
客戶端測試。本次測試在運行Windows 7 PC機上測試。在客戶端的網頁瀏覽器中打開http://202.204.112.82:9998/?cmd=server RunTimeTotal¶m=,則在瀏覽器中顯示:

圖4 瀏覽器訪問web服務的輸出結果
從圖4可以看出,運行本文設計的Agent服務器自上次啟動到執行上述請求,共運行了9天6小時44分52秒。
在服務器端PowerShell中顯示為:

圖5 web服務處理用戶請求的輸出信息
從圖5可以看出,在Web服務器端顯示客戶端請求的命令,客戶端 IP及端口號,以及命令執行結果,即服務器共計運行時間為9天6小時44分52秒。
本測試案例采用匿名方式進行用戶身份認證,因此在客戶端瀏覽器中不需要輸入運行Agent服務器的賬號和密碼就能直接顯示執行結果。本次執行的命令是一個名為ServerRunTimeTotal的自定義函數,其作用是計算出服務器運行的總時間。結構如下:
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} 小時, {2:00} 分鐘, {3:00} 秒' -f $Time.Days, $Time.Hours, $Time.Minutes, $Time.Seconds
return "服務器運行時間:$timeInfo"
}
本文結合 PowerShell強大的系統管理功能,以及.Net Framework對HTTP服務的支持,設計并實現了一個基于輕量級Web服務的系統運維監控Agent。該Agent完全基于PowerShell實現。運行時,只需要導入該PowerShell模塊文件,并啟動Web服務就行,而不需要安裝其它相關組件。通過REST API 接口方式能方便集成到IT運維監控系統中。由于該Agent基于腳本實現,因此在增加相關系統監控運維功能時,只需要在該腳本文件中增加滿足于這些功能的自定義函數即可。通過安裝SSH.NET能通過該Agent管理Llinux服務器。通過安裝SNMP程序,能在PowerShell中執行snmpget、snmpwalk等命令,從而能用該Agent以SNMP方式獲取其他軟硬件設備及系統的相關信息。因此Agent具有較好的靈活性和可擴展性。在實際系統監控運維中,由于監控端請求不會太頻繁,因此輕量級Web服務能滿足監控運維要求。
[1]周三琦.基于Agent網絡監控系統的研究[J].信息安全與技術,2014.
[2]盧彥兆.信息中心IT運維監控系統的設計與實現[D].北京:北京航空航天大學,2015.
[3]Donabel Santos,著.許昌永,譯。PowerShell V3--SQL Server 2012數據庫自動化運維權威指南[M].人民郵電出版社,2016.
[4]謝麗.微軟宣布 PowerShell將支持 SSH [EB/OL],2015.http://www.infoq.com/cn/news/2015/06/micro-power-s hell-ssh.
[5]馬毅.輕量級 Web 服務器的實現與應用[D].西安:西北大學,2008.
[6]https://msdn.microsoft.com/zh-cn/magazine/system.net. httplistener.aspx.
[7]Ed Wilson. Windows PowerShell Best Practices[M]. Microsoft Press,2013.