bir ASP.NET uygulamasından web hizmetlerine çağrı yaptığınızda performans sorunları

Bu makalede, bir Microsoft ASP.NET uygulamasından web hizmetlerine çağrı yaptığınızda oluşan performans sorunlarını çözmeye yardımcı olur.

Orijinal ürün sürümü: ASP.NET
Özgün KB numarası: 821268

Belirtiler

bir ASP.NET uygulamasından web hizmetlerine çağrı yaptığınızda çekişme, düşük performans ve kilitlenmelerle karşılaşabilirsiniz. İstemciler isteklerin yanıt vermeyi durdurduğunu veya yürütülmesinin uzun sürdüğünü bildirebilir. Kilitlenmeden şüpheleniliyorsa, çalışan işlemi geri dönüştürülebilir.

yöntemine çağrı HttpWebRequest.GetResponse yaptığınızda aşağıdaki özel durum hata iletisini alabilirsiniz:

"System.InvalidOperationException: ThreadPool nesnesinde işlemi tamamlamak için yeterli boş iş parçacığı yoktu."

Tarayıcıda aşağıdaki özel durum hata iletisini de alabilirsiniz:

"HttpException (0x80004005): İstek zaman aşımına uğradı."

Not

Bu makale, doğrudan istekte HttpWebRequest bulunabilen uygulamalar için de geçerlidir.

Neden

bu sorun, ASP.NET bir çağrının istekleri yürütmek için kullanabileceği çalışan iş parçacığı sayısını ve tamamlama bağlantı noktası iş parçacıklarını sınırladığından oluşabilir.

Genellikle, bir web hizmetine yapılan çağrı, isteği gönderen kodu yürütmek için bir çalışan iş parçacığı ve web hizmetinden geri çağırmayı almak için bir tamamlama bağlantı noktası iş parçacığı kullanır. Ancak, istek yeniden yönlendirildiyse veya kimlik doğrulaması gerektiriyorsa, çağrı en fazla iki çalışan iş parçacığı ve iki tamamlama bağlantı noktası iş parçacığı kullanabilir. Bu nedenle, aynı anda birden çok web hizmeti çağrısı gerçekleştiğinde yönetilen ThreadPool işlemi tüketebilirsiniz.

Örneğin, öğesinin ThreadPool 10 çalışan iş parçacığıyla sınırlı olduğunu ve 10 çalışan iş parçacığının tümünün şu anda geri çağırmanın yürütülmesini bekleyen kodu yürütdüğünü varsayalım. Öğesine kuyruğa alınan tüm iş öğeleri bir iş parçacığı kullanılabilir duruma gelene kadar engellendiği için ThreadPool geri çağırma hiçbir zaman yürütülemez.

Başka bir olası çekişme kaynağı, ad alanının bağlantı sayısını sınırlamak için kullandığı parametredir maxconnectionSystem.Net . Genel olarak, bu sınır beklendiği gibi çalışır. Ancak, birçok uygulama aynı anda tek bir IP adresine çok sayıda istekte bulunmaya çalışırsa, iş parçacıklarının kullanılabilir bir bağlantı için beklemesi gerekebilir.

Çözüm

Bu sorunları çözmek için ,Machine.config dosyasında aşağıdaki parametreleri durumunuzla en uygun şekilde ayarlayabilirsiniz:

  • maxWorkerThreads
  • minWorkerThreads
  • maxIoThreads
  • minFreeThreads
  • minLocalRequestFreeThreads
  • maxconnection
  • executionTimeout

Bu sorunları başarıyla çözmek için aşağıdaki eylemleri gerçekleştirin:

  • Aynı anda yürütülebilecek ASP.NET isteklerinin sayısını CPU başına yaklaşık 12 ile sınırlayın.
  • Web hizmeti geri aramalarının içindeki iş parçacıklarını serbestçe kullanmasına ThreadPoolizin ver.
  • parametresi için maxconnections uygun bir değer seçin. Seçiminizi kullanılan IP adresi ve AppDomain sayısına göre belirleyin.

Not

CPU başına ASP.NET isteklerinin sayısını 12 ile sınırlama önerisi biraz rastgeledir. Ancak bu sınırın çoğu uygulamada iyi çalıştığı kanıtlanmıştır.

MaxWorkerThreads ve maxIoThreads

ASP.NET, kullanılan en fazla çalışan iş parçacığı ve tamamlama iş parçacığı sayısını sınırlamak için aşağıdaki iki yapılandırma ayarlarını kullanır:

<processModel maxWorkerThreads="20" maxIoThreads="20">

maxWorkerThreads parametresi ve maxIoThreads parametresi, CPU sayısıyla örtük olarak çarpılır. Örneğin, iki işlemciniz varsa, en fazla çalışan iş parçacığı sayısı 2 * maxWorkerThreadsolur.

MinFreeThreads ve minLocalRequestFreeThreads

ASP.NET, uzak istek veya yerel istek başlatmak için kaç çalışan iş parçacığının ve tamamlanma bağlantı noktası iş parçacığının kullanılabilir olması gerektiğini belirleyen aşağıdaki yapılandırma ayarlarını da içerir:

<httpRuntime minFreeThreads="8" minLocalRequestFreeThreads="8">

Kullanılabilir yeterli iş parçacığı yoksa, yeterli iş parçacığı isteği yapmak için serbest olana kadar istek kuyruğa alınır. Bu nedenle, ASP.NET aynı anda aşağıdaki istek sayısından fazlasını yürütmez:

(maxWorkerThreads * CPU sayısı) - minFreeThreads

Not

minFreeThreads Parametresi ve minLocalRequestFreeThreads parametresi, CPU sayısıyla örtük olarak çarpılmaz.

MinWorkerThreads

ASP.NET ayrıca, uzak isteğe hemen hizmet vermek için kaç çalışan iş parçacığının kullanılabilir hale getirilebileceğini belirleyen aşağıdaki yapılandırma ayarını içerir.

<processModel minWorkerThreads="1">

Bu ayar tarafından denetlenen iş parçacıkları, Ortak Dil Çalışma Zamanı'nın (CLR) varsayılan iş parçacığı ayarlama özelliklerinden oluşturulan çalışan iş parçacıklarından çok daha hızlı oluşturulabilir.

Bu ayar, bir arka uç sunucusunda yavaşlaması, istemci ucundan gelen ani istek artışı veya kuyruktaki istek sayısında ani artışa neden olabilecek benzer bir durum nedeniyle ASP.NET istek kuyruğunun aniden dolmasına neden olabilecek isteklere hizmet ASP.NET sağlar.

Parametre için minWorkerThreads varsayılan değer 1'dir. parametresinin değerini aşağıdaki değere minWorkerThreads ayarlamanızı öneririz:

minWorkerThreads = maxWorkerThreads / 2

Varsayılan olarak, minWorkerThreads parametresi Web.config dosyasında veya Machine.config dosyasında mevcut değildir. Bu ayar, CPU sayısıyla örtük olarak çarpılır.

Maxconnection

maxconnection parametresi, belirli bir IP adresine kaç bağlantı yapılabilmesi gerektiğini belirler. parametresi aşağıdaki gibi görünür:

<connectionManagement>
    <add address="*" maxconnection="2">
    <add address="http://65.53.32.230" maxconnection="12">
</connectionManagement>

Uygulamanın kodu uygulamaya IP adresi yerine konak adıyla başvuruda bulunursa, parametre aşağıdaki gibi görünmelidir:

<connectionManagement>
    <add address="*" maxconnection="2">
    <add address="http://hostname" maxconnection="12">
</connectionManagement>

Son olarak, uygulama 80 dışında bir bağlantı noktasında barındırılıyorsa, parametresinin aşağıdakine benzer şekilde standart olmayan bağlantı noktasını URL'ye eklemesi gerekir:

<connectionManagement>
    <add address="*" maxconnection="2">
    <add address="http://hostname:8080" maxconnection="12">
</connectionManagement>

Bu makalenin başlarında açıklanan parametrelerin ayarlarının tümü işlem düzeyindedir. Ancak, maxconnection parametre ayarı AppDomain düzeyine uygulanır. Varsayılan olarak, bu ayar AppDomain düzeyi için geçerli olduğundan, işleminizdeki her AppDomain'den belirli bir IP adresine en fazla iki bağlantı oluşturabilirsiniz.

Executiontimeout

ASP.NET, istek yürütme süresini sınırlamak için aşağıdaki yapılandırma ayarını kullanır:

<httpRuntime executionTimeout="90"/>

Bu sınırı özelliğini kullanarak Server.ScriptTimeout da ayarlayabilirsiniz.

Not

Parametrenin değerini executionTimeout artırırsanız, parametre ayarını da değiştirmeniz processModelresponseDeadlockInterval gerekebilir.

Öneriler

Bu bölümde önerilen ayarlar tüm uygulamalar için çalışmayabilir. Ancak, aşağıdaki ek bilgiler uygun ayarlamaları yapmanıza yardımcı olabilir.

Her ASPX sayfasından tek bir IP adresine tek bir web hizmeti çağrısı yapıyorsanız, Microsoft aşağıdaki yapılandırma ayarlarını kullanmanızı önerir:

  • parametresinin ve maxIoThreads parametresinin maxWorkerThreads değerlerini 100 olarak ayarlayın.
  • parametresinin maxconnection değerini 12*N olarak ayarlayın (burada N , sahip olduğunuz CPU sayısıdır).
  • parametresinin minFreeThreads değerlerini 88*N ve parametresini minLocalRequestFreeThreads76*N olarak ayarlayın.
  • değerini minWorkerThreads50 olarak ayarlayın. minWorkerThreads Varsayılan olarak yapılandırma dosyasında olmadığını unutmayın. Bunu eklemelisiniz.

Bu önerilerden bazıları, sunucudaki CPU sayısını içeren basit bir formül içerir. Formüllerdeki CPU sayısını temsil eden değişken N'dir.

Bu ayarlar için, hiper iş parçacığı etkinleştirilmişse fiziksel CPU sayısı yerine mantıksal CPU sayısını kullanmanız gerekir. Örneğin, hiper iş parçacığı etkinleştirilmiş dört işlemcili bir sunucunuz varsa formüllerdeki N değeri 4 yerine 8 olur.

Not

Bu yapılandırmayı kullandığınızda, CPU başına en fazla 12 ASP.NET isteği aynı anda yürütebilirsiniz çünkü 100-88=12. Bu nedenle, en az 88*N çalışan iş parçacığı ve 88*N tamamlama bağlantı noktası iş parçacıkları diğer kullanımlar için kullanılabilir (örneğin, web hizmeti geri çağırmaları için).

Örneğin, dört işlemci ve hiper iş parçacığı etkinleştirilmiş bir sunucunuz var. Bu formüllere bağlı olarak, bu makalede bahsedilen yapılandırma ayarları için aşağıdaki değerleri kullanırsınız.

<system.web>
    <processModel maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50"/>
    <httpRuntime minFreeThreads="704" minLocalRequestFreeThreads="608"/>
</system.web>
<system.net>
    <connectionManagement>
        <add address="[ProvideIPHere]" maxconnection="96"/>
    </connectionManagement>
</system.net>

Ayrıca, bu yapılandırmayı kullandığınızda, her AppDomain için IP adresi başına CPU başına 12 bağlantı sağlanır. Bu nedenle, aşağıdaki senaryoda, istekler bağlantıları beklediğinde ve ThreadPool bitmediğinde çok az çekişme oluşur:

  • Web yalnızca bir uygulamayı barındırıyor (AppDomain).
  • ASPX sayfası için her istek bir web hizmeti isteğinde bulunur.
  • Tüm istekler aynı IP adresine yöneliktir.

Ancak, bu yapılandırmayı kullandığınızda, aşağıdakilerden birini içeren senaryolarda büyük olasılıkla çok fazla bağlantı kullanılır:

  • İstekler birden çok IP adresine yöneliktir.
  • İstekler yeniden yönlendirilir (302 durum kodu).
  • İstekler için kimlik doğrulaması gerekir.
  • İstekler birden çok AppDomain'den yapılır.

Bu senaryolarda, parametre için maxconnection daha düşük bir değer ve parametre ile parametre için minFreeThreadsminLocalRequestFreeThreads daha yüksek değerler kullanmak iyi bir fikirdir.

Daha fazla bilgi

Daha fazla bilgi için bkz . ASP.NET Performansını Geliştirme.

IIS'de ASP.NET ile birlikte düşük performans ve çekişme yaşıyorsanız aşağıdaki Microsoft bloglarına gidin: