Kuyruğa Alınan İletilerde Sorun Giderme
Bu bölüm, Windows Communication Foundation'da (WCF) kuyrukları kullanmaya yönelik sık sorulan soruları ve sorun giderme yardımlarını içerir.
Sık Sorulan Sorular
S: WCF Beta 1'i kullandım ve MSMQ düzeltmesini yükledim. Düzeltmeyi kaldırmam gerekiyor mu?
Y: Evet. Bu düzeltme artık desteklenmiyor. WCF artık MSMQ üzerinde düzeltme gereksinimi olmadan çalışır.
S: MSMQ için iki bağlama vardır: NetMsmqBinding ve MsmqIntegrationBinding. Ne ve ne zaman kullanmalıyım?
A: MSMQ'yu NetMsmqBinding iki WCF uygulaması arasında kuyruğa alınmış iletişim için aktarım olarak kullanmak istediğinizde kullanın. MsmqIntegrationBinding Yeni WCF uygulamalarıyla iletişim kurmak için mevcut MSMQ uygulamalarını kullanmak istediğinizde kullanın.
S: ve MsmqIntegration
bağlamalarını kullanmak için MSMQ'yu NetMsmqBinding yükseltmem gerekiyor mu?
Y: Hayır. Her iki bağlama da Windows XP ve Windows Server 2003 üzerinde MSMQ 3.0 ile çalışır. Windows Vista'da MSMQ 4.0'a yükselttiğinizde bağlamaların bazı özellikleri kullanılabilir hale gelir.
S: VE MsmqIntegrationBinding bağlamalarının NetMsmqBinding hangi özellikleri MSMQ 4.0'da kullanılabilir ancak MSMQ 3.0'da kullanılamaz?
A: Aşağıdaki özellikler MSMQ 4.0'da kullanılabilir ancak MSMQ 3.0'da kullanılamaz:
Özel teslim edilemeyen ileti kuyruğu yalnızca MSMQ 4.0'da desteklenir.
MSMQ 3.0 ve 4.0 zehirli iletileri farklı işler.
Yalnızca MSMQ 4.0, uzaktan işlem yapılan okumayı destekler.
S: Kuyruğa alınmış bir iletişimin bir tarafında MSMQ 3.0 ve diğer tarafta MSMQ 4.0 kullanabilir miyim?
Y: Evet.
S: Mevcut MSMQ uygulamalarını yeni WCF istemcileri veya sunucularıyla tümleştirmek istiyorum. MSMQ altyapımın her iki tarafını da yükseltmem gerekiyor mu?
Y: Hayır. Her iki tarafta da MSMQ 4.0'a yükseltmeniz gerekmez.
Sorun giderme
Bu bölüm en yaygın sorun giderme sorunlarının yanıtlarını içerir. Bilinen sınırlamalar olan bazı sorunlar sürüm notlarında da açıklanmıştır.
S: Özel bir kuyruk kullanmaya çalışıyorum ve şu özel durumu alıyorum: System.InvalidOperationException
URL geçersiz. Kuyruğun URL'si '$' karakterini içeremez. Özel kuyruğu ele almak için net.msmq://machine/private/queueName içinde söz dizimini kullanın.
A: Yapılandırmanızda ve kodunuzda sıra Tekdüzen Kaynak Tanımlayıcısı'nı (URI) denetleyin. URI'de "$" karakterini kullanmayın. Örneğin OrdersQueue adlı özel bir kuyruğu ele almak için URI'yi olarak net.msmq://localhost/private/ordersQueue
belirtin.
S: Kuyruğa alınan uygulamamda çağrı ServiceHost.Open()
şu özel durumu oluşturur: System.ArgumentException
Temel adres bir URI sorgu dizesi içeremez. Neden?
A: Yapılandırma dosyanızda ve kodunuzda kuyruk URI'sini denetleyin. MSMQ kuyrukları '?' karakterinin kullanımını desteklese de, URI'ler bu karakteri dize sorgusunun başlangıcı olarak yorumlar. Bu sorundan kaçınmak için '?' karakterleri içermeyen kuyruk adlarını kullanın.
S: Göndermem başarılı oldu ama alıcıda hiçbir hizmet işlemi çağrıldı. Neden?
A: Yanıtı belirlemek için aşağıdaki denetim listesini inceleyin:
İşlem kuyruğu gereksinimlerinin belirtilen güvencelerle uyumlu olup olmadığını denetleyin. Aşağıdaki ilkelere dikkat edin:
Dayanıklı iletileri (veri birimleri ve oturumlar) "tam olarak bir kez" güvencesiyle (ExactlyOnce =
true
) yalnızca işlem kuyruğuna gönderebilirsiniz.Oturumları yalnızca "tam olarak bir kez" güvencesiyle gönderebilirsiniz.
İşlem kuyruğundan bir oturumdaki iletileri almak için bir işlem gereklidir.
Geçici veya dayanıklı iletileri (yalnızca veri birimleri) hiçbir güvence olmadan (ExactlyOnce =
false
) yalnızca işlem dışı bir kuyruğa gönderebilir veya alabilirsiniz.
Teslim edilemeyen ileti kuyruğunu denetleyin. İletileri orada bulursanız neden teslim edilmediklerini belirleyin.
Bağlantı veya sorun giderme için giden kuyrukları denetleyin.
S: Özel bir teslim edilemeyen ileti kuyruğu belirttim, ancak gönderen uygulamayı başlattığımda, teslim edilemeyen ileti kuyruğunun bulunamadığını veya gönderen uygulamanın teslim edilemeyen ileti kuyruğuna izin vermediğini belirten bir özel durum alıyorum. Bu neden oluyor?
A: Özel teslim edilemeyen ileti kuyruğu URI'si ilk segmentte bir "localhost" veya bilgisayar adı içermelidir; örneğin, net.msmq://localhost/private/myAppdead-letter kuyruğu.
S: Özel bir teslim edilemeyen ileti kuyruğu tanımlamak her zaman gerekli mi yoksa varsayılan bir teslim edilemeyen ileti kuyruğu mu var?
A: Güvenceler "tam olarak bir kez" ()ExactlyOnce = true
ise ve özel bir teslim edilemeyen ileti kuyruğu belirtmezseniz, varsayılan değer sistem genelinde işlem için kullanılmayan ileti kuyruğudur.
Güvenceler yoksa (ExactlyOnce = false
), varsayılan değer teslim edilemeyen kuyruk işlevi değildir.
S: Hizmetim SvcHost.Open'da "EndpointListener gereksinimleri ListenerFactory tarafından karşılanamıyor" iletisiyle birlikte oluşturacak. Neden?
A. Hizmet sözleşmenizi denetleyin. Tüm hizmet işlemlerine "IsOneWay=true
" koymayı unutmuş olabilirsiniz. Kuyruklar yalnızca tek yönlü hizmet işlemlerini destekler.
S: Kuyrukta iletiler var ama hiçbir hizmet işlemi çağrılmış değil. Sorun nedir?
A: Hizmet ana bilgisayarınızın hatalı olup olmadığını belirleyin. İzlemeye bakarak veya uygulayarak IErrorHandler
kontrol edebilirsiniz. Varsayılan olarak, bir zehir iletisi algılanırsa hizmet ana bilgisayarı hataları.
S: Kuyrukta iletiler var ama Web'de barındırılan kuyruğa alınmış hizmetim etkinleştirilmiyor. Neden?
A: En yaygın neden izinlerdir.
İşlemin çalıştığından
NetMsmqActivator
ve işlemin kimliğineNetMsmqActivator
kuyrukta okuma ve arama izni verildiğinden emin olun.NetMsmqActivator
uzak bir makinede kuyrukları izliyorsa, kısıtlanmış belirteç altında çalışmadığından emin olunNetMsmqActivator
. kısıtlamasız bir belirteçle komutunu çalıştırmakNetMsmqActivator
için:sc sidtype NetMsmqActivator unrestricted
Güvenlikle ilgili olmayan Web ana bilgisayarı sorunları için bkz. Kuyruğa Alınmış Bir Uygulamayı Barındıran Web.
S: Oturumlara erişmenin en kolay yolu nedir?
A: Oturumdaki son iletiye karşılık gelen işlemde AutoComplete=true
değerini ayarlayın ve kalan tüm hizmet işlemlerinde AutoComplete=false
değerini ayarlayın.
S: Hizmetim hem kuyruğa alınmış oturum iletilerini hem de kuyruğa alınmış veri birimi iletilerini içeren bir kuyruktan okurken neden bir oluşturur ProtocolException
?
A: Kuyruğa alınan oturum iletilerinin ve kuyruğa alınan veri birimi iletilerinin oluşturma yönteminde temel bir fark vardır. Bu nedenle, kuyruğa alınmış bir oturum iletisini okumayı bekleyen bir hizmet kuyruğa alınmış bir veri birimi iletisi alamaz ve kuyruğa alınmış bir veri birimi iletisini okumayı bekleyen bir hizmet oturum iletisi alamaz. Aynı kuyruktan her iki ileti türünü de okumaya çalışmak aşağıdaki özel durumu oluşturur:
System.ServiceModel.MsmqPoisonMessageException: The transport channel detected a poison message. This occurred because the message exceeded the maximum number of delivery attempts or because the channel detected a fundamental problem with the message. The inner exception may contain additional information.
---> System.ServiceModel.ProtocolException: An incoming MSMQ message contained invalid or unexpected .NET Message Framing information in its body. The message cannot be received. Ensure that the sender is using a compatible service contract with a matching SessionMode.
Bir uygulama hem kuyruğa alınmış oturum iletilerini hem de kuyruğa alınmış veri birimi iletilerini aynı bilgisayardan gönderirse, sistem teslim edilemeyen ileti kuyruğu ve özel bir teslim edilemeyen ileti kuyruğu bu soruna özellikle duyarlıdır. İleti başarıyla gönderilemiyorsa, ileti teslim edilemeyen ileti kuyruğuna taşınır. Bu koşullar altında, hem oturum hem de veri birimi iletilerinin teslim edilemeyen ileti kuyruğunda olması mümkündür. Bir kuyruktan okurken çalışma zamanında her iki ileti türünü de ayırmanın bir yolu yoktur, bu nedenle uygulamalar aynı bilgisayardan hem kuyruğa alınmış oturum iletilerini hem de kuyruğa alınmış veri birimi iletilerini göndermemelidir.
MSMQ Tümleştirmesi: Belirli Sorun Giderme
S: bir ileti gönderdiğimde veya hizmet ana bilgisayarını açtığımda, şemanın yanlış olduğunu belirten bir hata alıyorum. Neden?
A: MSMQ tümleştirme bağlamasını kullanırken msmq.formatname düzenini kullanmanız gerekir. Örneğin, msmq.formatname:DIRECT=OS:.\private$\OrdersQueue. Ancak özel teslim edilemeyen ileti kuyruğunu belirttiğinizde net.msmq düzenini kullanmanız gerekir.
S: Genel veya özel biçimli bir ad kullandığımda ve Windows Vista'da hizmet ana bilgisayarını açtığımda bir hata alıyorum. Neden?
A: Windows Vista'da WCF tümleştirme kanalı, zehirli iletileri işlemek için ana uygulama kuyruğu için bir alt sorgu açılıp açılamadığını denetler. Alt sorgu adı, dinleyiciye geçirilen msmq.formatname URI'sinden türetilir. MSMQ'daki alt sorgu adı yalnızca doğrudan biçim adı olabilir. Bu nedenle hatayı görürsünüz. Kuyruk URI'sini doğrudan biçim adıyla değiştirin.
S: MSMQ uygulamasından ileti alınırken, ileti kuyrukta durur ve alıcı WCF uygulaması tarafından okunmuyor. Neden?
A: İletinin gövdesi olup olmadığını denetleyin. İletinin gövdesi yoksa MSMQ tümleştirme kanalı iletiyi yoksayar. Özel durumların bildirilmesi için uygulayın IErrorHandler
ve izlemeleri denetleyin.
Security-Related Sorunlarını Giderme
S: Çalışma grubu modunda varsayılan bağlama kullanan örneği çalıştırdığımda iletiler gönderilmiş gibi görünüyor ama alıcı tarafından hiçbir zaman alınmıyor.
A: Varsayılan olarak, iletiler Active Directory dizin hizmetini gerektiren bir MSMQ iç sertifikası kullanılarak imzalar. Active Directory kullanılamadığından, çalışma grubu modunda ileti imzalanmaz. Bu nedenle ileti teslim edilemeyen ileti kuyruğuna gelir ve "Hatalı imza" gibi hata nedeni belirtilir.
Geçici çözüm, güvenliği kapatmaktır. Bu, çalışma grubu modunda çalışmasını sağlamak için ayarlanarak Mode = None yapılır.
Bir diğer geçici çözüm de özelliğinden Transport öğesini alıp MsmqTransportSecurity olarak ayarlamak Certificateve istemci sertifikasını ayarlamaktır.
Ancak bir diğer geçici çözüm de MSMQ'yi Active Directory tümleştirmesiyle yüklemektir.
S: Active Directory'de varsayılan bağlama (aktarım güvenliği açık) olan bir iletiyi kuyruğa gönderdiğim zaman "iç sertifika bulunamadı" iletisi alıyorum. Bunu düzeltmek Nasıl yaparım??
A: Bu, gönderen için Active Directory'deki sertifikanın yenilenmesi gerektiği anlamına gelir. Bunu yapmak için Denetim Masası, Yönetim Araçları, Bilgisayar Yönetimi'ni açın, MSMQ'ye sağ tıklayın ve Özellikler'i seçin. Kullanıcı Sertifikası sekmesini seçin ve Yenile düğmesine tıklayın.
S: kullanarak Certificate bir ileti gönderdiğim ve kullanılacak sertifikayı belirttiğim zaman "Geçersiz sertifika" iletisi alıyorum. Bunu düzeltmek Nasıl yaparım??
A: Yerel makine sertifika depolarını sertifika moduyla kullanamazsınız. Sertifika ek bileşenini kullanarak sertifikayı makine sertifika deposundan geçerli kullanıcı deposuna kopyalamanız gerekir. Sertifika ek bileşenini almak için:
Başlat'a tıklayın, Çalıştır'ı seçin, yazın
mmc
ve Tamam'a tıklayın.Microsoft Yönetim Konsolu'ndaDosya menüsünü açın ve Ek Bileşen Ekle/Kaldır'ı seçin.
Ek Bileşen Ekle/Kaldır iletişim kutusunda Ekle düğmesine tıklayın.
Tek Başına Ek Bileşen Ekle iletişim kutusunda Sertifikalar'ı seçin ve Ekle'ye tıklayın.
Sertifikalar ek bileşeni iletişim kutusunda Kullanıcı hesabım'ı seçin ve Son'a tıklayın.
Ardından, önceki adımları kullanarak ikinci bir Sertifikalar ek bileşeni ekleyin, ancak bu kez Bilgisayar hesabı'nı seçin ve İleri'ye tıklayın.
Yerel Bilgisayar öğesini seçip Tamamla öğesini tıklatın. Artık sertifikaları makine sertifika deposundan geçerli kullanıcı deposuna sürükleyip bırakabilirsiniz.
S: Hizmetim çalışma grubu modunda başka bir bilgisayardaki kuyruktan okurken "erişim reddedildi" özel durumu alıyorum.
A: Çalışma grubu modunda, uzak bir uygulamanın kuyruğa erişim kazanması için uygulamanın kuyruğa erişim izni olması gerekir. Kuyruğun erişim denetimi listesine (ACL) "Anonim oturum açma" ekleyin ve okuma izni verin.
S: Bir ağ hizmeti istemcisi (veya etki alanı hesabı olmayan herhangi bir istemci) kuyruğa alınmış bir ileti gönderdiğinde, gönderme işlemi geçersiz bir sertifikayla başarısız olur. Bunu düzeltmek Nasıl yaparım??
A: Bağlama yapılandırmasını denetleyin. Varsayılan bağlamada, iletiyi imzalamak için MSMQ aktarım güvenliği açık durumdadır. Kapatın.
Uzaktan İşlem Yapılan Almalar
S: A makinesinde bir kuyruğum ve B makinesindeki bir kuyruktan iletileri okuyan bir WCF hizmetim olduğunda (uzak işlem yapılan alma senaryosu), iletiler kuyruktan okunmuyor. İzleme bilgileri, alma işleminin "İşlem içeri aktarılamıyor" iletisiyle başarısız olduğunu gösterir. Bunu düzeltmek için ne yapabilirim?
A: Bunun üç olası nedeni vardır:
Etki alanı modundaysanız, uzaktan işlem yapılan alma işlemi Microsoft Dağıtılmış İşlem Düzenleyicisi (MSDTC) ağ erişimi gerektirir. Bileşen Ekle/Kaldır'ı kullanarak bunu etkinleştirebilirsiniz.
İşlem yöneticisiyle iletişim kurmak için kimlik doğrulama modunu denetleyin. Çalışma grubu modundaysanız , "Kimlik Doğrulaması Gerekmez" seçilmelidir. Etki alanı modundaysanız ,"Karşılıklı Kimlik Doğrulaması Gerekli" seçili olmalıdır.
MSDTC'nin İnternet Bağlantısı Güvenlik Duvarı ayarlarındaki özel durumlar listesinde olduğundan emin olun.
Windows Vista kullandığınızdan emin olun. Windows Vista'da MSMQ, uzaktan işlem yapılmış okumayı destekler. Önceki Windows sürümlerinde MSMQ, uzaktan işlem yapılan okumayı desteklemez.
S: Kuyruktan okuma hizmeti bir ağ hizmetiyse (örneğin, bir Web konağında) kuyruktan okurken neden erişim reddedildi özel durumu alıyorum?
A: Ağ hizmetinin kuyruktan okuyabilmesi için ağ hizmeti okuma erişimi kuyruk ACL'sine eklenmelidir.
S: MSMQ etkinleştirme hizmetini kullanarak uygulamaları uzak makinedeki bir kuyruktaki iletilere göre etkinleştirebilir miyim?
Y: Evet. Bunu yapmak için MSMQ etkinleştirme hizmetini bir ağ hizmeti olarak çalışacak şekilde yapılandırmanız ve uzak makinedeki kuyruğa ağ hizmeti erişimi eklemeniz gerekir.
ReceiveContext Etkinken Özel MSMQ Bağlamaları Kullanma
Etkin olan ReceiveContext özel bir MSMQ bağlaması kullanılırken, yerel MSMQ zaman uyumsuz ReceiveContext almalar için G/Ç tamamlanmasını desteklemediğinden gelen ileti işlenirken iş parçacığı havuzu iş parçacığı kullanılır. Bunun nedeni, böyle bir iletinin işlenmesinin için ReceiveContext iç işlemleri kullanması ve MSMQ'nin zaman uyumsuz işlemeyi desteklememesidir. Bu sorunu geçici olarak çözmek için, zaman uyumlu işlemeyi zorlamak için uç noktaya bir SynchronousReceiveBehavior ekleyebilir veya 1 olarak ayarlayabilirsiniz MaxPendingReceives .