2012-11-14 17 views
7

Tôi đã đọc this, this, thisthis cùng với hàng tá bài đăng/blog khác.Application_End có nên kích hoạt trên App Pool Recycle tự động không?

Tôi có một ứng dụng ASP.Net trong chia sẻ lưu trữ thường xuyên được tái chế. Chúng tôi sử dụng NLog và có mã sau trong global.asax

void Application_Start(object sender, EventArgs e) 
{ 
    NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); 
    logger.Debug("\r\n\r\nAPPLICATION STARTING\r\n\r\n"); 
} 
protected void Application_OnEnd(Object sender, EventArgs e) 
{ 
    NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); 
    logger.Debug("\r\n\r\nAPPLICATION_OnEnd\r\n\r\n"); 
} 

void Application_End(object sender, EventArgs e) 
{ 
     HttpRuntime runtime = (HttpRuntime)typeof(System.Web.HttpRuntime).InvokeMember("_theRuntime", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField, null, null, null); 

if (runtime == null) 
    return; 

string shutDownMessage = (string)runtime.GetType().InvokeMember("_shutDownMessage", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, runtime, null); 

string shutDownStack = (string)runtime.GetType().InvokeMember("_shutDownStack", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, runtime, null); 

ApplicationShutdownReason shutdownReason = System.Web.Hosting.HostingEnvironment.ShutdownReason; 

NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); 
logger.Debug(String.Format("\r\n\r\nAPPLICATION END\r\n\r\n_shutDownReason = {2}\r\n\r\n _shutDownMessage = {0}\r\n\r\n_shutDownStack = {1}\r\n\r\n", 
       shutDownMessage, shutDownStack, shutdownReason)); 
} 

void Application_Error(object sender, EventArgs e) 
{ 
    NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); 
    logger.Debug("\r\n\r\nApplication_Error\r\n\r\n"); 

} 

log file của chúng tôi là rải rác với mục "ĐƠN KHỞI", nhưng không phải Application_OnEnd, Application_End, cũng không Application_Error được bao giờ bị sa thải trong những khởi động lại tự phát. Tôi biết họ đang làm việc vì có các mục nhập để chạm vào tệp web.config hoặc/bin. Chúng tôi cũng đã chạy kiểm tra quá tải bộ nhớ và có thể kích hoạt một số OutOfMemoryException bị bắt trong Application_Error.

Chúng tôi đang cố gắng xác định xem giới hạn bộ nhớ ảo có gây ra việc tái chế hay không. Chúng tôi đã thêm GC.GetTotalMemory(false) trong suốt mã, nhưng điều này là dành cho tất cả .Net, không chỉ là hồ bơi của ứng dụng của chúng tôi, đúng không? Chúng tôi cũng đã thử

var oPerfCounter = new PerformanceCounter(); 
oPerfCounter.CategoryName = "Process"; 
oPerfCounter.CounterName = "Virtual Bytes"; 
oPerfCounter.InstanceName = "iisExpress"; 
logger.Debug("Virtual Bytes: " + oPerfCounter.RawValue + " bytes"); 

nhưng không được phép chia sẻ lưu trữ.

Tôi đã theo dõi ứng dụng trên máy chủ dev có cùng yêu cầu khiến việc tái chế trong sản xuất với ANTS Memory Profiler được đính kèm và dường như không thể tìm thấy thủ phạm. Chúng tôi cũng đã chạy nó với một trình gỡ lỗi được đính kèm trong dev để kiểm tra các ngoại lệ chưa được bắt đầu trong các luồng được sinh ra có thể khiến ứng dụng bị hủy bỏ.

Câu hỏi của tôi là những:

  • Làm thế nào tôi có thể có hiệu quả giám sát việc sử dụng bộ nhớ trong chia sẻ lưu trữ để nói bao nhiêu ứng dụng của tôi được tiêu thụ trước khi một thùng ứng dụng?
  • Tại sao trình xử lý Application_ [End/OnEnd/Error] trong global.asax không được gọi?
  • Làm cách nào khác để xác định nguyên nhân gây ra những lần tái chế này?

Cảm ơn.

EDIT: Dựa trên câu trả lời bằng @Jani Hyytiäinen

Kịch bản: Chủ đề # 1 bắt đầu và được theo sau bởi thread # 2. Chủ đề số 1 truy cập giới hạn bộ nhớ nhưng vẫn tiếp tục xử lý. Chủ đề # 3 bắt đầu. Thread # 1 kết thúc, nhưng # 2 xử lý hơn 60 giây sau khi # 1 đã đạt tới giới hạn bộ nhớ.

Các hồ bơi sau đó hủy bỏ không đúng lúc? Câu trả lời http sẽ # 2 & # 3 nhận (Đây là những cuộc gọi AJAX, nhưng tôi nhận được 504 lỗi trong Fiddler)?
Yêu cầu cho số 3 được chấp nhận hay nó chỉ xếp hàng cho đến khi một hồ bơi mới bắt đầu?
Có cách nào để biết rằng giới hạn bộ nhớ đã bị trúng hoặc sắp sửa không?

Mọi chiến lược đều được chào đón.

+0

Thời gian chờ cổng HTTP 504 không thực sự được trang web của bạn trả về vì chính lỗi đó có nghĩa là tài nguyên được yêu cầu bởi url không phản hồi kịp thời. Trong trường hợp của bạn, có lẽ vì hồ bơi ứng dụng đã bị đóng cửa và mới chưa bắt đầu. Khi hồ bơi ứng dụng tắt, tất cả các chủ đề trong nó sẽ hủy bỏ với nó. Mà chắc chắn nhất dẫn đến HTTP 504 trên các chủ đề # 2 và # 3 –

Trả lời

12

Có giới hạn thời gian tắt hồ bơi ứng dụng trong iis. Hãy nói rằng đó là 60 giây và trong môi trường lưu trữ được chia sẻ có một giới hạn bộ nhớ ứng dụng hồ bơi. Hồ bơi ứng dụng của bạn đạt đến giới hạn này và iis yêu cầu nhóm ứng dụng hoàn thành tất cả công việc với các yêu cầu hiện tại. Nếu tất cả các yêu cầu kết thúc xử lý trước khi 60 giây được thông qua, application_end sẽ kích hoạt và ứng dụng pool sẽ tự tắt chính nó. Tuy nhiên, nếu 60 giây trôi qua và yêu cầu vẫn đang được xử lý, IIS sẽ khó chịu và giết chết nhóm ứng dụng. Lần này không có application_end sẽ kích hoạt. Tương tự, không có trình xử lý sự kiện lỗi nào được kích hoạt.

0

Tôi đã xem một trong các ứng dụng của tôi kích hoạt sự kiện tắt máy chính xác và đây là chữ ký trong Global.asax.cs:

protected void Application_End(object sender, EventArgs e) 
{ 
    ApplicationShutdownReason shutdownReason = System.Web.Hosting.HostingEnvironment.ShutdownReason; 
    // Write to log 
} 

Sự khác biệt duy nhất tôi nhận thấy là bạn "Application_End" và "Application_Error" phương pháp này không có "bảo vệ" sửa đổi. Tôi đã nhìn thấy rất nhiều tình huống mà sự phản chiếu không hoạt động với các thành viên riêng tư, do đó có thể đang diễn ra.

Ngoài ra, hãy thử đặt idle timeout trên hồ bơi ứng dụng cục bộ/dev của bạn xuống mức thấp (như 1 phút), sau đó đảm bảo sự kiện Application_End của bạn kích hoạt cục bộ.

Lưu ý rằng theo mặc định ứng dụng IIS có thể tái chế sau 20 phút không có yêu cầu, vì vậy bạn có thể nhấn nếu bạn có ứng dụng lưu lượng thấp. Ngoài ra, một số nhà cung cấp dịch vụ lưu trữ được chia sẻ thay đổi giá trị "thời gian chờ" này sẽ thấp hơn để tiết kiệm tài nguyên.

+1

Cảm ơn, nhưng như tôi đã nói chúng tôi đang nhận được sự kiện Application_End cho các loại tắt máy khác, "Tôi biết họ đang làm việc vì có mục nhập để chạm vào web.config hoặc/bin files. " Dễ thương pic btw :) – Laramie

+1

@Laramie, xin lỗi, tôi hiểu lầm. Bạn đã cố gắng thiết lập môi trường dev của bạn [giới hạn bộ nhớ ảo] (http://technet.microsoft.com/en-us/library/cc753179 (v = ws.10) .aspx) vào một điều gì đó thực sự thấp để xem bạn có thể tái tạo hành vi bạn đang thấy trong môi trường được chia sẻ? –

+0

Chúng tôi sẽ tiếp tục để chúng tôi có thể theo dõi việc sử dụng bộ nhớ. Trong khi chờ đợi, chúng tôi đã tối ưu hóa và kiểm soát nó trong thời gian này. Tôi không nghĩ rằng sẽ có một câu trả lời dễ dàng ở đây, nhưng tôi muốn được vui mừng để upvote một! – Laramie

0

Không chắc bạn đang sử dụng phiên bản IIS nào nhưng IIS7.5 có một loạt các cài đặt Nhật ký sự kiện của bể bơi ứng dụng cho phép bạn ghi lại lý do tái chế hồ bơi ứng dụng.

Trong IIS, hãy đi tới Hồ bơi ứng dụng và chuyển đến Cài đặt nâng cao trên nhóm ứng dụng được đề cập. Đi xuống để tái chế và có và menu phụ gọi là "Tạo mục nhập nhật ký sự kiện tái tạo".

Các vấn đề liên quan