Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Komunikat trucizny to komunikat, który przekroczył maksymalną liczbę prób dostarczenia do aplikacji. Taka sytuacja może wystąpić, gdy aplikacja oparta na kolejce nie może przetworzyć komunikatu z powodu błędów. Aby spełnić wymagania dotyczące niezawodności, aplikacja w kolejce odbiera komunikaty w ramach transakcji. Przerywanie transakcji, w której odebrano komunikat w kolejce, powoduje pozostawienie komunikatu w kolejce, tak aby komunikat został ponowiony w ramach nowej transakcji. Jeśli problem, który spowodował przerwanie transakcji, nie zostanie rozwiązany, aplikacja odbierająca może utknąć w pętli, odbierając i przerywając ten sam komunikat do momentu przekroczenia maksymalnej liczby prób dostarczenia oraz powstania komunikatu trucizny.
Wiadomość może stać się toksyczną wiadomością z wielu powodów. Najczęstsze przyczyny są specyficzne dla aplikacji. Jeśli na przykład aplikacja odczytuje komunikat z kolejki i wykonuje pewne przetwarzanie bazy danych, aplikacja może nie uzyskać blokady bazy danych, powodując przerwanie transakcji. Ponieważ transakcja bazy danych została przerwana, komunikat pozostaje w kolejce, co powoduje ponowne odczytanie komunikatu przez aplikację po raz drugi i podjęcie kolejnej próby uzyskania blokady w bazie danych. Komunikaty mogą również stać się trucizną, jeśli zawierają nieprawidłowe informacje. Na przykład zamówienie zakupu może zawierać nieprawidłowy numer klienta. W takich przypadkach aplikacja może dobrowolnie przerwać transakcję i zmusić komunikat do stania się wiadomością typu 'trucizna'.
W rzadkich przypadkach komunikaty mogą nie być wysyłane do aplikacji. Warstwa programu Windows Communication Foundation (WCF) może napotkać problem z komunikatem, na przykład jeśli komunikat zawiera nieprawidłową ramkę, dołączone nieprawidłowe poświadczenia komunikatu lub nieprawidłowy nagłówek akcji. W takich przypadkach aplikacja nigdy nie odbiera komunikatu; jednak komunikat nadal może stać się komunikatem trucizny i być przetwarzany ręcznie.
Obsługa wiadomości niebezpiecznych
W programie WCF obsługa komunikatów trucizny zapewnia mechanizm odbierania aplikacji do obsługi komunikatów, których nie można wysłać do aplikacji lub komunikatów wysyłanych do aplikacji, ale które nie mogą być przetwarzane z powodu przyczyn specyficznych dla aplikacji. Skonfiguruj obsługę komunikatów trucizny przy użyciu następujących właściwości w każdym z dostępnych powiązań w kolejce:
ReceiveRetryCount. Wartość całkowita wskazująca maksymalną liczbę ponownych prób dostarczenia komunikatu z kolejki aplikacji do aplikacji. Wartość domyślna to 5. Jest to wystarczające w przypadkach, gdy natychmiastowa ponowna próba rozwiąże problem, na przykład w przypadku tymczasowego zakleszczenia w bazie danych.MaxRetryCycles. Wartość całkowita wskazująca maksymalną liczbę cykli ponawiania prób. Cykl ponawiania prób składa się z przesyłania komunikatu z kolejki aplikacji do podkolejki ponawiania, a po skonfigurowanym opóźnieniu, z podkolejki ponawiania z powrotem do kolejki aplikacji w celu ponownego dostarczenia. Wartość domyślna to 2. W systemie Windows Vista komunikat jest wypróbowany maksymalnie (ReceiveRetryCount+1) * (MaxRetryCycles+ 1) razy.MaxRetryCyclesjest ignorowany w systemach Windows Server 2003 i Windows XP.RetryCycleDelay. Opóźnienie czasowe między cyklami ponawiania prób. Wartość domyślna to 30 minut.MaxRetryCyclesiRetryCycleDelayrazem zapewniają mechanizm rozwiązywania problemu polegającego na tym, że ponawianie próby po okresowym opóźnieniu rozwiązuje problem. Na przykład obsługuje zablokowany wiersz ustawiony w oczekującym zatwierdzeniu transakcji programu SQL Server.ReceiveErrorHandling. Wyliczenie wskazujące akcję do wykonania dla komunikatu, który zakończył się niepowodzeniem po próbie maksymalnej liczby ponownych prób. Wartościami mogą być Błędy, Upuść, Odrzuć i Przenieś. Domyślną opcją jest Błąd.Błąd. Ta opcja wysyła usterkę do odbiornika, który spowodował usterkę
ServiceHost. Komunikat musi zostać usunięty z kolejki aplikacji przez jakiś mechanizm zewnętrzny, zanim aplikacja będzie mogła nadal przetwarzać komunikaty z kolejki.Kropla. Ta opcja odrzuca komunikat trucizny, a komunikat nigdy nie jest dostarczany do aplikacji. Jeśli właściwość komunikatu
TimeToLivewygasła w tym momencie, komunikat może pojawić się w kolejce utraconych wiadomości nadawcy. Jeśli tak nie jest, komunikat nie jest wyświetlany nigdzie. Ta opcja wskazuje, że użytkownik nie określił, co zrobić, jeśli komunikat zostanie utracony.Odrzuć. Ta opcja jest dostępna tylko w systemie Windows Vista. Powoduje to, że usługa kolejkowania komunikatów (MSMQ) wysyła negatywną potwierdzenie z powrotem do menedżera kolejki wysyłającej, że aplikacja nie może odebrać komunikatu. Komunikat jest umieszczany w kolejce wiadomości niedostarczonych menedżera kolejki wysyłania.
Ruszaj. Ta opcja jest dostępna tylko w systemie Windows Vista. Spowoduje to przeniesienie komunikatu trucizny do kolejki komunikatów trucizny w celu późniejszego przetworzenia przez aplikację do obsługi komunikatów trucizny. Kolejka komunikatów problemowych jest podkolejką kolejki aplikacji. Aplikacja do obsługi komunikatów trucizny może być usługą WCF, która odczytuje komunikaty z kolejki trucizny. Kolejka trucizny jest kolejką podrzędną kolejki aplikacji i może zostać skierowana jako net.msmq://<nazwa-maszyny>/applicationQueue; trucizna, gdzie nazwa maszyny jest nazwą komputera, na którym znajduje się kolejka, a applicationQueue jest nazwą kolejki specyficznej dla aplikacji.
Poniżej przedstawiono maksymalną liczbę prób dostarczenia dla komunikatu:
((ReceiveRetryCount+1) * (MaxRetryCycles + 1)) w systemie Windows Vista.
(ReceiveRetryCount + 1) w systemach Windows Server 2003 i Windows XP.
Uwaga
Żadne ponowne próby nie są tworzone dla komunikatu, który został pomyślnie dostarczony.
Aby śledzić liczbę prób odczytu komunikatu, system Windows Vista utrzymuje trwałą właściwość wiadomości, która zlicza liczbę przerwań oraz właściwość licznika przeniesień, która zlicza liczbę razy, gdy wiadomość jest przenoszona między kolejką aplikacji a podkolejkami. Kanał WCF używa tych elementów do obliczenia liczby ponownych prób odbierania i liczby cykli ponawiania. W systemach Windows Server 2003 i Windows XP liczba przerwań jest utrzymywana w pamięci przez kanał WCF i jest resetowany, jeśli aplikacja ulegnie awarii. Ponadto kanał WCF może przechowywać liczbę przerwań dla maksymalnie 256 komunikatów w pamięci w dowolnym momencie. Jeśli zostanie odczytana 257. wiadomość, liczba anulowań najstarszej wiadomości zostanie zresetowana.
Właściwości licznika przerwań i licznika przeniesień są dostępne dla operacji serwisowej za pośrednictwem kontekstu operacji. Poniższy przykład kodu pokazuje, jak uzyskać do nich dostęp.
MsmqMessageProperty mqProp = OperationContext.Current.IncomingMessageProperties[MsmqMessageProperty.Name] as MsmqMessageProperty;
Console.WriteLine($"Abort count: {mqProp.AbortCount} ");
Console.WriteLine($"Move count: {mqProp.MoveCount} ");
// code to submit purchase order ...
Program WCF udostępnia dwa standardowe powiązania w kolejce:
NetMsmqBinding. Powiązanie programu .NET Framework odpowiednie do przeprowadzania komunikacji opartej na kolejce z innymi punktami końcowymi programu WCF.
MsmqIntegrationBinding. Powiązanie odpowiednie do komunikowania się z istniejącymi aplikacjami kolejkowania komunikatów.
Uwaga
Właściwości tych powiązań można zmienić na podstawie wymagań usługi WCF. Cały mechanizm obsługi komunikatów trucizny jest lokalny w aplikacji odbierającej. Proces jest niewidoczny dla aplikacji wysyłającej, chyba że aplikacja odbierającego ostatecznie zatrzymuje się i wysyła negatywne potwierdzenie z powrotem do nadawcy. W takim przypadku komunikat jest przenoszony do kolejki utraconych wiadomości nadawcy.
Najlepsze rozwiązanie: obsługa wyjątku MsmqPoisonMessageException
Kiedy usługa ustali, że komunikat jest trucizną, transport w kolejce zgłasza MsmqPoisonMessageException, który zawiera LookupId wiadomości trucizny.
Aplikacja odbierającą może zaimplementować IErrorHandler interfejs, aby obsługiwać wszelkie błędy wymagane przez aplikację. Aby uzyskać więcej informacji, zobacz Rozszerzanie kontroli nad obsługą błędów i raportowaniem.
Aplikacja może wymagać zautomatyzowanego systemu obsługi zatrutych komunikatów, który przenosi te komunikaty do kolejki komunikatów zatrutych, aby usługa mogła uzyskać dostęp do pozostałych komunikatów w kolejce. Jedynym scenariuszem użycia mechanizmu obsługi błędów do nasłuchiwania wyjątków dotyczących komunikatów trujących jest, gdy ustawienie ReceiveErrorHandling jest ustawione na Fault. Przykład komunikatu typu 'poison' dla kolejkowania wiadomości 3.0 demonstruje to zachowanie. Poniżej przedstawiono kroki, które należy wykonać w celu obsługi wiadomości złośliwych, w tym najlepszych praktyk.
Upewnij się, że ustawienia trucizny odzwierciedlają wymagania aplikacji. Podczas pracy z ustawieniami upewnij się, że rozumiesz różnice między możliwościami kolejkowania komunikatów w systemie Windows Vista, Windows Server 2003 i Windows XP.
W razie potrzeby zaimplementuj element
IErrorHandler, aby obsługiwać błędy komunikatów o truciznie. Ponieważ ustawienieReceiveErrorHandlingnaFaultwymaga ręcznego mechanizmu przenoszenia komunikatu trucizny z kolejki lub rozwiązania zewnętrznego problemu zależnego, typowo stosuje sięIErrorHandler, gdyReceiveErrorHandlingjest ustawiona naFault, jak pokazano w poniższym kodzie.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 = {((MsmqPoisonMessageException)error).MessageLookupId}"); return true; } return false; } }Utwórz
PoisonBehaviorAttribute, którego może używać zachowanie usługi. Zachowanie instalujeIErrorHandlerelement na dyspozytorze. Zapoznaj się z poniższym przykładem kodu.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); } } }Upewnij się, że usługa jest oznaczona adnotacją z atrybutem zachowania trucizny.
Ponadto, jeśli ReceiveErrorHandling jest ustawione na Fault, ServiceHost ulega awarii przy napotkaniu komunikatu trucizny. Możesz dołączyć do zdarzenia awaryjnego i zamknąć usługę, podjąć działania naprawcze i ponownie uruchomić. Na przykład można zauważyć, że LookupId w MsmqPoisonMessageException jest propagowane do IErrorHandler, a kiedy wystąpi błąd hosta usługi, można użyć interfejsu API System.Messaging do odebrania komunikatu z kolejki, używając LookupId, aby usunąć komunikat z kolejki i zapisać go w zewnętrznym magazynie danych lub w innej kolejce. Następnie można ponownie uruchomić ServiceHost , aby wznowić normalne przetwarzanie. Obsługa komunikatów pułapki w programie MSMQ 4.0 demonstruje to zachowanie.
Transakcja Time-Out i komunikaty truciznowe
Rodzaj błędów może wystąpić między kolejkowym kanałem transportu a kodem użytkownika. Te błędy można wykryć za pomocą warstw między nimi, takich jak warstwa zabezpieczeń komunikatów lub logika wysyłania usługi. Na przykład brak certyfikatu X.509 wykrytego w warstwie zabezpieczeń protokołu SOAP i brakująca akcja to przypadki, w których komunikat zostanie wysłany do aplikacji. W takim przypadku model usługi pominie komunikat. Ponieważ komunikat jest odczytywany w transakcji i nie można podać wyniku dla tej transakcji, transakcja ostatecznie upływa limit czasu, zostaje przerwana, a komunikat zostaje umieszczony z powrotem w kolejce. Innymi słowy, w przypadku określonej klasy błędów transakcja nie przerywa się natychmiast, ale czeka na limit czasu transakcji. Limit czasu transakcji dla usługi można zmodyfikować przy użyciu polecenia ServiceBehaviorAttribute.
Aby zmienić limit czasu transakcji dla całego komputera, zmodyfikuj plik machine.config i ustaw odpowiedni limit czasu transakcji. Należy pamiętać, że w zależności od limitu czasu ustawionego w transakcji, transakcja ostatecznie zostaje anulowana i wraca do kolejki, a jej liczba anulowań jest zwiększana. W końcu komunikat staje się trujący i jest odpowiednio zarządzany zgodnie z ustawieniami użytkownika.
Sesje i komunikaty zatrute
Sesja podlega tym samym procedurom ponawiania i obsługi komunikatów trucizny, co pojedyncza wiadomość. Właściwości wymienione poprzednio dla wiadomości typu 'trucizna' dotyczą całej sesji. Oznacza to, że cała sesja jest ponawiana i trafia do ostatecznej kolejki zatrutych wiadomości lub kolejki martwych listów nadawcy, jeśli komunikat zostanie odrzucony.
Dzielenie na partie i zatrucie komunikatów
Jeśli wiadomość stanie się wiadomością typu poison i jest częścią partii, cała partia zostanie wycofana, a kanał powróci do odczytu jednej wiadomości naraz. Aby uzyskać więcej informacji na temat dzielenia na partie, zobacz Batching Messages in a Transaction (Przetwarzanie wsadowe komunikatów w transakcji)
Obsługa komunikatów trucizny dla komunikatów w kolejce trucizny
Obsługa komunikatów o truciznie nie kończy się, gdy komunikat zostanie umieszczony w kolejce komunikatów otruciu. Komunikaty w kolejce komunikatów szkodliwych muszą być nadal odczytywane i obsługiwane. Można użyć podzbioru ustawień obsługi wiadomości trucizny podczas odczytywania wiadomości z końcowej podkolejki trucizny. Odpowiednie ustawienia to ReceiveRetryCount i ReceiveErrorHandling. Możesz ustawić ReceiveErrorHandling na "Drop", "Reject" lub "Fault".
MaxRetryCycles jest ignorowane, a wyjątek jest zgłaszany, jeśli ReceiveErrorHandling jest ustawiony na Przenieś.
Różnice między systemami Windows Vista, Windows Server 2003 i Windows XP
Jak wspomniano wcześniej, nie wszystkie ustawienia obsługi komunikatów trucizny dotyczą systemów Windows Server 2003 i Windows XP. Następujące kluczowe różnice między kolejkowaniem komunikatów w systemie Windows Server 2003, Windows XP i Windows Vista są istotne dla obsługi komunikatów trucizny:
Kolejkowanie komunikatów w systemie Windows Vista obsługuje kolejki podrzędne, podczas gdy systemy Windows Server 2003 i Windows XP nie obsługują kolejek podrzędnych. Podkolejki są używane w obsłudze wiadomości-grozy. Kolejki ponowień i kolejki z komunikatami trucizny są kolejkami podrzędnymi kolejki aplikacji, tworzona w oparciu o ustawienia obsługi komunikatów trucizny. Parametr
MaxRetryCyclesokreśla, ile podkolejek ponownych prób należy utworzyć. W związku z tym w przypadku uruchamiania w systemie Windows Server 2003 lub Windows XPMaxRetryCyclessą ignorowane iReceiveErrorHandling.Moveniedozwolone.Kolejkowanie komunikatów w systemie Windows Vista obsługuje potwierdzenie negatywne, podczas gdy systemy Windows Server 2003 i Windows XP nie. Negatywne potwierdzenie od odbierającego menedżera kolejek powoduje, że menedżer kolejek wysyłających umieszcza odrzucony komunikat w kolejce wiadomości niedostarczonych. W związku z tym
ReceiveErrorHandling.Rejectnie jest dozwolone w systemach Windows Server 2003 i Windows XP.Kolejkowanie komunikatów w systemie Windows Vista obsługuje właściwość komunikatu, która utrzymuje liczbę prób dostarczenia komunikatów. Ta właściwość dotycząca liczby przerwań nie jest dostępna w systemach Windows Server 2003 i Windows XP. Program WCF utrzymuje liczbę przerwań w pamięci, więc możliwe, że ta właściwość może nie zawierać dokładnej wartości, gdy ten sam komunikat jest odczytywany przez więcej niż jedną usługę WCF w farmie.