內容字號:默認大號超大號

段落設置:段首縮進取消段首縮進

字體設置:切換到微軟雅黑切換到宋體

為什么服務器端系統要對運維友好?如何開發運維友好的服務器端系統

2017-11-15 10:48 出處:韓大 人氣: 評論(0

外網事故,一直以來都是互聯網企業力圖盡量避免的,也是服務器端程序員最重視的問題之一。然而,如果我們統計一下各種外網事故的原因,會發現一個結論:70%的外網事故原因,都是存在于運維領域的,只有30%左右的事故原因,是由于程序本身的BUG導致。

為什么服務器端系統要對運維友好

外網事故,一直以來都是互聯網企業力圖盡量避免的,也是服務器端程序員最重視的問題之一。然而,如果我們統計一下各種外網事故的原因,會發現一個結論:70%的外網事故原因,都是存在于運維領域的,只有30%左右的事故原因,是由于程序本身的BUG導致。這里說的“運維領域的原因”,包括了由于配置錯誤、現網操作失誤、網絡或其他硬件環境變化、硬件故障等等。在流行“運維”“開發”分離的時代,似乎這些都是運維的鍋,但是這鍋背了幾十年,也沒有什么本質上的進步。說明僅僅試圖用“分清責任”這種純管理手段,是解決不了這個技術問題的。舉個例子,當你需要重新部署一個有幾百個進程,分為十幾不同類型的服務的一個系統時候,你可能要小心翼翼的處理幾十上百項配置以及操作命令。這些配置和命令既有大批相似的,也有一些是需要仔細甄別異同的。加上這些配置之中,還有很多互相的關聯,你必須理解的非常清楚,加上這些配置和命令的執行順序也是有嚴格要求的。部署這一切,就像在操作一個有幾百個按鈕的機器面板。最要命的是,如果你搞錯了其中任何一項,都可能讓系統馬上,或者在將來某個不可預料的時間里,造成“外網事故”。這導致了老板就會在半夜三點把你從被窩里扯到電腦前處理這個爛攤子。當然,我說的這個情況并不是每個項目都會發生,但是我們確實是在很多項目中,都不同程度的陷入過類似的陷阱。不知道我們是不是因為都被apache那復雜的httpd.conf所征服過,所以很多程序員都非常熱愛配置文件。“一切都要可配置!”不但成了我們的口號,還成了無數復雜配置項和詭異的工具命令。——但這些東西,在實際的業務運行中,卻切切實實的成為了無數顆定時炸彈。

為什么服務器端系統要對運維友好?如何開發運維友好的服務器端系統

[程序員都愛配置文件]

自動化測試現在已經成為開發的標準流程之一。特別是敏捷開發方式興起之后,最重要的實踐之一就是自動化測試。我們知道,一般我們用來做測試的環境,往往和真實環境不一樣。比如我們做功能測試的時候,運行被測試程序的內存硬盤可能比真正的運行環境要小的多。如果我們的程序因為這些硬件或者其他的諸如IP地址之類的軟件差異,都要配置一番才能運行,那么我們的每次測試,都有可能需要手工的去操作一下,這樣的測試就不能說是“自動化”了。加上手工操作的錯誤,更是可能讓測試結果嚴重錯漏。測試工作除了環境上的差異可能導致運維操作,本身測試也需要多套環境的,比如很多系統都有多個分支在同時開發,又或者有內部功能測試、外部邀請用戶測試、公共測試等多個測試環境。假設我們的軟件,每次部署都要手工進行一大堆的操作,那么面對多個環境,頻繁的發布新版本來做測試,部署的工作肯定是非常繁重的,而這些繁重的工作本來是可以盡量的避免。

為什么服務器端系統要對運維友好?如何開發運維友好的服務器端系統

[美好的CI閉環往往毀于復雜的部署流程]

快速開發一直是現代軟件企業追求的目標。由于需求、市場日新月異,軟件產品和應用系統也被迫著每天在更新功能。說到服務器端軟件,我們往往需要在開發的過程中,配合其他很多程序一起開發調試,最典型的就是和客戶端軟件交互。假設每個參與項目的程序員,都集中連接到一個開發服務器上進行調試,必定產生各種互相影響的事情。而且這種跨機的開發環境,往往也只有一些命令行界面,比不上圖形界面的IDE軟件使用效率高。假設我們開發的程序,特別是服務器端軟件,能直接在開發的工作機上運行和調試,那么除了能響應更快以外,還可以方便的在多個程序同時運行的時候進行調試,這對于常常因為“聯調”而頭疼的工程師來說,是一個非常有效的提升工作效率的措施。但上面說的這些措施,都需要我們的服務器端程序,能很方便簡單的部署到各種環境上。反過來說,有的服務器系統結構比較復雜,要啟動很多進程,配對很多配置文件才能啟動,那么大家一定會懶得部署很多套,而是都擠到一個環境上做開發。

分布式系統在運維友好方面的難點

防止資源泄漏。我們知道,服務器端程序需要長期運行,特別害怕資源系列,比如內存漏洞、文件句柄漏洞、網絡連接相關漏洞等等。所以很多時候,我們愿意在服務器一啟動的時候,就把所有需要的資源,都全部“占用”或“分配”好,然后不管后續來了多少個請求,做什么事情,都完全不需要“分配”,這樣就杜絕了一切的“泄漏”。然而,這個方法也導致程序在運維上的復雜程度大大提高。首先,我們難以明確的硬編碼一個程序所運行的硬件資源,而是設計了諸如配置文件、命令行參數這些東西,來根據運行時的環境,來確定可能使用的硬件資源。比如我們會在配置文件中,設計一個“網絡協議緩沖區大小”的配置項,根據服務器的內存大小來配置。但是,一個程序中的功能可能是很復雜的,要把所有用到的內存、文件等資源都弄成配置項,這個配置文件必定也同樣巨復雜無比。如果我們指望運維人員去理解這些配置文件,那還不如開發人員自己去做運維,因為開發人員有時候自己都沒想清楚這些資源的合理配置應該是怎樣——原因是太過于依賴這種“預先申請”的方式,而習慣于把這些難處理的問題,都延后來解決了。防止資源漏洞,固然是一個重要的問題,但是僅僅是簡單化的把資源申請都變成配置文件,卻同樣帶來另外一個災難。特別要命的是,這種配置文件災難在多進程協作的系統中,會承幾何倍數的增長。這種運維復雜度,在一個系統剛剛上線的時候,似乎都還可以接受,但是隨著系統逐步變得更大、更復雜,運維工作的難度就好像溫水煮青蛙一樣,慢慢的變得完全不可收拾。有些系統隨著3-5年的運營,到后來居然發展到完全沒有人能從零開始部署一套新環境的地步。

為什么服務器端系統要對運維友好?如何開發運維友好的服務器端系統

[打一成語]

快速診斷故障。現在的商業應用系統,往往都不會是一個很簡單的功能體,而是會包含了大量相關或者不相關的功能。而我們最害怕的問題,就是這些共同運行的功能,在同時處理成千上萬的網絡請求的時候,如果因為某一個部分功能代碼的BUG,導致整個系統不可用。所以我們往往更希望建立某種隔離體系,比如把不同功能的代碼運行在不同的進程里。這樣利用操作系統的工具,就能很快的發現那些出問題的代碼。但如果你真的要把一個系統的多個功能分開到不同的進程中運行,首先會碰到的就是進程間通訊的問題。這個問題是現代分布式系統的核心問題之一,無數的開源軟件項目都在試圖解決這個問題。但不管你是使用開源軟件,還是自己寫代碼解決,這都會讓系統的進程變多。特別是我們很喜歡按功能來劃分代碼和進程,那就是說在運維一個系統的時候,我們需要面對大量“不同種類”的進程。而我們越是劃分功能細致,進程的種類就越多,需要操作和運維的進程就復雜。在管理這些進程的時候,除了前面說到的一些性能參數需要配置,還有巨量的進程間關系需要配置。而這些進程間關系,還會隨著業務的變更而變化,對于那些沒有具體接觸開發需求的運維人員來說,簡直是噩夢。也許有些程序員一開始是在通信企業工作,所以很習慣于按進程劃分功能,按通信層次來組織系統,但是隨著業務系統的日益復雜化,這種工作習慣帶來的是大量的麻煩——每周都有可能需要往系統中加入新進程,或者調整某些進程的通信關系。不同的行業需要不同的技術方案,這才是理性的工程師的想法。

為什么服務器端系統要對運維友好?如何開發運維友好的服務器端系統

[小貓喜歡畫地為牢,我們的代碼也喜歡用進程邊界作牢]

負載均衡。現代的服務器端系統,基本上都是分布式系統。也就是由多個服務器、多個進程組合起來提供服務的系統。而為了讓這個系統工作穩定,最常見的措施,就是防止過載。在多個進程中防止某一個過載,就需要負載均衡。而防止所有同類的所有進程過載,則需要過載保護。分布式系統最常見的配置工作之一,就是要配置每類進程啟動多少個,每個進程的過載保護閾值。然而,在一個上千個進程,幾百個服務器的系統中,要準確無誤的填對這些配置,實際上是很難的。特別是這些服務器并不都如提供商說的那樣是性能一致的。假如你需要在集群中加入一些服務器,或者修改(搬遷)某些服務器上的服務,那么更是危險重重,因為稍有不慎,就可能讓原來能工作的系統出現故障。然而,和業務需求在不停變化一樣,運維環境也是在不停變化,比如搬遷IDC就是最常見的“折騰”。我們大可以編寫很多運維管理的工具,來試圖“自動化”這些工作,但是,業務需求也是在不停“折騰”的,而在一些“開發、運維分離”的團隊中,開發人員可不太關心運維工具的開發,因為他們已經被市場和業務人員逼得連續加班,只想功能盡快上線拉倒了。由于需要負載均衡,而產生的大量服務器端軟件的與我內工作量,由于和集群中巨大服務器的數量相關,所以是最直接體現運維和開發服務器端系統困難的地方。

如何開發運維友好的服務器端系統

為了讓服務器端系統能夠良好的運行,我們顯然應該采取一些開發措施,而不單純的依靠所謂“運維”甚至更不靠譜的“管理”手段來降低失誤和故障。

第一個可供參考的思路,就是“建立具備性能彈性的系統”。所以性能彈性,最簡單的是指,我們的服務器進程,可以在各種不同的性能環境下運行,而無需復雜的配置文件或運維操作。這里除了最簡單的自己檢測機器的IP地址、內存大小等自我配置的功能外,更重要的是我們對于資源管理的思路上的改進。由于一個系統要處理的問題可能比較復雜,需要使用到的資源也會很復雜,比如我們需要用內存來緩沖沒收完的網絡包,還需要用內存來存放用戶的會話數據等等。如果我們只是把這樣一塊塊內存都提出來配置,就會有一大堆各種內存容量的配置。然而,我們完全可以通過建立一個業務抽象,來簡化這種資源模型。比如對于一個在線交互的系統,我們可以把資源管理的單位定義為“會話”——每個會話代表了一次“并發”的服務,每個會話要使用多少資源,是我們可以設計的,然后我們注意管理總的“會話”數量,防止資源泄漏。當然這種“會話”在不同的業務系統中,其概念和功能可能都不一樣,幸好我們還可以用面向對象的思想,來用類和對象封裝這些會話及其相關數據。這樣我們在性能規劃的時候,就不用在程序到處翻找使用“資源”的地方機器配置,而僅僅抓住一個關鍵變量就可以了。更進一步的是,我們可以對“會話”這類關鍵指標,采用一種“池”的管理策略,把對這種對象的使用,變成需要“申請/歸還”的機制,這樣我們放棄在一開始就“分配”大量資源的做法,而是根據實際需要來分配資源,而由于“池”的限制,在資源達到上限的時候,拒絕進一步的服務請求,在防止資源漏洞的同時,解決一些過載保護的問題。而且,在某些環境下,我們還可以讓這個“資源池”變得更智能和彈性,比如我們可以在請求壓力接近閾值上限的時候,不是簡單的拒絕服務,而是開始啟動一些擴容或者報警的工作。又或者我們可以定期的查詢被“申請”的資源的處理情況,如果發現占用時間過久,就可以清理掉這些服務請求,這樣就有了一定的自我恢復服務的彈性。如果建立了具備“資源彈性”的系統能力,這樣的進程只需要進行很少的配置就能自我管理和運行。從根本上減輕了運維工作的復雜程度,也降低了環境變化對系統的影響程度。同時抽象良好的功能代碼,在代碼維護和開發上也非常有好處,可謂一舉多得。

為什么服務器端系統要對運維友好?如何開發運維友好的服務器端系統

[子彈封裝了火藥、彈頭、底火,所以告別了通馬桶式發射]

第二個思路,是“在功能容器下運行”。在某個項目實踐中,我見過某一個系統,他的每個進程,都包含了整個系統的全部功能代碼。通過啟動時的命令行參數,可以指定此進程需要提供什么功能。這個系統在運維的便利性上,就遠遠比需要配置、部署各種不同功能發布包的系統來的簡單。而且這個服務器系統,還可以以單進程全功能的形態,用于開發和自動化測試,在開發效率上有著明顯的優勢。而在JSP/Servlet技術的使用中,我們往往也是把不同的WebApp部署到不同的Servlet容器(如Tomcat/Resin等)中運行,而不需要完整的配置各種不同的Servlet容器。現在還有一些系統,把主要的業務功能,都用類似python/JS/Lua這類腳本語言來編寫,系統中的進程部署,只要完成了腳本容器(引擎)后,基本上就是拷貝腳本文件而已。在容器技術的支持下,我們除了可以簡化部署的工作,還可以獲得一些“熱更新”的好處。而基于硬件、訪問量的運維工作,運維人員可以集中注意力管理好“容器”即可。比如GoogleAppEngine,就是一個高度自動化的Web App容器,使用者甚至完全不需要安裝部署任何軟件,直接上傳一個PHP腳本或者Servlet類文件,就可以開始提供服務。在容器下運行服務器系統,還可以利用容器規定的一些通訊規范,做一些自動化運維的事情,比如自動擴容、縮容、容災——容器可以自我發現集群的運行狀態,加入新的運行資源,剔除有故障(比如訪問超時)的運行資源。這也是所謂SOA概念最常見的實現方式。從另外一個角度說,如果有了容器支持,我們在配置服務器進程的時候,是可以簡化對整個集群中各種關系的配置的,因為只要告訴容器,怎樣加入一個目標的集群,其他的事情都可以讓容器去和其他集群成員協商配置。容器除了提出了統一的功能代碼開發環境約束,還規范了運維工作。這對于需要頻繁變化服務內容,以及不斷改變運行環境的項目來說,是非常有價值的。在WEB開發領域,容器的概念已經是深入人心了,所以這一類的系統應用比較廣泛,而運維工作也能比較專業順利的開展,但是在諸如網絡游戲這種沒有“行業標準”的領域,關于功能容器的概念還是沒有被很多人接受,很多人還是在質疑為什么要給自己套上這個“枷鎖”,卻不知道自由從來都是在約束下行走的。

為什么服務器端系統要對運維友好?如何開發運維友好的服務器端系統

[進程需要容器,功能也同樣需要容器,有容器比沒容器好!]

最后,我想說說各種運維工具,不管是Chef,還是各種非通用的運維部署系統,如果僅僅以操作系統提供的能力,就想把所有的系統都統一管理起來,是非常困難的。而如果我們在開發的時候,就充分考慮到系統的運維需求,那么可能只進行了一些簡單的約束,都能讓運維工作有巨大的改進。我想這也是所謂DevOps流行起來的原因吧。

相關欄目

相關文章



分享給小伙伴們:

評論

發表評論愿您的每句評論,都能給大家的生活添色彩,帶來共鳴,帶來思索,帶來快樂。

簽名: 驗證碼: 點擊我更換圖片

評論列表

    © 2002-2017 dngsw.cn 電腦高手網 版權所有

    粵ICP備13005586號-3

    26选5开奖