1. 程式人生 > >IIS6,SESSION失效的解決

IIS6,SESSION失效的解決

ASP(Active Server Pages)技術的Session物件用於儲存使用者在對話期間的私有資訊。當前使用者的Session物件中定義的變數和物件能在頁面之間共享,但是不能為應用中其他使用者所訪問,因此在用ASP開發網路應用程式時,可以利用Session物件儲存和跟蹤使用者的狀態資訊。
Session物件有一個十分重要的屬性:Timeout,它用於設定在會話資源被釋放前,會話物件所能保持非活動狀態的時間(預設值為20分鐘)。當Timeout屬性設定的時間值耗盡後,會話資源將被釋放。通過Timeout屬性破壞Session物件,避免了Session物件在伺服器中無限制地產生,保護了伺服器資源。

同理,ASP.NET中的Session繼承了以上功能。那麼這裡簡單談談Session的Timeout的一些設定(即Session的有效期)。 最簡單的設定方式延長Session有效期。
1、設定網站的應用程式配置 2、設定ASP.NET中的配置,修改webconfig檔案。(也可以通過程式碼新增) 3、Session儲存的位置絕對不在客戶端。Session儲存方式有三種,可在web.config中設定。
InProc模式,這種模式下Session儲存在ASP.NET的程序內,是一個內部容器,在同一個應用程式目錄是共享的,但是如果這個程序被Web伺服器回收,則Session就會丟失,所以這種模式很不穩定。
StateServer模式,這種模式下Session被儲存在一個Windows Service的程序內,Windows Service的程序比ASP.NET的程序穩定得多,只要開啟這個服務的電腦不當機,一般來說都是比較穩定的。
SQL Server模式,這種模式就更進一步,將Session儲存到了資料庫中,通過犧牲效率換取穩定。 也可通過ASP.NET配置設定

4、儲存的型別和大小?
一般來說,InProc模式下,Session對儲存的物件沒有任何限制。而在StateServer和SQL Server模式中,由於Session需要跨程序保持,所以要求所儲存物件的型別必須是可序列化的。雖然Session對所儲存的資料大小沒有什麼限制,但不建議在Session中儲存太多的東西。

5、生命週期是怎麼樣的?
正常情況下Session在新的客戶端第一次訪問頁面時建立,在超過超時時間沒有任何頁面訪問後銷燬。

6、常見的訪問方法
一般來說Session這種公用容器需要為期專門撰寫訪問類,而不應直接訪問。
一個簡單的訪問類可能看起來是這樣的:

public MyContext
{
public static MyContext Current
{
    get { return HttpContext.Current.Session["hnop"] as MyContext; }
    set { HttpContext.Current.Session["hnop"] = value; }
}
}


7、比較
Session的特點很突出,就是他與客戶端有關,一般來說只要客戶端不關閉瀏覽器,那麼他訪問的所有的頁面所獲得的都是同一個Session容器。我們可以往Session中放入使用者相關的資訊,如登陸資訊。但要注意的是,Session是一個公共容器,所以他裡面的資訊可以被任何執行在伺服器上的程式碼所修改。

===========================================================================================================

ASP.Net中的Session如果使用者關閉了CookieSession的值一樣也可以被儲存。
config.web檔案進行一些配製,因為在其中找到關於Session
的設定文字,如:
<
sessionstate cookieless="false" />cookieless="false" 改成cookieless="true" ,那麼以後Session就不儲存在cookies中了,而在儲存在URL中。

Session還能在另外一臺主機上保持:把localhost改成您要的主機
<
sessionstate inproc="false" server="localhost" port="42424" />

===========================================================================================================

Application狀態為應用程式提供了一個全域性的狀態。所有客戶都可以使用該狀態。從設計的角度來說,我們通常用Application來儲存一些標準的資料。同時,我們在使用它時要注意避免效能的降低,儲存的資料儘可能提供給客戶只讀的功能。

我們可以使用HttpApplication類的Application屬性來訪問Application狀態,它返回一個HttpApplicationState類的例項。這個類是一個物件集合,可以儲存任何型別的資料,並以鍵/值對的形式儲存。一旦資料被儲存到狀態後,就不會刪除,除非應用程式重新啟動或者被終止或回收。

我們可以在Global.asax的Application_Start函式中儲存資料: void Application_Start(object src, EventArgs e) { int exp = 0; // population of dataset from ADO.NET query not shown // Cache DataSet reference Application["Experiment"] = exp; }

現在你可以在任意頁面下使用它:

private void Page_Load(object src, EventArgs e) { int expr = Int32.Parse((Application["Experiment"])); }

由於Application狀態對於所有客戶都是共享的,如果客戶只是讀取該資料,則沒有什麼問題,一旦要進行寫操作,就不能保證執行緒的安全以及出現同步爭用的問題。我們可以使用HttpApplicationStateLock類,它派生於ReadWriteObjectLock類,它提供了讀/寫鎖的兩種屬性。在ASP.Net下,隱式地呼叫了AcquireWrite()和AcquireRead()方法以保證避免上面的問題。當然,我們也可以顯示地使用Lock()和Unlock():

private void Page_Load(object sender, System.EventArgs e) { Application.Lock(); int expr = Int32.Parse((Application["Experiment"])); if (expr>=something) { //do something } Else { //do something else } Application.UnLock(); //Some other thing goes here }

session,cookie,view狀態都是用來儲存客戶端資訊的。它們之間又有什麼區別呢?

Session狀態是在客戶登入的時候建立的,它儲存了客戶特定的資訊,並以Session ID來標識。當一個新客戶訪問應用程式時,先生成一個新的Session ID(或是Session Key),併為同一個客戶接下來的請求建立聯絡。你可以在Session State中儲存任意型別的資料,作為你的應用,狀態被同一個程序和AppDomain(App域)維護。Session State的特點是為每一個特定的客戶建立狀態以維護客戶的資訊,這些狀態資訊儲存在伺服器端的預設的會話狀態配置中。

Session(“Value”) = expr ; // Storing the data into session object SomeFunction() { int expr = Int32.Parse(Session(“Value”));//Accessing from it if (expr>=something) { //do something } Else { //do something else } //Some other thing goes here }

既然Session State針對特定的客戶建立,通過它來識別客戶的請求。Asp.Net提供了一種加密機制和編碼演算法生成自己的Session Key。這是非常必要的,因為知道了你的Session Key,就有許可權訪問指定的頁面了。

在ASP.Net中生成Session Key的方法:

byte[] sessionkey = new byte[15];

//Generates a random number RNGCryptoServiceProvider rngkey = new RNGCryptoServiceProvider (); rngkey.GetBytes (sessionkey); string clientsessionKey = SessionId.Encode (sessionkey);

但是Session和客戶端的Cookie是有關的,當客戶關掉Cookie時,Session就失效了。不過在ASP.Net 中可以在web.config中修改設定,使Session的傳遞脫離Cookie。方法是:

對於Cookie大家並不陌生,每個Cookie儲存了多個名/值對,我們可以通過HttpCookie類的值集合來訪問它,也可以間接地通過類所提供的索引器訪問。Cookie在ASP.Net下的使用: protected void Page_Load(Object sender, EventArgs E) { int expr = 0; if (Request.Cookies["Expr"] == null) { // "Expr" cookie not set, set with this response HttpCookie cokExpr = new HttpCookie("Expr"); cokExpr.Value = exprTextBox.Text; Response.Cookies.Add(cokExpr); expr = Convert.ToInt32(exprTextBox.Text); } else { // use existing cookie value... expr = Convert.ToInt32(Request.Cookies["Expr"].Value); } // use expr to customize page }

由於Cookie儲存的資訊是放到客戶端的,使用者在訪問伺服器端頁面時,必然在客戶端和伺服器端之間頻繁交換資訊,影響了程式的效能。而Session由於儲存在伺服器記憶體中,因此不存在這個問題。不過,Session儲存的資訊是臨時的,使用者一旦關閉瀏覽器,狀態即失去。而Cookie則相反。

至於View State,主要是指控制元件和頁面的狀態資訊,它以_VIEWSTATE值傳遞給伺服器端。有興趣的可以看我另外一篇文章:ASP.Net中控制元件的EnableViewState屬性

Application、Session和Cookie,可以借用Carfield的總結:

COOKIE 是本地檔案,是 40 大盜在阿里巴巴家做的記號,或者是送牛奶的人在你家門口釘的箱子。

SESSION 是伺服器端記憶體,是你洗澡時浴池發給你的鑰匙。自己專用,可以開自己的好多箱子。

APPLICATION 是公共浴池。在這裡能看見所有人,包括 ppmm 哦:)。

1
IIS6,SESSION超時時間過短的解決。通常在主目錄->配置->應用程式選項重設定會話時間,預設20,單位分鐘。另外還可以修改配置檔案METABASE.XML的ASPSESSIONTIMEOUT項實現。但這次沒有起作用。去掉了站點本身的可能,最後把目標放在應用程式池上。開啟網站對應的應用程式池屬性,將WEB園數量改為1。重啟IIS後,session正常。


2
IIS6下面預設SESSION的超時時間是20秒,造成一些程度認證資訊丟失,檢查發現這是由於META-BA**.*ML的設定裡面ASPSESSIONTIMEOUT="20"引起的。一般可以考慮改為900或者1200。
這個設定檔案在WINDOWS/SYSTEM32/INETSRV下面。

注意修改之前需要停掉IISADMIN服務。改完了重啟W3SVC就可以用了。


3
應用程式池DefaultAppPool關閉超時錯誤2007年03月15日 12:15今天伺服器產生“應用程式池 'DefaultAppPool' 提供服務的程序關閉時間超過了限制。程序 ID 是 '2068'。”的錯誤,導致iis處於假死狀態,而這樣的情況在前期數量少的網站情況下沒有發生。後來通過搜尋相關網站,才瞭解是IIS應用程式池的設定問題。解決方法如下:

右擊應用程式池DefaultAppPool,選取屬性:
一、回收
1、回收工作程序(分鐘):選中,值為1740
2、回收工作程序(請求數目):不選(原先設定為35000)
3、在下列時間回收工作程序:不填
4、消耗太多記憶體時回收工作程序:全不選。(2、3、4項可能避免了在訪問量高的時候強制回收程序可能引發的伺服器響應問題,導致iis假死不響應)
二、效能
      只選中空閒超時20分鐘。其他都不選。WEB園最大工作程序數為1(預設)。注意web園這裡一定要保持預設,如果填寫其他超過1的數字就會導致一些網站程式的後臺程式打不開或者重新整理不停。

原來的請求佇列限制為4000,現在無限制。
三、執行狀況
      前兩項都起用,是原來的預設設定。啟動時間限制90秒,關閉時間限制180秒。

“關閉時間限制180秒”是必須的,因為程序關閉的時間,原來為90秒限制,是預設值,如果程序關閉時間超過90秒,則認為超時,從而出現:程序關閉時間超過了限制 日誌,所以,適當延長這個時間,可以避免這種錯誤




.Net WebService(也包括一般意義的 HttpWebRequest) 超時設定

.Net WebService(也包括一般意義的 HttpWebRequest) 超時設定

1. 伺服器端設定超時

web.config 的 system.web 裡新增如下配置項:

< httpRuntime
executionTimeout="30"
/>

以上時間單位是秒.

記得要把 web.config 的 debug 模式關閉:

< compilation
defaultLanguage="c#"
debug="false"
/>

如果 debug 模式沒有關閉, executionTimeout 會被忽略. 這時候, 如果應用是在單步跟蹤的模式下, 根據經驗, 超時時間大約是 90 秒(在 machine.config 裡設定的, 我猜的^_^), 如果不是在單步跟蹤的模式下, 超時時間可能是 20 分鐘(也是我猜的, 因為其 session 的預設超時時間是 20 分鐘, 哈). 我懶得找微軟的文件作進一步的求證了, 反正我用不著知道 debug 模式下的確切超時時間.

2. 客戶端設定超時

在 WebService 的客戶端代理程式(用 wsdl.exe 生成)裡設定 Request 超時時間, 單位是毫秒:
protected override WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest wr = (HttpWebRequest)base.GetWebRequest( uri );
wr.Timeout = 30*1000;
return wr;
}

從同一個頁面傳到另一個頁面才能延續同一個session,也就是說session不可跨域,同時客戶端一關閉瀏覽器或一關閉瀏覽頁 Session也消失了,再次訪問時又會建立新的Session 但還會在伺服器上存活等待超時,只是呼叫不到了.  另外比如在第一個頁面置了SESSION,然後REDIRECT去第二個頁面。解決方法是在REDIRECT中設定endResponse為FALSE。

  Iframe丟Session的原因:session是客戶端和伺服器端共同認證的,客戶端儲存標識,通過附加在頁面的頭髮送給伺服器端,伺服器進行識別,如果符合條件就可以獲得相應的session操作權。