IIS 服務器遷移過程詳解
介紹
客戶端可能在任何時候移動他們的生產服務器。因為有很多原因做這個。一些理由可能是:
- 更改數據中心
- 升級操作系統,例如Windows Server 2003 升到 Windows Server 2008/2012
- 升級電腦硬件,例如32位信息處理機升到帶有多核環境的64位信息處理機
- 公司位置的變化
- 還有很多很多
當任何技術上的人或隊伍開始移動期間,生產服務器,他/她或他的隊伍將可能面對很多技術挑戰。我將在這篇文章中解釋什么樣的挑戰他們可能面對以及怎樣去全部解決。
背景
幾天前我們把生產服務器從一個數據中心移動到另一個數據中心。當時,我們遇到了許多挑戰。在闡述挑戰前,我想描述一下我們的新老服務器的生產服務器環境。
我們的舊生產服務器是32位的Windows 2003 Server、SQL Server 2005和帶有互聯網信息服務(IIS)6.0版本的Reporting Service 2005 版本。我們移動舊生產服務器到一個新環境--64位Windows 2008 Server、SQL Server 2008和帶有IIS 7.5版本的集成模式的Reporting Service (SSRS) 2008。在開始移動之前我們覺得這對我們來說是很簡單的任務。但是在執行的時候我們發現我們遇到了很多挑戰,那個時期真的是我們的非常艱難的時期。因此我決定與大家分享,在將來任何人都可能做相似的工作,那么,他/她或他的隊伍將從中受益。 #p#
遷移期間的維護警報顯示
開始執行前,我們需要備份舊的服務器數據庫,復制代碼文件(二進制和資源文件)、配置文件和其他文件,并且壓縮他們和移動他們到新服務器。 大約需要5/6的時間去做這些事。做這些的時候,我們不想讓客戶端訪問我們的網站/應用去改變任何東西。實際上我們脫機我們的生產網站。但是我們給我們的顧客必須展示正確的信息,即使他們知道服務器正在維護、他們僅僅需要等幾次。我們建立了一個靜止不變的html文件假定它的名字是MaintenanceAlert.htm。現在的問題時什么時候、怎樣去重定向到它?答案是當客戶端訪問我們的網站或任何書簽頁面時,我們重定向到這個頁面。 怎樣去重定向呢?一個解決方案可能是我們從文件后的母板頁代碼重定向。
- Response.Redirect(“MaintenanceAlert.html", false);
但問題是,我們有多份母板頁而且我們需要全部改變和把他部署到生產服務器上,在完成了任務后,我們需要回滾到舊的母板頁上。因此,我們認為這不是個完美的解決方案。我們在尋找一個不讓代碼改變的方法,我們能從網站上找到方法來做些什么呢? 配置(config)文件。如果這樣做了,他對我們將變得非常的容易。在用google搜索后我們發現了一個用的鏈接 Http Redirection
- <httpRedirect enabled="true" destination="Maintenance.htm"
- exactDestination="true" httpResponseStatus="Permanent" />
httpRedirect網站。配置條目將所有請求重定向到維護.htm頁面。
我們有另一個問題,我們得有一個Hello.htm的頁面在我們的網站上。這篇文章將被負載平衡器公司使用。如果有任何請求從這個網頁上來,我們不應該重定向。另一個網頁配置條目將解決這個問題。
- <location path="Hello.htm">
- <system.webServer>
- <httpRedirect enabled="false />
- </system.webServer>
- </location>
這將為Hello.htm網頁重寫http重定向的默認行為。#p#
Web/AppSettings 配置文件問題
我們都知道每一個網站/應用都有個web.config 文件。這個配置文件包含很多配置值,像數據庫連接線、郵件設置、超文本處理機、超文本模塊注冊、應用程序設置鍵值對、第三方組件注冊等等。在現實生活中,這個網站配置文件變得非常大。它的大小在一天天的增大。為了保持web.config文件小和簡單,我們把連接線和應用程序設置值放在兩個不同的文件中。這個文件設置看起來像
- <connectionString configSource="connection.config"/>
- <appSettings configSource="AppSettings.config"/>
- <add key="smtpHost" value="192.168.0.1" />
在另一個地方發現 :
- <add key="mailServer" value="192.168.0.1" />
當我們用新郵件服務ip地址代替時,我們只改變了主機關鍵字,郵件服務關鍵字任然沒有被改變。使用郵件服務關鍵字的組件不能發送郵件。因此,我們找出了所有重復的值并且用新的值替換了。但是,這是非常艱難的任務。我們沒有發現這些關鍵字的正確說明。
另一個可能發生的情況是,我們的系統有10-12個.NET可執行文件在windows任務調度程序中運行。每一個文件有它自己的配置文件。假定10個可執行文件有10個配置文件,而且每一個配置文件包含3個數據庫連接線。 那么我們就需要替換所有這類文件的值。測試期間,我們的質量保證工程師匯報了一些調度程序沒有正確運行的情況。我們發現不知道什么緣故,我們沒有上傳那個配置文件。為了解決這個問題,我們創建了一個根目錄的ConnectionString.config 文件腳本,我們從所有配置文件中找到了那個ConnectionString.config 文件。用這個方法我們僅僅改變了一個文件,而且它將反應所有配置文件并解決那些依然沒有被改變的配置值。
- <connectionString configSource="ConnectionString.config" />
#p#
文件系統安全問題
在測試我們的新網站時,我們發現網站的日志文件沒有寫。我們不能確定問題出在哪兒。調查之后,我們意識到我們需要對日志管理者授予必要的權限。哪個使用者需要這個權限呢?用戶在其下運行的網站應用程序池帳戶(在本例中我們運行網絡服務)必須授予權限。
在我們的任務調度器中,我們創建了不同的必要權限的用戶帳戶來運行調度程序的可執行文件。在開發時期,我們看見許多開發者當面臨權限有關的問題時,他允許每個人對他的個人電腦都有完全控制權限和修理權限。但是實際上這個方法忽視了一個問題。如果我們在我們的生產服務器中這樣做了那么我們就對我們的整個系統打開了一個安全門,而且在未來這有可能發生很多安全問題。我發現了一個對安全問題最好方法的有效鏈接。
通用http處理程序(簡單處理程序工廠集成)刪除動/謂詞丟失的問題
我們對異步請求使用通用的http處理程序而不是從我們的服務器中刪除資源。這個處理程序將不包含“刪除”http動/謂詞。因此使用這個處理程序將不會刪除任何資源文件。但是,如果有些需要刪除,怎么做呢?我們僅僅需向處理程序添加“刪除”動/謂詞命令即可。預先,我們在舊的生產服務器中做了實驗。但在我們的質量工程師匯報他不能在服務器中刪除任何資源之前的很長一段時間我們忘了做這個事情。在調查這個問題之后我們發現我們忘了增加那個刪除動/謂詞了,添加這個詞后我們解決了這個問題。#p#
統一登錄問題
我們開發了一個網站,用于處理用戶身份驗證。我們的網站中有少數依賴該網站進行用戶身份驗證。如果用戶身份驗證通過,身份驗證cookie返回請求的網站。多個站點共享相同的cookie,并允許用戶訪問該cookie認證的多個站點,簡單來說就是登錄一次便可訪問其他多個站點。我們稱之為統一登錄。遷移完成后,我們發現我們的網站無法登錄。只有一個消息傳來-"用戶無效"。首先,我們猜測數據庫連接字符串是錯誤的。經過檢查,我們發現每一個配置都是正確的。我們沒有解決問題。我在本地PC上創建了一個統一登錄的環境,發現它工作的很好。我審查了代碼但依舊沒有發現問題。我們知道進行身份驗證登錄網站時使用的是WCF安全服務。我們將容錯模式"關閉"后在生產環境中獨立運行,發現拋出DiretoryNotExists異常,但在我們當前的代碼庫中,我們沒有發現任何這樣的目錄。我在svn庫中需求幫助。我審查了舊版本的代碼,發現在一個地方,它讀取XML文件,并添加到文件緩存依賴對象。我們搜索這個文件夾發現這個目錄在舊服務器上有,但新服務器上沒有。我們明白了舊的生產代碼沒有被更新。我們從我們的臨時服務器重新部署這些代碼并修復了問題。
32位64位問題
我剛才提到我們的舊服務器是32位的Windows 2003操作系統,而新的服務器是64位的Windows 2008服務器。遷移只是簡單的將我們的代碼從舊服務器復制到新的服務器。網站按預期工作。我們有10-12運行Windows任務調度程序的可執行文件,本來可正常工作,但QA工程師報告一些我們可以按需運行通過ajax請求的調度不能正常工作。調查時,我們發現,雙擊運行它時它沒有運行并且不拋出任何錯誤消息。我們審查了代碼和運行exe文件頁面的Web方法:
- Process.Start("Publish.exe");
我們搜索事件日志、錯誤日志以及網站日志試圖發現導致這個情況的原因,但沒有發現任何有用的資源。經過多次問題我們明白了,我們的網站應用程序池運行在64位上。但我們的臨時服務器是32位。我們使用SVN代碼庫中建立的可執行文件是32位的。當我們將應用程序池從64位換到32位它是工作正常的,我們定位了問題。我們重置回64位應用程序池,并在64位開發PC上重編譯了我們的調度程序,重新部署到新的生產服務器,工作以前正常。#p#
Ajax Pro 在IIS 7.5的注冊問題
Ajax pro 是一個基于.NET的ajax交互組件。如果你想知道更多這個組件的細節,請點擊下面的鏈接進行訪問。
我們使用AjaxPro和Jqery庫進行ajax的實時交互。在先前的服務器上,我們發現工作得很好。但是在我們新的生產環境里,我們發現Ajaxpro不工作了,但是jquery工作良好,我找到2個解決這個問題得比較好的鏈接。
其實在以前的IIS6.0,我們注冊組件在下面的節點。
- <httpHandlers>
- <add verb="POST,GET" path="ajaxpro/*.ashx"
- type="AjaxPro.AjaxHandlerFactory, AjaxPro.2"/>
- </httpHandlers>
但是在iis7,這個配置如果并不工作,他被新的節點所取代。
- <system.webServer>
- <handlers>
- <add name="AjaxPro" verb="*" path="ajaxpro/*.ashx"
- type = "AjaxPro.AjaxhandlerFactory, AjaxPro.2 resourceType="unspecified" />
- </handlers>
- </system.webServer>
System.Transactions.TransactionScope 問題
我們使用System.Transactions.TransactionScope對象執行我們的事務。
但是當我們測試的時候發現這個錯誤。
我們開始收集這個問題,發現下面這個又有的鏈接。
我們的web服務器和數據庫是兩個不同的物理服務器。
我們需要在兩臺服務器都需要開啟事務,然后我們發現他工作正常了。#p#
HTTP還是HTTPS 問題
在我們的開發和登臺服務器(譯注:staging server登臺服務器,交付準備服務器)環境中,我們使用的是http。但在生產服務器環境中,我們使用https來進行安全通信。在測試新服務器的過程中,我們發現有個奇怪的錯誤冒出來。我們看到的錯誤,在crome瀏覽器中看起來是這樣的
在 Internet Explorer這個錯誤像這樣:
我們著手研究這個錯誤,找到了2個非常有用的鏈接。
我們明白了是哪里做錯了。我們使用的是cdn上http形式的jquey路徑
http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js
所以在我們的https網站中,瀏覽器拋出了不安全內容的警告。
我們僅僅只是將CDN定位中http替換為https便修復了這個問題。
https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js
#p#
localhost 與 127.0.0.1 問題
在遷移和配置完新的郵件服務器后,我們發現我們的郵件不能發生。在我們的配置文件中,smtphost間值是使用的localhost。在調查的時候,我們發現了兩個非常有用的鏈接。
我們替換了配置節點中的localhost為127.0.0.1,發現郵件發送正確了。
SSRS 報表文件(.rdl) 未上傳問題
(譯注:SSRs,SQL Server Reporting Services)
從老服務器下載所有rdl文件,在上傳到新服務器的時候,我發現有2個文件沒有上傳。文件拋出異常。異常信息是“ssrs報表私有位置未找到私有程序集custom.dll”。經過研究我們發現有2個rdl文件使用私有程序集custom.dll。SSRS報表從它的私有程序集目錄的位置查找那個dll文件。這個位置是:
- %ProgramFiles%\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies
在將那個dll分發到這個目錄之后,rdl文件便正常上傳并解決了我們的問題。#p#
數據庫未啟用SQL CLR(SQL 公共語言運行庫) 問題
在sql服務器的存儲過程中,我們使用了clr函數。我們還使用了一些第三方sql clr函數。結果在測試新服務器的時,發生了一個異常“你的數據庫未啟用SQL CLR”(SQL CLR not enabled to your database)。在排查這個問題的過程中,我找到了一個非常好的鏈接啟用CLR的過程。
在給我們的生產服務器啟用sql服務器clr選項以后,這個問題就解決了。
SSRS 報表文件夾權限問題
在部署完成所有的報表到新的生產服務器后,報表仍然不顯示。在調查的時候,我們發現了這個有用的鏈接(SSRS Report Folder Permission)。
我們創建了一個系統用戶帳號,并且分配了新的用戶和角色分配給報表文件夾,發現每個報表都可以顯示了。
SSRS 報表默認圖標不顯示
在做報表測試的時候,我們發現一個非常有趣的問題。報表默認導航圖標(First, Previous, Next, Last)不顯示。在那時我們非常迷惑,應為那時sql server默認的圖片。我們不知道怎么來修復這個問題,在那段時間里,我們發現2個非常有用的鏈接。
我們才明白那是IIS6和IIS7相關的問題,我們需要注冊這個處理程序到iis7。
- <handlers>
- <add name ="ReportViewerWebControlHandler" preCondition="integratedMode"
- verb="*" path="Reserved.ReportViewerControl.axd"
- type="Microsoft.Reporting.WebForms.HttpHandler,
- Microsoft.ReportViewer.WebForms, Version=8.0.0.0,
- Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
- </handlers>
在注冊完這個處理程序到iis7之后,我們發現默認的圖片顯示問題得到了解決。#p#
客戶端PC中的DNS刷新問題
我們開始測試新遷移的服務器網站時,舊服務器仍在運行,而且兩臺服務器的dns名字是一樣的。那么怎樣測試新網站呢?一個解決辦法是添加主機條目。但僅僅主機條目并不能解決這個問題。首先我們應該關閉所有瀏覽器。
然后在命令提示窗口執行dnsflush命令。接著我們就可以打開瀏覽器,通過url訪問網站,觀察遠端ip并確保請求被發送到新服務器。
總結
我很難覆蓋到遷移生產環境服務器時所面對的所有場景。但我已經盡力覆蓋了遷移舊服務器到新服務器過程中的盡可能多的場景。我希望在不久的將來,如果有人做類似的工作時,這篇文章可以幫助他。
原文鏈接:http://www.oschina.net/translate/production-server-migration-challenges