WCF zaman aşımı istisnası ayrıntılı inceleme


94

IIS7 üzerinde çalışan bir WCF hizmetine (* .svc) ve hizmeti sorgulayan çeşitli istemcilere sahip bir uygulamamız var. Sunucu, Win 2008 Sunucusunu çalıştırıyor. İstemciler Windows 2008 Sunucusu veya Windows 2003 sunucusu çalıştırıyor. Aslında çok sayıda potansiyel WCF sorunuyla ilgili olabileceğini gördüğüm aşağıdaki istisnayı alıyorum.

System.TimeoutException: The request channel timed out while waiting for a reply after 00:00:59.9320000. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout. ---> System.TimeoutException: The HTTP request to 'http://www.domain.com/WebServices/myservice.svc/gzip' has exceeded the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout. 

Zaman aşımını 30 dakikaya çıkardım ve hata hala devam ediyor. Bu bana başka bir şeyin işin başında olduğunu söylüyor çünkü veri miktarının yüklenmesi veya indirilmesi asla 30 dakika süremez.

Hata gelir ve gider. Şu anda daha sık. Aynı anda çalışan 3 istemcim veya 100'üm olması önemli görünmüyor, yine de arada bir oluyor. Çoğu zaman zaman aşımı olmuyor ama yine de saatte birkaç tane alıyorum. Hata, çağrılan yöntemlerin herhangi birinden gelir. Bu yöntemlerden birinin parametresi yoktur ve bir bit veri döndürür. Bir diğeri parametre olarak çok fazla veri alır ancak eşzamansız olarak çalışır. Hatalar her zaman istemciden kaynaklanır ve yığın izlemede sunucudaki herhangi bir koda asla başvurmaz. Her zaman şu şekilde biter:

 at System.Net.HttpWebRequest.GetResponse()
  at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

Sunucuda: Aşağıdaki bağlama ayarlarını denedim (ve şu anda var):

maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647"

Etkisi yok gibi görünüyor.

Aşağıdaki kısıtlama ayarlarını denedim (ve şu anda var):

<serviceThrottling maxConcurrentCalls="1500"   maxConcurrentInstances="1500"    maxConcurrentSessions="1500"/>

Etkisi yok gibi görünüyor.

Şu anda WCF hizmeti için aşağıdaki ayarlara sahibim.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]

ConcurrencyMode.MultipleBir süre koştum ve hata hala devam etti.

IIS'yi yeniden başlatmayı, temeldeki SQL Server'ımı yeniden başlatmayı ve makineyi yeniden başlatmayı denedim. Tüm bunların bir etkisi yok gibi görünüyor.

Windows güvenlik duvarını devre dışı bırakmayı denedim. Etkisi yok gibi görünüyor.

İstemcide şu ayarlara sahibim:

maxReceivedMessageSize="2147483647"

<system.net>
    <connectionManagement>
    <add address="*" maxconnection="16"/>
</connectionManagement> 
</system.net>

Müşterim bağlantılarını kapatıyor:

var client = new MyClient();

try
{
    return client.GetConfigurationOptions();
}
finally
{
    client.Close();
}

Daha fazla giden bağlantıya izin vermek için kayıt defteri ayarlarını değiştirdim:

MaxConnectionsPerServer=24, MaxConnectionsPer1_0Server=32.

Son zamanlarda SvcTraceViewer.exe'yi denedim. Müşteri tarafında bir istisna yakalamayı başardım. Süresinin 1 dakika olduğunu görüyorum. Sunucu tarafı izine baktığımda, sunucunun bu istisnadan haberdar olmadığını görebiliyorum. Görebildiğim maksimum süre 10 saniyedir.

exec sp_whoSunucuda kullanarak aktif veritabanı bağlantılarına baktım . Bende sadece birkaç tane var (2-3). TCPview kullanarak bir istemciden gelen TCP bağlantılarına baktım. Genellikle 2-3 civarında ve 5 veya 6'ya kadar gördüm.

Basitçe söylemek gerekirse, şaşkınım. Bulabildiğim her şeyi denedim ve bir WCF uzmanının görebileceği çok basit bir şeyi kaçırıyor olmalıyım. Sunucu gerçekten mesajı almadan önce bir şeyin müşterilerimi düşük seviyede (TCP) engellediğini ve / veya bir şeyin mesajları sunucu seviyesinde kuyruğa aldığını ve asla işlemelerine izin vermediğini hissettim.

Bakmam gereken performans sayaçlarınız varsa lütfen bana bildirin. (Bu sayaçlardan bazılarının şifresini çözmek zor olduğundan, lütfen hangi değerlerin kötü olduğunu belirtin). Ayrıca, WCF mesaj boyutunu nasıl kaydedebilirim? Son olarak, istemcim ve sunucum arasında kaç bağlantı kurabileceğimi test etmeme izin verecek herhangi bir araç var mı (uygulamamdan bağımsız olarak)

Zaman ayırdığınız için teşekkürler!

Ekstra bilgiler 20 Haziran'da eklendi:

WCF uygulamam aşağıdakine benzer bir şey yapıyor.

while (true)
{
   Step1GetConfigurationSettingsFromServerViaWCF(); // can change between calls
   Step2GetWorkUnitFromServerViaWCF();
   DoWorkLocally(); // takes 5-15minutes. 
   Step3SendBackResultsToServerViaWCF();
}

WireShark'ı kullanarak, hata oluştuğunda, beş TCP yeniden aktarımım olduğunu ve ardından daha sonra bir TCP sıfırlamasının olduğunu gördüm. Tahminimce RST, bağlantıyı kesen WCF'den geliyor. Aldığım istisna raporu 3. Adımda zaman aşımına uğradı.

Bunu "tcp.stream eq 192" tcp akışına bakarak keşfettim. Daha sonra filtremi "tcp.stream eq 192 ve http ve http.request.method eq POST" olarak genişlettim ve bu akış sırasında 6 POST gördüm. Bu garip göründü, bu yüzden tcp.stream eq 100 gibi başka bir akışla kontrol ettim. Üç POST'um vardı, bu biraz daha normal görünüyor çünkü üç arama yapıyorum. Ancak, her WCF çağrısından sonra bağlantımı kapatıyorum, bu nedenle akış başına bir çağrı bekliyordum (ancak TCP hakkında fazla bir şey bilmiyorum).

Biraz daha araştırarak, http paket yükünü diske atarak bu altı kişinin neyi nerede aradığına baktım.

1) Step3
2) Step1
3) Step2
4) Step3 - corrupted
5) Step1
6) Step2

Tahminime göre iki eşzamanlı istemci aynı bağlantıyı kullanıyor, bu yüzden kopyalar gördüm. Ancak, hala anlayamadığım birkaç sorun daha var:

a) Paket neden bozulmuş? Rastgele ağ şansı - belki? Yükleme, bu örnek kod kullanılarak gzip ile sıkıştırılır: http://msdn.microsoft.com/en-us/library/ms751458.aspx - Kod, aynı anda kullanıldığında arada bir hatalı olabilir mi? Gzip kitaplığı olmadan test etmeliyim.

b) Bozuk işlem zaman aşımına uğradıktan SONRA neden 1. ve 2. adımın çalıştığını görüyorum? Bana öyle geliyor ki bu operasyonlar olmamalıydı. Belki doğru akışa bakmıyorum çünkü TCP anlayışım kusurludur. Aynı anda gerçekleşen başka akışlarım var. Diğer akışları araştırmalıyım - 190-194 akışlarına hızlı bir bakış, Adım 3 POST'un uygun yük verilerine sahip olduğunu (bozuk değil) gösterir. Beni gzip kitaplığına tekrar bakmaya zorluyor.


Jason - bu sorunu hiç çözdün mü? DefaultConnectionLimit ayarı mıydı?
SFun28

2
@JasonKealey - Diğer birçok sorunun aksine, soruyu göndermeden önce kendi kendinize denememekle suçlanamazsınız :) Sorunuzun bu kadar ayrıntılı ve tüm önemli detayları içermesini çok seviyorum. Tanımladığınız semptomlar benimkine çok benziyor, bu yüzden çözümün de aynı
olacağını

Yanıtlar:


51

.Net istemcisi kullanıyorsanız, ayarlamamış olabilirsiniz

//This says how many outgoing connection you can make to a single endpoint. Default Value is 2
System.Net.ServicePointManager.DefaultConnectionLimit = 200;

orijinal soru ve yanıt burada WCF Service Throttling

Güncelleme :

Bu yapılandırma .Net istemci uygulamasına giriyor, başlangıçta veya ne zaman ancak testlerinize başlamadan önce olabilir.

Dahası, app.config dosyasında ve aşağıdaki gibi olabilir

<system.net>
    <connectionManagement>
      <add maxconnection = "200" address ="*" />
    </connectionManagement>
  </system.net>

Bu umut verici görünüyor. Bunu bir sonraki ölçeklenebilirlik testimde test edilmek üzere dahil ettim. Tam olarak çökmesine neden olacak türden bir rastgele ayara benziyor :) İşaretçi için teşekkürler.
Jason Kealey

1
@Jason: Sunucu programcısıysanız, sunucunun ölçeklenebilirliğini elinizde tutmanın ne kadar önemli olduğunu ve aynı zamanda yukarıda kullandıktan sonra bile eşzamanlılık sorunu yaşayan birinin ne kadar önemli olduğunu biliyorsunuz. Lütfen aşağıdaki soruya bakabilirseniz stackoverflow.com/questions/2637175/wcf-network-cost Kısaca istemci ve sunucu arasında 31 ms gecikme yaşıyorum ve bunu azaltmam gerekiyor.
Mubashar

3
Sadece bir yıl sürdü, ancak sonunda bu bayrak setiyle uygulama üzerinde başka bir stres testi yaptım. Sorun çözülmüş görünüyor, bu yüzden size en iyi cevabı veriyorum. Bunun yapbozun gerekli olan son parçası olmasına, ancak hatanın gerçekleşmemesini sağlamak için diğer tüm unsurların yerinde olması gerektiğine şaşırmam. Çok teşekkürler!
Jason Kealey

2
@Aris: .net istemci uygulamasında, başlangıçta veya global yapılandırmanızı ayarladığınız her yerde, yapılandırılabilir tutmak istiyorsanız, bunu <system.net> <connectionManagement> gibi yapılandırma dosyasına ekleyebilirsiniz <add maxconnection = "200" address = "*" /> </connectionManagement> </system.net>
Mubashar

3

Zaten denemediyseniz - Sunucu tarafı WCF İşlemlerinizi try / nihayet bloklarında kapsülleyin ve gerçekten geri döndüklerinden emin olmak için günlük kaydı ekleyin.

Bunlar Operasyonların tamamlandığını gösteriyorsa, bir sonraki adımım daha düşük bir seviyeye gitmek ve gerçek taşıma katmanına bakmak olacaktır.

Wireshark veya başka bir benzer paket yakalama aracı bu noktada oldukça yardımcı olabilir. Bunun standart bağlantı noktası 80'de HTTP üzerinden çalıştığını varsayıyorum.

İstemcide Wireshark'ı çalıştırın. Yakalamayı başlattığınızda Seçenekler'de, yakalama filtresini olarak ayarlayın tcp http and host service.example.com - bu, alakasız trafik miktarını azaltacaktır.

Yapabiliyorsanız, istemcinizi size aramanın tam başlangıç ​​zamanını ve zaman aşımının oluştuğu zamanı bildirecek şekilde değiştirin. Veya sadece yakından izleyin.

Bir hata aldığınızda, aramanın başlangıcını bulmak için Wireshark günlükleri arasında gezinebilirsiniz. İstemcinizin onu çağırdığı ilk pakete sağ tıklayın (GET /service.svc veya POST /service.svc gibi bir şey olmalıdır) ve TCP Akışını İzle öğesini seçin.

Wireshark tüm HTTP Konuşmasının kodunu çözecektir, böylece WCF'nin gerçekten yanıtları geri göndermesini sağlayabilirsiniz.


Sunucuda oturum açıyorum - bu uçta bir hata yok. Ne bulabileceğimi görmek için şu anda WireShark'ı çalıştırıyorum. Yüksek trafik hacmi göz önüne alındığında, analiz etmek zor olacak, ancak bir şey bulabilirsem geri bildireceğim.
Jason Kealey

WireShark'ı son altı saatte çalıştırdım ve 60 bin kare topladım. Bugün bu müşteri tarafından yalnızca bir istisna rapor edildi. Görünüşe göre, hata e-postasını gönderdikten sonra, muhtemelen bağlantıyı sonlandıran WCF olan RST (sıfırlama) olarak işaretlenmiş bir TCP bağlantısı gördüm. Yükü (525k) diske kaydettim. Benzer boyutlu yüklere sahip 87 başka çağrı olduğunu doğruladım. Birkaç TCP yeniden iletimi gördüm, ancak bazılarını diğer çağrılarda da gördüm (bu başarısız olmadı). Ağ donanımı + kablolarımı merak etmeye başladım.
Jason Kealey

Yerel bir ağda bile, TCP Retransmits varlığı mutlaka kötü değildir. İki uç noktayı tek bir anahtara fiziksel olarak bağlamak mümkünse, bu bir denemeye değer olabilir, ancak bunun düzeltileceğini ummuyorum. Yapabiliyorsanız, trafiğin bir kısmını sunucunuza ileri geri aktaran ve başka hiçbir şey yapmayan çok basit bir istemci uygulaması oluşturun. Bu, uygulamanızda zaman aşımına neden olabilecek herhangi bir sorunu gidermeye yardımcı olabilir.

Ayrıca, TCP Sıfırlama paketini gördüğünüzden bahsediyorsunuz - sunucu bu noktada herhangi bir yanıt verdi mi (veya belki de daha fazla veri bekliyor muydu)? RST ile önceki paket arasında kayda değer bir gecikme oldu mu?

Sunucu uzaktadır. Bunun yardımcı olup olmadığını görmek için yerel olarak bir test ortamı oluşturmayı planlıyorum. RST'ye gelince, beş TCP Yeniden İletiminin sonuncusundan 34 saniye sonra gönderildi. (Yeniden iletimler arasında 1 ila 8 saniyelik aralıklar). Bu sana herhangi bir ipucu veriyor mu?
Jason Kealey

2

from: http://www.codeproject.com/KB/WCF/WCF_Operation_Timeout_.aspx

Bu zaman aşımı hatasını önlemek için, WCF istemci kodunda Proxy için OperationTimeout özelliğini yapılandırmamız gerekir . Bu yapılandırma, makalenin başlarında tartıştığım Gönderme Zaman Aşımı, Alma Zaman Aşımı vb. Gibi diğer yapılandırmalardan farklı olarak yeni bir şey. Bu işlem zaman aşımı özelliği yapılandırmasını ayarlamak için, işlem sözleşmesi yöntemlerini çağırmadan önce proxy'mizi WCF istemci uygulamasındaki IContextChannel'e çevirmeliyiz.


Bunu denedim. Koyduğum zaman aşımına bakılmaksızın, yine de zaman aşımına uğradı ama bu bir anlam ifade etmiyor çünkü işlem o kadar uzun değil ve çünkü aynı sorguları yapan diğer tüm istemciler bu süre içinde çalışıyor.
Jason Kealey

Testlerim, OperationTimeout'un yalnızca Config'den ReceiveTimeout'u geçersiz kıldığını kanıtladı. Bu nedenle, hiçbir faydası yoktur.
dudeNumber4

2

Çok benzer bir sorun yaşıyorum. Geçmişte bu, serileştirme sorunları ile ilgiliydi. Hala bu sorunu yaşıyorsanız, geri gönderdiğiniz nesneleri doğru şekilde serileştirebildiğinizi doğrulayabilir misiniz? Özellikle, ilişkileri olan Linq-To-Sql nesnelerini kullanıyorsanız, bir alt nesneye ana nesneye bir geri başvuru koyarsanız ve bu geri başvuruyu DataMember olarak işaretlerseniz bilinen serileştirme sorunları vardır.

Sunucu tarafındaki DataContractSerializer'ı ve istemcinizin kullandığı serileştirme yöntemlerini kullanarak nesnelerinizi serileştiren ve serisini kaldıran bir konsol uygulaması yazarak serileştirmeyi doğrulayabilirsiniz. Örneğin, mevcut uygulamamızda hem WPF hem de Compact Framework istemcilerimiz var. DataContractSerializer kullanarak serileştirebileceğimi ve XmlDesserializer kullanarak seriyi kaldırabileceğimi doğrulamak için bir konsol uygulaması yazdım. Bunu deneyebilirsin.

Ayrıca, alt koleksiyonları olan Linq-To-Sql nesnelerini iade ediyorsanız, onları sunucu tarafında hevesle yüklediğinizden emin olmaya çalışabilirsiniz. Bazen, tembel yükleme nedeniyle, döndürülen nesneler doldurulmaz ve isteğin hizmet yöntemine birden çok kez gönderildiği yerde gördüğünüz davranışa neden olabilir.

Bu sorunu çözdüyseniz, nasıl olduğunu duymak isterim çünkü ben de buna bağlıyım. Sorunumun serileştirme olmadığını doğruladım, bu yüzden kayboldum.

GÜNCELLEME: Size yardımcı olup olmayacağından emin değilim, ancak Hizmet İzleme Görüntüleyici Aracı, sizinkine çok benzer 5 günlük deneyimden sonra sorunumu çözdü. İzlemeyi kurarak ve ardından ham XML'e bakarak, serileştirme sorunlarıma neden olan istisnaları buldum. Başarıyla serileştirilebilecek olandan daha fazla alt nesneye sahip olan Linq-SQL nesneleriyle ilgiliydi. Aşağıdakileri web.config dosyanıza eklemek, izlemeyi etkinleştirmelidir:

<sharedListeners>
    <add name="sharedListener"
         type="System.Diagnostics.XmlWriterTraceListener"
         initializeData="c:\Temp\servicetrace.svclog" />
  </sharedListeners>
  <sources>
    <source name="System.ServiceModel" switchValue="Verbose, ActivityTracing" >
      <listeners>
        <add name="sharedListener" />
      </listeners>
    </source>
    <source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
      <listeners>
        <add name="sharedListener" />
      </listeners>
    </source>
  </sources>

Ortaya çıkan dosya, sonuçları incelemek için Service Trace Viewer Tool ile veya sadece IE'de açılabilir.


2

İstekler arasında WCF hizmetiyle olan bağlantıyı kapatıyor musunuz? Bunu yapmazsanız, bu tam zaman aşımını göreceksiniz (sonunda).


2

Sorunu çözdüm, App.config dosyasındaki düğümlerin yanlış yapılandırıldığını buldum.

<client>
<endpoint name="WCF_QtrwiseSalesService" binding="wsHttpBinding" bindingConfiguration="ws" address="http://cntgbs1131:9005/MyService/TGE.ISupplierClientManager" contract="*">
</endpoint>
</client>

<bindings>
    <wsHttpBinding>
        <binding name="ws" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text">
            <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
            <**security mode="None">**
                <transport clientCredentialType="None"></transport>
            </security>
        </binding>
    </wsHttpBinding>
</bindings>

Düğümdeki yapılandırmanızı onaylayın, <security>"mod" özniteliğinin değeri "Yok" dur. Değeriniz "Taşıma" ise, hata oluşur.


Bu güvenliği etkilemez mi? Öyleyse, bu çoğu gerçek uygulama için bir çözüm olmayabilir
Veverke

0

SOAP araç seti veya benzeri bir şey kullanarak gönderilen mesajı görmek için clientVia'yı kullanmayı denediniz mi? Bu, hatanın istemcinin kendisinden mi yoksa başka bir yerden mi geldiğini görmeye yardımcı olabilir.


Kullanımdan kaldırılmış SOAP araç setinden daha yeni, bu bilgileri WCF çağrılarına kaydetmemi kolaylaştıracak herhangi bir araç biliyor musunuz?
Jason Kealey

SOAP Toolkit isedeprecated
Kiquenet

0

WCF izlerini kontrol ettiniz mi? WCF'nin istisnaları yutma ve yalnızca son istisnayı döndürme eğilimi vardır, bu da aldığınız zaman aşımıdır, çünkü bitiş noktası anlamlı bir şey döndürmez.


SvcTraceViewer'ı denedim ve bildirdiği tek istisna, zaman aşımıydı (istemcide). Sunucuda hiçbir şey rapor edilmedi.
Jason Kealey

İz üzerindeki tüm seçenekleri açın, tüm izleme seçeneklerini açmamış olabilirsiniz. Ayrıca, hem olay izleme hem de ileti izleme dosyalarını kontrol edin.
Miki Watts

0

Ayrıca, istemciye varsayılan olarak ayarlanmayan bir enum türü özelliği içeren ve bu numaralandırmanın 0 ile eşleşen bir değeri olmayan bir nesneyi geri gönderiyorsanız da bu hatayı alırsınız. enum MyEnum{ a=1, b=2};


0

Görünüşe göre bu istisna mesajı oldukça geneldir ve çeşitli nedenlerle alınabilir. İstemciyi Windows 8.1 makinelerde dağıtırken bununla karşılaştık. WCF istemcimiz bir Windows hizmetinin içinde çalışır ve sürekli olarak WCF hizmetini sorgular. Windows hizmeti yönetici olmayan bir kullanıcı altında çalışır. Sorun, aşağıdaki gibi kimlik doğrulamanın geçişine izin vermek için WCF yapılandırmasında clientCredentialType "Windows" olarak ayarlanarak düzeltildi:

      <security mode="None">
        <transport clientCredentialType="Windows" proxyCredentialType="None"
          realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>

0

Bir WCF uzmanı değilim, ancak IIS'de bir DDOS korumasıyla karşılaşıp karşılaşmadığınızı merak ediyorum. Tecrübelerimden, tek bir istemciden bir sunucuya bir dizi eşzamanlı bağlantı çalıştırırsanız, sunucunun bir DDOS saldırısından şüphelendiği için çağrılara yanıt vermeyi bıraktığını biliyorum. Ayrıca, istemcinin saldırılarını yavaşlatmak için bağlantıları zaman aşımına uğrayana kadar açık tutacaktır.

Ancak farklı makinelerden / IP'lerden gelen çoklu bağlantı sorun olmamalıdır.

Bu MSDN gönderisinde daha fazla bilgi var:

http://msdn.microsoft.com/en-us/library/bb463275.aspx

MaxConcurrentSession sproperty'ye göz atın.


Gördüğüm her şeyden bunun olduğunu hissediyorum, ancak (sunucuda) sahip olsam da: <serviceThrottling maxConcurrentCalls = "150" maxConcurrentInstances = "150" maxConcurrentSessions = "150" /> <serviceDebug includeExceptionDetailInFaults = "true" /> Bunun olup olmadığını görmek için izleyebileceğim herhangi bir performans izleyicisi veya IIS günlüğü olacak mı?
Jason Kealey
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.