| win2003 server下的IIS6預設設定下對每個運行在預設應用池中的工作者進程都會經過20多個小時後自動回收該進程,造成儲存在該進程中的session丟失。 因為Session,Application等資料預設儲存在運行該Web應用程式的工作者進程中,如果回收工作者進程,則會造成丟失。 解決辦法: 修改配置,設定為不定時自動回收該工作者進程,比如設定為當超出佔用現有實體記憶體60%後自動回收 該進程。通過使用預設應用程式集區,可以確保多個應用程式間互相隔離,保證由於一個應用程式的崩潰不會影響另外的Web應用程式。還可以使一個獨立的應用程式運行在一個指定的使用者帳號特權之下。 如果使用StateServer方式或者Sql Server資料庫方式來儲存Session,則不受該設定的影響。 可能的原因2: 系統要運行在Server Load Balancer的 Web 場環境中,而系統設定檔web.config中的Session狀態卻設定為InProc(即在本機存放區工作階段狀態),導至在使用者訪問量大時,Session常經逾時的情況。引起這個現象的原因主要是因為使用者通過Server Load BalancerIP來訪問WEB應用系統,某段時候在某台伺服器儲存了Session的工作階段狀態,但在其它的WEB前端伺服器中卻沒有儲存Session的工作階段狀態,而隨著並發量的增大,Server Load Balancer會當作路由隨時訪問閒置伺服器,結果閒置伺服器並沒有之前儲存的Session工作階段狀態。 解決辦法: 1.當您在Server Load Balancer的 Web 場環境中運行 ASP.NET Web 應用程式時,一定要使用 SqlServer 或 StateServer 工作階段狀態模式,在項目中我們基於效能考慮並沒有選擇SqlServer模式來儲存Session狀態,而是選擇一台SessionStateServer 伺服器來使用者的Session工作階段狀態。我們要在系統設定檔web.config中設定如下: 還要添加一項 2. 我們同時還要在SessionStateServer 伺服器中啟動ASP.NET State Service服務,具體設定:控制台>>管理工具>>服務>>ASP.NET State Service,把它設為自動啟動即可。 3. 每台前端WEB服務的Microsoft“Internet 資訊服務”(IIS)設定 要在 Web 場中的不同 Web 服務器間維護工作階段狀態,Microsoft“Internet 資訊服務”(IIS) 設定資料庫中 Web 網站的應用程式路徑(例如,LMW3SVC2)與 Web 場中所有 Web 服務器必須相同。大小寫也必須相同,因為應用程式路徑是區分大小寫。在一台 Web 服務器上,承載 ASP.NET 應用程式的 Web 網站的執行個體 ID 可能是 2(其中應用程式路徑是 LMW3SVC2)。在另一台 Web 服務器上,Web 網站的執行個體 ID 可能是 3(其中應用程式路徑是 LMW3SVC3)。因此,Web 場中的 Web 服務器之間的應用程式路徑是不同的。我們必須使Web 場Web 網站的執行個體 ID 相同即可。你可以在IIS中把某一個WEB配置資訊儲存為一個檔案,其他Web 服務器的IIS配置可以來自這一個檔案。 Session丟失的解決辦法小結 最近在做ASP.NET項目時,測試網站老是取不出Session中的值,在網上搜尋了一下,找到一些解決方案,記錄在這裡。最後使用儲存在StateServer中的辦法解決了問題。 SessionState 的Timeout),其主要原因有三種 一:有些殺病毒軟體會去掃描您的Web.Config檔案,那時Session肯定掉,這是微軟的說法。 二:程式內部裡有讓Session掉失的代碼,及伺服器記憶體不足產生的。 三:程式有架構頁面和跨域情況。 第一種解決辦法是:使殺病毒軟體屏蔽掃描Web.Config檔案(程式運行時自己也不要去編輯它) 第二種是檢查代碼有無Session.Abandon()之類的。 第三種是在Window服務中將ASP.NET State Service 啟動。 下面是協助中的內容: (ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/cpconsessionstate.htm) ASP.NET 提供一個簡單、便於使用的工作階段狀態模型,您可以使用該模型跨多個 Web 請求儲存任意資料和對象。它使用基於字典的、記憶體中的對象引用(這些對象引用存在於 IIS 進程中)緩衝來完成該操作。使用進程內工作階段狀態模式時請考慮下面的限制: 使用進程內工作階段狀態模式時,如果 aspnet_wp.exe 或應用程式定義域重新啟動,則工作階段狀態資料將丟失。這些重新啟動通常會在下面的情況中發生: 在應用程式的 Web.config 檔案的 <processModel> 元素中,設定一個導致新進程在條件被滿足時啟動的屬性,例如 memoryLimit。 修改 Global.asax 或 Web.config 檔案。 更改到 Web 應用程式的 Bin 目錄。 用殺毒軟體掃描並修改 Global.asax 檔案、Web.config 檔案或 Web 應用程式的 Bin 目錄下的檔案。 如果在應用程式的 Web.config 檔案的 <processModel> 元素中啟用了網路園模式,請不要使用進程內工作階段狀態模式。否則將發生隨機資料丟失。 還有這二種: 一:在第一個頁面置了SESSION,然後REDIRECT去第二個頁面。解決方案是在REDIRECT中設定endResponse為FALSE。 二: ASP.NET中使用了ACCESS資料庫,而且資料庫是放在bin目錄中的。解決方案是不要放會更新的檔案在BIN目錄中。 參考:http://www.dotnet247.com/247reference/msgs/58/290316.aspx Asp.net 預設配置下,Session莫名丟失的原因及解決辦法 正常操作情況下Session會無故丟失。因為程式是在不停的被操作,排除Session逾時的可能。另外,Session逾時時間被設定成60分鐘,不會這麼快就逾時的。 這次到CSDN上搜了一下文章,發現好多人在討論這個問題,然後我又google了一下,發現微軟網站上也有類似的內容。 現在我就把原因和解決辦法寫出來。 原因: 由於Asp.net程式是預設配置,所以Web.Config檔案中關於Session的設定如下: <sessionState mode='InProc' stateConnectionString='tcpip=127.0.0.1:42424' sqlConnectionString='data source=127.0.0.1;Trusted_Connection=yes' cookieless='true' timeout='60'/> 我們會發現sessionState標籤中有個屬性mode,它可以有3種取值:InProc、StateServer?SQLServer(大小寫敏感) 。預設情況下是InProc,也就是將Session儲存在進程內(IIS5是aspnet_wp.exe,而IIS6是W3wp.exe),這個進程不穩定,在某些事件發生時,進程會重起,所以造成了儲存在該進程內的Session丟失。 哪些情況下該進程會重起呢?微軟的一篇文章告訴了我們: 1、設定檔中processModel標籤的memoryLimit屬性 2、Global.asax或者Web.config檔案被更改 3、Bin檔案夾中的Web程式(DLL)被修改 4、殺毒軟體掃描了一些.config檔案。 更多的資訊請參考PRB: Session variables are lost intermittently in ASP.NET applications 解決辦法: 前面說到的sessionState標籤中mode屬性可以有三個取值,除了InProc之外,還可以為StateServer、SQLServer。這兩種存Session的方法都是進程外的,所以當aspnet_wp.exe重起的時候,不會影響到Session。 現在請將mode設定為StateServer。StateServer是原生一個服務,可以在系統服務裡看到服務名為ASP.NET State Service的服務,預設情況是不啟動的。當我們設定mode為StateServer之後,請手工將該服務啟動。 這樣,我們就能利用原生StateService來儲存Session了,除非電腦重啟或者StateService崩掉,否則Session是不會丟的(因Session逾時被丟棄是正常的)。 除此之外,我們還可以將Session通過其他電腦的StateService來儲存。具體的修改是這樣的。同樣還在sessionState標籤中,有個stateConnectionString='tcpip=127.0.0.1:42424'屬性,其中有個ip地址,預設為本機(127.0.0.1),你可以將其改成你所知的運行了StateService服務的電腦IP,這樣就可以實現位於不同電腦上的Asp.net程式互連Session了。 如果你有更高的要求,需要在服務期重啟時Session也不丟失,可以考慮將mode設定成SQLServer,同樣需要修改sqlConnectionString屬性。關於使用SQLServer儲存Session的操作,請訪問這裡。 在使用StateServer或者SQLServer儲存Session時,所有需要儲存到Session的對象除了基礎資料型別 (Elementary Data Type)(預設的資料類型,如int、string等)外,都必須序列化。只需將[Serializable]標籤放到要序列化的類前就可以了。 如: 複製 儲存[Serializable]public class MyClass{ //......}具體的序列化相關的知識請參這裡。 至此,問題解決。 |