2012-02-27 44 views
6

我有一個複雜的服務器應用程序,使用Nhibernate和Linq2SQL。 Linq2sql代碼每天約3次生成一個「值不能爲空」的異常。一旦發生這種情況,代碼將始終生成異常。診斷和解決根本原因將是漫長的,並會引起不穩定。如何以編程方式回收.net Web應用程序自己的應用程序池?

目前的「修復」是每小時回收一次應用程序池。但是,從問題發生的時候起,服務就會停止,直到發生回收。我希望Web服務捕捉異常並回收它自己的應用程序池。我希望所有其他的網絡請求都能得到遵守,直到它們完成。

編輯:該故障位於負載平衡Web場上的兩臺服務器上。僅僅因爲此代碼崩潰,客戶端不會從一臺服務器切換到另一臺服務器。

+2

「診斷和解決根本原因將是漫長的,並會在downvotealanche之前引入不穩定性。您應該配置應用程序池以在短期內進行回收,並長期修復該錯誤。 – Will 2012-02-27 18:25:40

+0

謝謝。這是計劃 – 2012-02-27 18:32:04

+0

最好的方法是修復bug – 2012-02-27 19:36:47

回答

18

以下代碼將回收當前網站的應用程序池。您需要添加對Microsoft.Web.Administration的引用

using (ServerManager iisManager = new ServerManager()) 
{ 
    SiteCollection sites = iisManager.Sites; 
    foreach (Site site in sites) 
    { 
     if (site.Name == HostingEnvironment.ApplicationHost.GetSiteName()) 
     { 
     iisManager.ApplicationPools[site.Applications["/"].ApplicationPoolName].Recycle(); 
     break; 
     } 
    } 
} 
+6

這應該是可以接受的答案。 – vittore 2015-05-21 16:55:18

+0

@vittore與OP有類似的問題,這不會削減它。 APPPOOL沒有權利解決這個問題,所以它也可能不適用於OP。 OP的解決方案對我來說很有用,但它只是感覺*令人毛骨悚然*;)這樣做。 – ClasG 2016-07-07 13:55:12

+0

@ClasG是的,你需要擴展權限才能工作 – vittore 2016-07-07 14:55:15

0

最後一句話是一個殺手。

爲了實現這個目標,你必須實現一個負載均衡設置,這個設置比解決你原來的問題要複雜得多。

我建議你付出一些努力來解決這個異常。請從相關的Linq查詢中發佈一些代碼,也許我們可以在那裏提供一些建議。

+1

如果您確實想解決潛在的問題,請發佈一個新問題:原始問題和問題是非常單獨的問題。 – 2012-02-27 18:37:52

+0

我確實想解決潛在的問題,是的,你是對的,這是一個完全不同的任務。但這不是本月的工作。 – 2012-02-27 18:39:02

3

將ASP.NET工作進程「移動」回收到應用程序池的最簡單方法是以某種方式修改web.config文件。此更改由文件系統監視器提取,並導致ASP.NET重新啓動以加載新配置。

該文件的內容不必以任何實際的方式改變;只需添加或刪除空白字符就足夠了。

編輯:

如果這是沒有強大到足以解決你的問題,你可以去整個生豬和使用目錄服務來手動回收應用程序池。

// Set up the path identifying your application pool. 
var path = "IIS://YOURSERVERNAME/W3SVC/AppPools/YourAppPoolName"; 

// Create the directory entry to control the app pool 
var appPool = new DirectoryEntry(path); 

// Invoke the recycle action. 
appPool.Invoke("Recycle", null); 

根據Code Project: Recycling IIS 6.0 application pools programmatically

+0

觸摸web.config,即使我明確授予IUSR寫入權限(這是一個樂隊幫助記住),它只會回收應用程序,而不是APP POOL。數據問題出現在應用程序池中,並且w3wp進程繼續歡快地 – 2012-02-27 20:03:35

+0

用更直接的方法更新。它沒有被驗證在IIS7 +上工作,所以讓我們知道你如何繼續。 – 2012-02-28 07:39:44

+0

我原本是沿着這條路走下去的,但所需的權限列表非常繁瑣複雜。我決定採用一種更簡單的解決方案,即讓應用程序池的設置在超出memoryLimit值時進行回收,然後故意分配內存,直到回收被觸發。 – 2012-02-28 14:11:14

0

我以前有過完全一樣的問題;我應該寫博客,因爲現在我不記得根本原因。

我的直覺告訴我,那是下列之一:

  1. 沒有得到某處佈置的上下文。
  2. 線程問題:確保多個線程無法訪問相同的上下文。

或沿着這些線。只要確保你正確使用Linq2Sql。

0

我最終選擇的解決方案是爲appPool允許使用的內存量設置最大值。代碼然後簡單地吞噬內存,直到asp.net決定回收appPool。

在應用程序池高級設置中,我將專用內存限制設置爲800,000 Kb。

在該保持部分,其中的LINQ代碼失敗了,我比限制分配更多的內存:

List<string> listOfMemory = new List<string>(); 

// in the app pool, you need to set the virtual memory limit to 800,000kb 
log.Error("Allocating so much memory that the app pool will be forced to recycle... "); 
for (int intCount = 1; intCount < 10000000; intCount++) 
{ 
listOfMemory.Add("new string " + intCount.ToString()); 
} 

現在這意味着新的W3WP進程產生之前僅約4個線程失敗。在此解決方案之前,線程一直會失敗,直到人工手動回收應用程序池。不幸的是,如果您將應用程序池設置爲按常規分鐘數回收,則分鐘數越小,崩潰越頻繁。而分鐘數越大,線程越多失敗。

這種創造性的解決方法限制了損害。

+0

雖然這可能適合你的環境,但如果出現以下情況,它也可能暫時連接服務器:你的應用程序使用200 MB內存,服務器有400 MB的內存空間,你的應用程序開始分配內存。此時,您需要600 MB來強制回收,並且服務器將在分配400 MB後開始大量頁面。 – 2013-08-20 02:18:58

+0

哇......很醜陋。但即使你想這樣做,爲什麼不只是新的[]任何數量的RAM你想分配? – 2016-09-13 11:36:34

相關問題