2012-05-04 31 views
11

Tôi đã biết câu trả lời cho điều này, nhưng muốn chia sẻ với cộng đồng vì nó KHÔNG được ghi lại từ Microsoft.Server 2008 RC2, IIS 7.5, ASP.NET và các yêu cầu Xếp hàng kém hiệu suất

Kịch bản: Tăng lưu lượng truy cập truy cập trang web IIS 7.5 ASP.NET của bạn và bạn nhận thấy rằng các yêu cầu bắt đầu xếp hàng. Hiệu suất của trang web chậm lại khi thu thập dữ liệu, nhưng bạn có rất nhiều CPU và RAM.

Đây là vấn đề chúng tôi thấy gần đây với trang web đã thực hiện một loạt các cuộc gọi dịch vụ web nội bộ. Một kiểm tra sức khỏe nội bộ sẽ bắt đầu thời gian ra, mà sẽ gây ra máy chủ này để thả ra khỏi cụm của chúng tôi. (Tuy nhiên, máy chủ này là phần cứng mạnh mẽ nhất của bó ...)

Trả lời

12

Sau khi tìm kiếm trên internet, tôi thấy các bài viết sau đây từ Microsoft có liên quan đến các vấn đề:

KB 821.268: Contention, poor performance, and deadlocks when you make Web service requests from ASP.NET applications

Bài viết này cung cấp một số mẹo chỉnh sửa hiệu suất tuyệt vời, tuy nhiên nó không đề cập đến một số trần rất quan trọng mà chúng tôi đã chạy đến.

Các giải pháp đối với chúng ta là để sửa đổi Machine.config của chúng tôi, và cư các nút XML sau:

<system.web> 
    <processModel autoConfig="false" maxWorkerThreads="xxx" maxIoThreads="xxx" minWorkerThreads="xxx" minIoThreads="xxx" requestQueueLimit="5000" responseDeadlockInterval="00:03:00"/> 
    <httpRuntime minFreeThreads="xxx" minLocalRequestFreeThreads="xxx"/> 
</system.web> 

Tôi cố tình thiết lập một số những con số này để "xxx" vì chúng là phụ thuộc vào phần cứng của bạn.

Từ bài viết KB ở trên, Microsoft đề xuất một số phương trình để tìm ra các giá trị này. Tuy nhiên, họ không đề cập đến giá trị tối đa cho những con số này là kích thước của một INT, hoặc 32767.

Vì vậy, ĐÚNG phương trình để tính toán những hiểu như sau:

  • maxWorkerThreads: 32767/#Cores
    • Trong trường hợp của chúng tôi, chúng tôi có máy chủ 24 lõi. Vì vậy, giá trị của chúng tôi maxWorkerThreads được thiết lập một cách chính xác để: 1365. Bất kỳ số có kết quả trong một số nguyên lớn hơn 32767, máy chủ sẽ thiết lập các maxWorkerThreads đến 32767.
  • maxIoThreads: Tương tự như maxWorkerThreads (32767/#Cores)
  • minWorkerThreads: maxWorkerThreads/2
    • Đây là một khó khăn. Nếu vượt quá giá trị số nguyên LARGER hơn 32767 (và bất chấp bài viết KB nói gì, con số này IS nhân với số lõi bạn có) và không giống như giá trị "tối đa", giá trị mặc định này cho số lõi trên máy của bạn! Trong trường hợp của chúng tôi, điều này đã được thiết lập để 24 (vì chúng tôi thiết lập một giá trị tùy ý cao cho min), và đó là KILLING hiệu suất trên máy chủ của chúng tôi.
  • minIoThreads: Tương tự như minWorkerThreads
  • minFreeThreads: 88 * #Cores (lấy trực tiếp từ bài viết KB)
  • minLocalRequestFreeThreads: 76 * #Cores (lấy trực tiếp từ bài viết KB)

Giải pháp này không dành cho tất cả mọi người và chỉ nên sử dụng nếu bạn đáp ứng các tiêu chí trong bài viết KB. Một công cụ khác mà chúng tôi đã sử dụng để giúp chúng tôi chẩn đoán đây là trang .ASPX không có mã phía sau mà chúng tôi có thể ném ra trên bất kỳ máy chủ nào (mà không cần đặt lại Hồ bơi ứng dụng). Trang này sử dụng sự phản chiếu để cho bạn biết điều gì đang thực sự xảy ra trong nhóm luồng và những giá trị của các cài đặt này hiển thị trên máy chủ của bạn.

<%@ Page Language="C#" %> 

<!DOCTYPE html> 
<html lang="en"> 
<head> 
<style> 
    body { margin: 20pt; padding: 0pt; font-family: Verdana, "san-serif";} 
    fieldset { border-radius: 5px; border: none; background-color: #fff; margin: 10pt;} 
    fieldset.parent { background-color: #f0f0f0; } 
    legend { font-size: 10pt; color: #888; margin: 5pt; } 

    .ports div { padding: 10pt 0pt 0pt 0pt; clear: both; } 
    .ports div:first-child { padding: 0pt; } 
    .ports div div { padding: 0pt; clear: none; margin: 1pt; background-color: #eef; display: block; float: left; border: 5pt solid #eef; } 
    .ports div div:first-child { border-top-left-radius: 5pt; border-bottom-left-radius: 5pt; background-color: #ccf; border-color: #ccf;} 
    .ports div div:last-child { border-top-right-radius: 5pt; border-bottom-right-radius: 5pt; background-color: #ccf; border-color: #ccf; padding: 0pt 10pt 0pt 10pt; } 
</style> 

</head> 
<body> 

<% 
Response.Cache.SetCacheability(HttpCacheability.NoCache); 

int worker, workerMIN, workerMAX; 
int port, portMIN, portMAX; 
System.Threading.ThreadPool.GetAvailableThreads(out worker, out port); 
System.Threading.ThreadPool.GetMinThreads(out workerMIN, out portMIN); 
System.Threading.ThreadPool.GetMaxThreads(out workerMAX, out portMAX); 

%> 

<fieldset class="parent"> 
<legend>Thread Information</legend> 

<fieldset> 
    <legend>Worker Threads</legend> 
    <div class="ports"> 
     <div> 
      <div>Min: <%=workerMIN %></div> 
      <div>Current: <%=workerMAX - worker %></div> 
      <div>Max: <%=workerMAX %></div> 
     </div> 
    </div> 
</fieldset> 

<fieldset> 
    <legend>Completion Port Threads</legend> 
    <div class="ports"> 
     <div> 
      <div>Min: <%=portMIN %></div> 
      <div>Current: <%=portMAX - port %></div> 
      <div>Max: <%=portMAX %></div> 
     </div> 
    </div> 
</fieldset> 

<fieldset> 
    <legend>Request Queue Information</legend> 
    <div class="ports"> 

<% 


var fi = typeof(HttpRuntime).GetField("_theRuntime", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static).GetValue(null); 
var rq = typeof(HttpRuntime).GetField("_requestQueue", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(fi); 
var fields = rq.GetType().GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); 

foreach (var field in fields) 
{ 
    string name = field.Name; 
    string value = ""; 

    switch (name) 
    { 
     case "_localQueue": 
     case "_externQueue": 
      System.Collections.Queue queue = field.GetValue(rq) as System.Collections.Queue; 
      value = queue.Count.ToString(); 
      break; 

     default: 
      value = field.GetValue(rq).ToString(); 
      break; 
    } 

    %> 
     <div> 
      <div><%=name %></div> 
      <div><%=value %></div> 
     </div> 
    <% 
    //Response.Write(string.Format("{0}={1}<br/>", name, value)); 
} 

%> 
    </div> 
</fieldset> 
</fieldset> 



</body></html> 
+0

Tại sao maxWorkerThreads tỷ lệ nghịch với #Cores? nghĩa là các lõi bạn có maxWorkerThreads thấp hơn. Nó có ý nghĩa hơn với tôi rằng maxWorkerThreads là x * #Cores, nói maxWorkerThreads = 16 * #Cores. – DavidF

+0

Bạn chắc chắn rằng minWorkerThreads và minIoThreads được nhân với số lõi? Điều đó có dành riêng cho .net 4.5 không? –

+0

Dường như được xác nhận ở đây - https://msdn.microsoft.com/en-us/library/system.web.configuration.processmodelsection.minworkerthreads(v=vs.100).aspx –

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