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