Zehirli İleti İşleme

Zehirli ileti , uygulamaya en fazla teslim denemesi sayısını aşan bir iletidir. Bu durum, kuyruk tabanlı bir uygulama hatalar nedeniyle bir iletiyi işleyemediğinde ortaya çıkabilir. Güvenilirlik taleplerini karşılamak için, kuyruğa alınan bir uygulama bir işlem kapsamında iletiler alır. Kuyruğa alınmış bir iletinin alındığı işlemi durdurmak, iletinin yeni bir işlem altında yeniden denenmesi için iletiyi kuyrukta bırakır. İşlemin durdurulmasına neden olan sorun düzeltilmediyse, alıcı uygulama en fazla teslim denemesi sayısı aşılana ve zehirli ileti sonuçlanana kadar aynı iletiyi alan ve durduran bir döngüde takılabilir.

Bir ileti birçok nedenden dolayı zehirli bir iletiye dönüşebilir. En yaygın nedenler uygulamaya özgü nedenlerdir. Örneğin, bir uygulama kuyruktan bir iletiyi okur ve bazı veritabanı işlemleri gerçekleştirirse, uygulama veritabanında kilit alamayabilir ve bu da işlemin durdurulmasına neden olabilir. Veritabanı işlemi durdurulmuş olduğundan, ileti kuyrukta kalır ve bu da uygulamanın iletiyi ikinci kez yeniden okumasına ve veritabanında bir kilit almak için başka bir girişimde bulunmasına neden olur. İletiler geçersiz bilgi içeriyorsa da zehirlenebilir. Örneğin, bir satınalma siparişi geçersiz bir müşteri numarası içerebilir. Bu durumlarda, uygulama işlemi gönüllü olarak iptal edebilir ve iletiyi zehirli bir ileti olmaya zorlayabilir.

Nadir durumlarda, iletiler uygulamaya gönderilene kadar başarısız olabilir. Windows Communication Foundation (WCF) katmanı, iletide yanlış çerçeve, geçersiz ileti kimlik bilgileri veya geçersiz bir eylem üst bilgisi olması gibi iletiyle ilgili bir sorun bulabilir. Bu gibi durumlarda uygulama hiçbir zaman iletiyi almaz; ancak ileti yine de zehirli bir ileti haline gelebilir ve el ile işlenebilir.

Zehirli İletileri İşleme

WCF'de zehirli ileti işleme, alıcı uygulamanın uygulamaya gönderilemeyen veya uygulamaya dağıtılan ancak uygulamaya özgü nedenlerden dolayı işlenemeyen iletilerle başa çıkılabilmesi için bir mekanizma sağlar. Kullanılabilir kuyruğa alınan bağlamaların her birinde aşağıdaki özelliklerle zehirli ileti işlemeyi yapılandırın:

  • ReceiveRetryCount. Bir iletinin uygulama kuyruğundan uygulamaya teslimini yeniden deneme sayısı üst sınırını gösteren tamsayı değeri. Varsayılan değer 5'tir. Bu, bir veritabanının geçici kilitlenmesi gibi bir acil yeniden denemenin sorunu düzelttiği durumlarda yeterlidir.

  • MaxRetryCycles. En fazla yeniden deneme döngüsü sayısını gösteren bir tamsayı değeri. Yeniden deneme döngüsü, bir iletinin uygulama kuyruğundan yeniden deneme alt sırasına aktarılmasından ve yapılandırılabilir bir gecikmeden sonra yeniden deneme alt kuyruğundan uygulama kuyruğuna teslimi yeniden değerlendirmeye aktarılmasından oluşur. Varsayılan değer 2'dür. Windows Vista'da ileti en fazla (ReceiveRetryCount +1) * (MaxRetryCycles + 1) kez denenir. MaxRetryCycles , Windows Server 2003 ve Windows XP'de yoksayılır.

  • RetryCycleDelay. Yeniden deneme döngüleri arasındaki gecikme süresi. Varsayılan değer 30 dakikadır. MaxRetryCycles ve RetryCycleDelay birlikte, düzenli bir gecikmeden sonra yeniden denemenin sorunu çözdüğü sorunu gidermek için bir mekanizma sağlar. Örneğin, SQL Server bekleyen işlem işlemesinde kilitli bir satır kümesini işler.

  • ReceiveErrorHandling. Yeniden deneme sayısı üst sınırı denendikten sonra teslimi başarısız olan bir ileti için gerçekleştirilecek eylemi gösteren bir numaralandırma. Değerler Hata, Bırakma, Reddetme ve Taşıma olabilir. Varsayılan seçenek Hata'dır.

  • Hatam. Bu seçenek, hataya neden ServiceHost olan dinleyiciye bir hata gönderir. Uygulamanın kuyruktan gelen iletileri işlemeye devam etmesi için önce iletinin bir dış mekanizma tarafından uygulama kuyruğundan kaldırılması gerekir.

  • Bırak. Bu seçenek zehirli iletiyi bırakır ve ileti hiçbir zaman uygulamaya teslim edilir. İletinin TimeToLive özelliğinin süresi bu noktada dolduysa, ileti gönderenin teslim edilemeyen ileti kuyruğunda görünebilir. Aksi takdirde, ileti hiçbir yerde görünmez. Bu seçenek, ileti kaybolursa kullanıcının ne yapacağını belirtmediğini gösterir.

  • Reddetmek. Bu seçenek yalnızca Windows Vista'da kullanılabilir. Bu, Message Queuing'e (MSMQ) gönderen kuyruk yöneticisine uygulamanın iletiyi alamayacağına ilişkin olumsuz bir bildirim göndermesini ister. İleti, gönderen kuyruk yöneticisinin teslim edilemeyen ileti kuyruğuna yerleştirilir.

  • Hareket. Bu seçenek yalnızca Windows Vista'da kullanılabilir. Bu, zehirli ileti işleme uygulaması tarafından daha sonra işlenmek üzere zehirli ileti kuyruğuna taşır. Zehirli ileti kuyruğu, uygulama kuyruğunun bir alt sırasıdır. Zehirli ileti işleme uygulaması, iletileri zehir kuyruğundan okuyan bir WCF hizmeti olabilir. Zehir kuyruğu, uygulama kuyruğunun bir alt sırasıdır ve net.msmq://<machine-name>/applicationQueue olarak adreslenebilir; zehir; burada makine-adı kuyruğun bulunduğu bilgisayarın adı, applicationQueue ise uygulamaya özgü kuyruğun adıdır.

İleti için yapılan en fazla teslim denemesi sayısı aşağıdadır:

  • Windows Vista üzerinde ((ReceiveRetryCount+1) * (MaxRetryCycles + 1)) .

  • Windows Server 2003 ve Windows XP'de (ReceiveRetryCount + 1).

Not

Başarıyla teslim edilen bir ileti için yeniden deneme yapılmaz.

Bir iletinin kaç kez okunmaya çalışıldığını izlemek için Windows Vista, durdurma sayısını sayan dayanıklı bir ileti özelliğini ve iletinin uygulama kuyruğu ile alt sıralar arasında kaç kez taşındığını sayan bir taşıma sayısı özelliğini korur. WCF kanalı, alma yeniden deneme sayısını ve yeniden deneme döngüleri sayısını hesaplamak için bunları kullanır. Windows Server 2003 ve Windows XP'de durdurma sayısı WCF kanalı tarafından bellekte tutulur ve uygulama başarısız olursa sıfırlanır. Ayrıca WCF kanalı, bellekte istediğiniz zaman en fazla 256 ileti için iptal sayılarını tutabilir. 257. ileti okunursa, en eski iletinin iptal sayısı sıfırlanır.

İptal sayısı ve taşıma sayısı özellikleri, işlem bağlamı aracılığıyla hizmet işlemi için kullanılabilir. Aşağıdaki kod örneği, bunlara nasıl erişeceklerini gösterir.

MsmqMessageProperty mqProp = OperationContext.Current.IncomingMessageProperties[MsmqMessageProperty.Name] as MsmqMessageProperty;
Console.WriteLine("Abort count: {0} ", mqProp.AbortCount);
Console.WriteLine("Move count: {0} ", mqProp.MoveCount);
// code to submit purchase order ...

WCF iki standart kuyruğa alınmış bağlama sağlar:

  • NetMsmqBinding. Diğer WCF uç noktalarıyla kuyruk tabanlı iletişim gerçekleştirmek için uygun bir .NET Framework bağlaması.

  • MsmqIntegrationBinding. Mevcut Message Queuing uygulamalarıyla iletişim kurmaya uygun bir bağlama.

Not

Bu bağlamalardaki özellikleri WCF hizmetinizin gereksinimlerine göre değiştirebilirsiniz. Zehirli ileti işleme mekanizmasının tamamı, alıcı uygulama için yereldir. Alıcı uygulama nihai olarak durdurulup gönderene geri negatif bir onay göndermediği sürece işlem gönderen uygulama tarafından görünmez. Bu durumda, ileti gönderenin teslim edilemeyen ileti kuyruğuna taşınır.

En İyi Yöntem: MsmqPoisonMessageException İşleme

Hizmet bir iletinin zehirli olduğunu belirlediğinde, kuyruğa alınan aktarım zehir iletisini içeren LookupId bir MsmqPoisonMessageException oluşturur.

Alıcı bir uygulama, uygulamanın gerektirdiği hataları işlemek için arabirimini uygulayabilir IErrorHandler . Daha fazla bilgi için bkz . Hata İşleme ve Raporlama Üzerinde Denetimi Genişletme.

Uygulama, hizmetin kuyruktaki iletilerin geri kalanına erişebilmesi için zehirli iletileri zehirli ileti kuyruğuna taşıyan bir tür otomatik işleme gerektirebilir. Zehirli ileti özel durumlarını dinlemek için hata işleyici mekanizmasını kullanmanın tek senaryosu, ayarın ReceiveErrorHandling olarak Faultayarlandığı durumlardır. Message Queuing 3.0 için zehirli ileti örneği bu davranışı gösterir. Aşağıda, en iyi yöntemler de dahil olmak üzere zehirli iletileri işlemek için atılması gereken adımlar özetlenmektedir:

  1. Zehir ayarlarınızın uygulamanızın gereksinimlerini yansıtdığından emin olun. Ayarlarla çalışırken Windows Vista, Windows Server 2003 ve Windows XP'de Message Queuing'in özellikleri arasındaki farkları anladığınızdan emin olun.

  2. Gerekirse, zehirli ileti hatalarını işlemek için uygulamasını IErrorHandler uygulayın. ayarıReceiveErrorHandling, zehirli iletiyi kuyruk dışına taşımak veya dış bağımlı bir sorunu düzeltmek için el ile bir mekanizma gerektirdiğinden, tipik kullanım aşağıdaki kodda gösterildiği gibi olarak olarak ayarlandığında Faultuygulamaktır IErrorHandlerReceiveErrorHandling.Fault

    class PoisonErrorHandler : IErrorHandler
    {
        public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {
            // No-op -We are not interested in this. This is only useful if you want to send back a fault on the wire…not applicable for queues [one-way].
        }
    
        public bool HandleError(Exception error)
        {
            if (error != null && error.GetType() == typeof(MsmqPoisonMessageException))
            {
                Console.WriteLine(" Poisoned message -message look up id = {0}", ((MsmqPoisonMessageException)error).MessageLookupId);
                return true;
            }
    
            return false;
        }
    }
    
  3. Hizmet davranışının kullanabileceği bir PoisonBehaviorAttribute oluşturun. Davranış, dağıtıcıya yükler IErrorHandler . Aşağıdaki kod örneğine bakın.

    public class PoisonErrorBehaviorAttribute : Attribute, IServiceBehavior
    {
        Type errorHandlerType;
    
        public PoisonErrorBehaviorAttribute(Type errorHandlerType)
        {
            this.errorHandlerType = errorHandlerType;
        }
    
        void IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
        {
        }
    
        void IServiceBehavior.AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
        {
        }
    
        void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
        {
            IErrorHandler errorHandler;
    
            try
            {
                errorHandler = (IErrorHandler)Activator.CreateInstance(errorHandlerType);
            }
            catch (MissingMethodException e)
            {
                throw new ArgumentException("The errorHandlerType specified in the PoisonErrorBehaviorAttribute constructor must have a public empty constructor", e);
            }
            catch (InvalidCastException e)
            {
                throw new ArgumentException("The errorHandlerType specified in the PoisonErrorBehaviorAttribute constructor must implement System.ServiceModel.Dispatcher.IErrorHandler", e);
            }
    
            foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
            {
                ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
                channelDispatcher.ErrorHandlers.Add(errorHandler);
            }
        }
    }
    
  4. Hizmetinize zehir davranışı özniteliğiyle ek açıklama eklendiğinden emin olun.

Buna ek olarak, olarak ayarlanırsa ReceiveErrorHandlingFault, ServiceHost zehir iletisiyle karşılaşıldığında oluşan hatalar. Hatalı olaya bağlanıp hizmeti kapatabilir, düzeltici eylemler gerçekleştirebilir ve yeniden başlatabilirsiniz. Örneğin, LookupId 'a IErrorHandler yayılan içindeki MsmqPoisonMessageException not edilebilir ve hizmet konak hataları olduğunda, api'yi kullanarak System.MessagingLookupId iletiyi kuyruktan alıp iletiyi kuyruktan kaldırabilir ve iletiyi bir dış depoda veya başka bir kuyrukta depolayabilirsiniz. Ardından normal işlemeye devam etmek için yeniden başlatabilirsiniz ServiceHost . MSMQ 4.0'daki Zehirli İleti İşleme bu davranışı gösterir.

İşlem Zaman Aşımı ve Zehirli İletiler

Kuyruğa alınan aktarım kanalı ile kullanıcı kodu arasında bir hata sınıfı oluşabilir. Bu hatalar, ileti güvenlik katmanı veya hizmet dağıtım mantığı gibi aradaki katmanlar tarafından algılanabilir. Örneğin, SOAP güvenlik katmanında eksik bir X.509 sertifikası algılandı ve eksik bir eylem, iletinin uygulamaya gönderildiği durumlardır. Bu durumda hizmet modeli iletiyi bırakır. İleti bir işlemde okunduğu ve bu işlem için bir sonuç sağlanamadığı için işlem zaman aşımına uysa, iptal edilir ve ileti kuyruğa geri alınır. Başka bir deyişle, belirli bir hata sınıfı için işlem hemen durdurulmuyor ancak işlem zaman aşımına uğrana kadar bekliyor. kullanarak ServiceBehaviorAttributebir hizmet için işlem zaman aşımını değiştirebilirsiniz.

İşlem zaman aşımını bilgisayar genelinde değiştirmek için machine.config dosyasını değiştirin ve uygun işlem zaman aşımını ayarlayın. İşlemde ayarlanan zaman aşımına bağlı olarak işlemin sonunda durdurulduğunu ve kuyruğa geri döndüğünü ve iptal sayısının artırıldığını unutmayın. Sonunda, ileti zehirlenir ve kullanıcı ayarlarına göre doğru değerlendirme yapılır.

Oturumlar ve Zehirli İletiler

Oturum, tek bir iletiyle aynı yeniden deneme ve zehirli ileti işleme yordamlarından geçer. Daha önce zehirli iletiler için listelenen özellikler tüm oturum için geçerlidir. Bu, oturumun tamamının yeniden denendiği ve ileti reddedilirse son zehirli ileti kuyruğuna veya gönderenin teslim edilemeyen ileti kuyruğuna gittiği anlamına gelir.

Toplu İşlem ve Zehirli İletiler

İleti zehirli bir iletiye dönüşürse ve bir toplu işlemin parçasıysa, toplu iş geri alınır ve kanal her seferinde bir iletiyi okumaya döner. Toplu işlem hakkında daha fazla bilgi için bkz. İşlemde İletileri Toplu İşle

Zehirli Kuyruktaki İletiler için Zehirli İleti İşleme

Zehirli ileti işleme, bir ileti zehirli ileti kuyruğuna yerleştirildiğinde sona ermez. Zehirli ileti kuyruğundaki iletiler hala okunmalı ve işlenmelidir. Son zehir alt sırasındaki iletileri okurken zehirli ileti işleme ayarlarının bir alt kümesini kullanabilirsiniz. Geçerli ayarlar ve ReceiveErrorHandlingşeklindedirReceiveRetryCount. Bırakma, Reddetme veya Hata olarak ayarlayabilirsiniz ReceiveErrorHandling . MaxRetryCycles yoksayılır ve Taşı olarak ayarlanırsa ReceiveErrorHandling bir özel durum oluşturulur.

Windows Vista, Windows Server 2003 ve Windows XP Farkları

Daha önce belirtildiği gibi, tüm zehirli ileti işleme ayarları Windows Server 2003 ve Windows XP için geçerli değildir. Windows Server 2003, Windows XP ve Windows Vista'da Message Queuing arasındaki aşağıdaki önemli farklar zehirli ileti işlemeyle ilgilidir:

  • Windows Vista'da Message Queuing alt sıraları desteklerken, Windows Server 2003 ve Windows XP alt sorguları desteklemez. Alt sıralar, zehirli ileti işlemede kullanılır. Yeniden deneme kuyrukları ve zehir kuyruğu, zehirli ileti işleme ayarlarına göre oluşturulan uygulama kuyruğunun alt sıralarıdır. , MaxRetryCycles oluşturulacak yeniden deneme alt sıralarının sayısını belirler. Bu nedenle, Windows Server 2003 veya Windows XP'de MaxRetryCycles çalışırken yoksayılır ve ReceiveErrorHandling.Move izin verilmez.

  • Windows Vista'da Message Queuing olumsuz bildirimi desteklerken, Windows Server 2003 ve Windows XP desteklemez. Alıcı kuyruk yöneticisinden gelen olumsuz bir bildirim, gönderen kuyruk yöneticisinin reddedilen iletiyi teslim edilemeyen ileti kuyruğuna yerleştirmesine neden olur. Bu nedenle, ReceiveErrorHandling.Reject Windows Server 2003 ve Windows XP ile birlikte kullanılamaz.

  • Windows Vista'da Message Queuing, ileti teslimi deneme sayısını tutan bir ileti özelliğini destekler. Bu iptal sayısı özelliği Windows Server 2003 ve Windows XP'de kullanılamaz. WCF, bellekteki durdurma sayısını korur, bu nedenle aynı ileti bir grup içindeki birden fazla WCF hizmeti tarafından okunduğunda bu özelliğin doğru bir değer içermemesi mümkündür.

Ayrıca bkz.