Řešení potíží – korelace
Korelace se používá k vzájemnému propojení zpráv služby pracovního postupu a správné instance pracovního postupu, ale pokud není správně nakonfigurovaná, zprávy nebudou přijaty a aplikace nebudou správně fungovat. Toto téma obsahuje přehled několika metod pro řešení potíží s korelací a také seznam některých běžných problémů, ke kterým může dojít při použití korelace.
Zpracování události UnknownMessageReceived
K UnknownMessageReceived události dojde, když služba obdrží neznámou zprávu, včetně zpráv, které nelze korelovat s existující instancí. U místních služeb lze tuto událost zpracovat v hostitelské aplikaci.
host.UnknownMessageReceived += delegate(object sender, UnknownMessageReceivedEventArgs e)
{
Console.WriteLine("Unknown Message Received:");
Console.WriteLine(e.Message);
};
U služeb hostovaných na webu lze tuto událost zpracovat odvozením třídy z WorkflowServiceHostFactory a přepsáním CreateWorkflowServiceHost.
class CustomFactory : WorkflowServiceHostFactory
{
protected override WorkflowServiceHost CreateWorkflowServiceHost(Activity activity, Uri[] baseAddresses)
{
// Create the WorkflowServiceHost.
WorkflowServiceHost host = new WorkflowServiceHost(activity, baseAddresses);
// Handle the UnknownMessageReceived event.
host.UnknownMessageReceived += delegate(object sender, UnknownMessageReceivedEventArgs e)
{
Console.WriteLine("Unknown Message Received:");
Console.WriteLine(e.Message);
};
return host;
}
}
Tento vlastní WorkflowServiceHostFactory je pak možné zadat v svc
souboru pro službu.
<% @ServiceHost Language="C#" Service="OrderServiceWorkflow" Factory="CustomFactory" %>
Při vyvolání této obslužné rutiny lze zprávu načíst pomocí Message vlastnosti UnknownMessageReceivedEventArgsa bude vypadat podobně jako následující zpráva.
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://localhost:8080/OrderService</To>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IService/AddItem</Action>
</s:Header>
<s:Body>
<AddItem xmlns="http://tempuri.org/">
<Item>Books</Item>
</AddItem>
</s:Body>
</s:Envelope>
Kontrola zpráv odeslaných do UnknownMessageReceived obslužné rutiny může poskytnout vodítko o tom, proč zpráva nekorelovala s instancí služby pracovního postupu.
Monitorování průběhu pracovního postupu pomocí sledování
Sledování poskytuje způsob, jak monitorovat průběh pracovního postupu. Ve výchozím nastavení se záznamy sledování generují pro události životního cyklu pracovního postupu, události životního cyklu aktivit, šíření chyb a obnovení záložek. Vlastní záznamy sledování navíc můžou být generovány vlastními aktivitami. Při řešení potíží s korelací jsou nejužitečnější záznamy sledování aktivit, záznamy o obnovení záložky a záznamy šíření chyb. Záznamy sledování aktivit se dají použít k určení aktuálního průběhu pracovního postupu a můžou pomoct určit, která aktivita zasílání zpráv aktuálně čeká na zprávy. Záznamy obnovení záložek jsou užitečné, protože indikují, že pracovní postup přijal zprávu, a záznamy o šíření chyb poskytují záznam o všech chybách v pracovním postupu. Pokud chcete povolit sledování, zadejte požadovanou TrackingParticipant hodnotu v parametru WorkflowExtensionsWorkflowServiceHost. V následujícím příkladu ConsoleTrackingParticipant
se (z ukázky vlastního sledování ) nakonfiguruje pomocí výchozího sledovacího profilu.
host.WorkflowExtensions.Add(new ConsoleTrackingParticipant());
Účastník sledování, jako je ConsoleTrackingParticipant, je užitečný pro místní služby pracovního postupu, které mají okno konzoly. U služby hostované na webu by měl být použit účastník sledování, který protokoluje informace o sledování do odolného úložiště, jako je předdefinovaný EtwTrackingParticipantnebo vlastní účastník sledování, který tyto informace protokoluje do souboru.
Další informace o sledování a konfiguraci sledování pro službu pracovních postupů hostovaných na webu najdete v tématech Sledování a trasování pracovních postupů, Konfigurace sledování pro pracovní postup a Ukázky sledování [ukázek WF].
Použití trasování WCF
Trasování WCF poskytuje trasování toku zpráv do a z služby pracovního postupu. Tyto informace o trasování jsou užitečné při řešení potíží s korelací, zejména u korelace na základě obsahu. Pokud chcete povolit trasování, zadejte požadované naslouchací web.config
procesy trasování v system.diagnostics
části souboru, pokud je služba pracovního postupu hostovaná na webu, nebo app.config
soubor, pokud je služba pracovního postupu hostovaná v místním prostředí. Chcete-li zahrnout obsah zpráv do trasovacího souboru, zadejte true
pro logEntireMessage
v elementu messageLogging
diagnostics
v části .system.serviceModel
V následujícím příkladu jsou informace trasování, včetně obsahu zpráv, nakonfigurovány tak, aby byly zapsány do souboru s názvem service.svclog
.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Information" propagateActivity="true">
<listeners>
<add name="corr"/>
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="corr"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add name="corr" type="System.Diagnostics.XmlWriterTraceListener" initializeData="c:\logs\service.svclog">
</add>
</sharedListeners>
</system.diagnostics>
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="false"
logMessagesAtServiceLevel="false" logMessagesAtTransportLevel="true" maxSizeOfMessageToLog="2147483647">
</messageLogging>
</diagnostics>
</system.serviceModel>
</configuration>
K zobrazení informací o trasování obsažených v service.svclog
nástroji Service Trace Viewer (SvcTraceViewer.exe) se používá. To je užitečné zejména při řešení potíží s korelací na základě obsahu, protože můžete zobrazit obsah zprávy a přesně zjistit, co se předává a jestli odpovídá CorrelationQuery korelaci založené na obsahu. Další informace o trasování WCF najdete v tématech Nástroj prohlížeče trasování služby (SvcTraceViewer.exe),Konfigurace trasování a Řešení potíží s aplikací pomocí trasování.
Běžné problémy s korelací výměny kontextu
Určité typy korelace vyžadují, aby se ke správnému fungování korelace použil určitý typ vazby. Mezi příklady patří korelace požadavek-odpověď, která vyžaduje obousměrnou vazbu, jako BasicHttpBindingje , a korelaci výměny kontextu, která vyžaduje kontextovou vazbu, například BasicHttpContextBinding. Většina vazeb podporuje obousměrné operace, takže se nejedná o běžný problém korelace požadavek-odpověď, ale existuje pouze několik kontextových vazeb, včetně BasicHttpContextBinding, WSHttpContextBindinga NetTcpContextBinding. Pokud se některá z těchto vazeb nepoužije, počáteční volání služby pracovního postupu bude úspěšné, ale následná volání selžou s následujícím FaultExceptionpříkazem .
There is no context attached to the incoming message for the service
and the current operation is not marked with "CanCreateInstance = true".
In order to communicate with this service check whether the incoming binding
supports the context protocol and has a valid context initialized.
Kontextové informace, které se používají pro korelaci kontextu, mohou být vráceny aktivitou SendReplyReceive , která inicializuje kontextovou korelaci při použití obousměrné operace, nebo může být určena volajícím, pokud je operace jednosměrná. Pokud volající kontext neodesílají nebo nevrátí služba pracovního postupu, vrátí se při vyvolání další operace totéž, co FaultException bylo popsáno dříve.
Běžné problémy s korelací Request-Reply
Korelace žádosti a odpovědi se používá s dvojicí Receive/SendReply k implementaci obousměrné operace ve službě pracovního postupu a s párem Send/ReceiveReply , který vyvolá obousměrnou operaci v jiné webové službě. Při vyvolání obousměrné operace ve službě WCF může být služba buď tradiční imperativní služba WCF založená na kódu, nebo může být službou pracovního postupu. Pokud chcete použít korelaci požadavek-odpověď, musí být použita obousměrná vazba, například BasicHttpBinding, a operace musí být obousměrné.
Pokud má služba pracovního postupu obousměrné operace paralelně nebo se překrývají Receive/SendReply neboReceiveReplySend/páry, nemusí být správa popisovačů implicitní korelace poskytovaná službou dostatečná, zejména ve scénářích s vysokým zatíženímWorkflowServiceHost, a zprávy nemusí být správně směrovány. Pokud chcete tomuto problému zabránit, doporučujeme při použití korelace požadavek-odpověď vždy explicitně zadat CorrelationHandle . Při použití šablon SendAndReceiveReply a ReceiveAndSendReply z části Zasílání zpráv v sadě nástrojů v návrháři CorrelationHandle pracovního postupu je explicitně nakonfigurovaný ve výchozím nastavení. Při vytváření pracovního postupu pomocí kódu CorrelationHandle je zadána v CorrelationInitializers první aktivitě v páru. V následujícím příkladu Receive je aktivita nakonfigurována s explicitně CorrelationHandle zadaným v objektu RequestReplyCorrelationInitializer.
Variable<CorrelationHandle> RRHandle = new Variable<CorrelationHandle>();
Receive StartOrder = new Receive
{
CanCreateInstance = true,
ServiceContractName = OrderContractName,
OperationName = "StartOrder",
CorrelationInitializers =
{
new RequestReplyCorrelationInitializer
{
CorrelationHandle = RRHandle
}
}
};
SendReply ReplyToStartOrder = new SendReply
{
Request = StartOrder,
Content = ... // Contains the return value, if any.
};
// Construct a workflow using StartOrder and ReplyToStartOrder.
Trvalost není povolena mezi párem Receive/SendReply nebo párem Send/ReceiveReply . Vytvoří se zóna bez trvalé uchování, která trvá, dokud se nedokončily obě aktivity. Pokud se aktivita, například aktivita zpoždění, nachází v této zóně bez zachování a způsobí, že pracovní postup bude nečinný, pracovní postup se nezachová ani v případě, že je hostitel nakonfigurovaný tak, aby pracovní postupy zůstaly v nečinnosti. Pokud se aktivita, například trvalá aktivita, pokusí explicitně zachovat v zóně bez zachování, vyvolá se závažná výjimka, pracovní postup se přeruší a FaultException volajícímu se vrátí. Závažná zpráva o výjimce je System.InvalidOperationException: Trvalé aktivity nelze obsahovat v blocích trvalosti. Tato výjimka se nevrátí volajícímu, ale je možné ji pozorovat, pokud je povolené sledování. Zpráva pro vrácenou FaultException volajícímu je "Operaci nelze provést, protože WorkflowInstance '5836145b-7da2-49d0-a052-a49162adeab6' byla dokončena".
Další informace o korelaci požadavek-odpověď najdete v tématu Žádost-odpověď.
Běžné problémy s korelací obsahu
Korelace založená na obsahu se používá, když služba pracovního postupu přijímá více zpráv a část dat v vyměňovaných zprávách identifikuje požadovanou instanci. Korelace na základě obsahu používá tato data ve zprávě, například číslo zákazníka nebo ID objednávky, ke směrování zpráv do správné instance pracovního postupu. Tato část popisuje několik běžných problémů, ke kterým může dojít při použití korelace založené na obsahu.
Ujistěte se, že identifikace dat je jedinečná.
Data, která se používají k identifikaci instance, se zatřiďují do korelačního klíče. Je třeba věnovat pozornost tomu, aby data použitá pro korelaci byla jedinečná nebo jinak by mohlo dojít ke kolizi v klíči hash a způsobit chybné přesměrování zpráv. Například korelace založená pouze na jménu zákazníka může způsobit kolizi, protože může existovat více zákazníků, kteří mají stejné jméno. Dvojtečka (:) by neměl být použit jako součást dat, která se používají ke korelaci zprávy, protože se již používají k oddělení klíče a hodnoty dotazu na zprávu k vytvoření řetězce, který je následně hashován. Pokud se používá trvalost, ujistěte se, že dříve trvalá instance nepoužila aktuální identifikační data. S identifikací tohoto problému může pomoct dočasné zakázání trvalosti. Trasování WCF lze použít k zobrazení počítaného korelačního klíče a je užitečné pro ladění tohoto typu problému.
Konflikty časování
Mezi službou přijímající zprávu a skutečně inicializovanou korelací je malá časová prodleva, během které se budou následné zprávy ignorovat. Pokud služba pracovního postupu inicializuje korelaci založenou na obsahu pomocí dat předaných z klienta při jednosměrné operaci a volající odešle okamžitě následné zprávy, budou tyto zprávy během tohoto intervalu ignorovány. Tomu se můžete vyhnout pomocí obousměrné operace k inicializaci korelace nebo pomocí TransactedReceiveScope.
Problémy s korelačním dotazem
Korelační dotazy slouží k určení, která data ve zprávě se použijí ke korelaci zprávy. Tato data jsou určena pomocí dotazu XPath. Pokud se zprávy do služby neodesílají, i když se zdá, že je vše v pořádku, je jednou ze strategií řešení potíží zadání hodnoty literálu, která odpovídá hodnotě dat zprávy místo dotazu XPath. Pokud chcete zadat hodnotu literálu string
, použijte funkci . V následujícím příkladu MessageQuerySet je nakonfigurovaná hodnota literálu 11445
pro OrderId
a dotaz XPath je zakomentován.
MessageQuerySet = new MessageQuerySet
{
{
"OrderId",
//new XPathMessageQuery("sm:body()/tempuri:StartOrderResponse/tempuri:OrderId")
new XPathMessageQuery("string('11445')")
}
}
Pokud je dotaz XPath nakonfigurován nesprávně tak, že nejsou načtena žádná data korelace, vrátí se chyba s následující zprávou: "Korelační dotaz přinesl prázdnou sadu výsledků. Ujistěte se, že jsou správně nakonfigurované korelační dotazy pro koncový bod. Jedním z rychlých způsobů, jak tento problém vyřešit, je nahradit dotaz XPath hodnotou literálu, jak je popsáno v předchozí části. K tomuto problému může dojít, pokud použijete tvůrce dotazů XPath v dialogových oknech Přidat inicializátory korelace nebo KorelaceNa definici a služba pracovního postupu používá kontrakty zpráv. V následujícím příkladu je definována třída kontraktu zpráv.
[MessageContract]
public class AddItemMessage
{
[MessageHeader]
public string CartId;
[MessageBodyMember]
public string Item;
}
Tento kontrakt zprávy je používán aktivitou Receive v pracovním postupu. V CartId
záhlaví zprávy se používá ke korelaci zprávy se správnou instancí. Pokud je dotaz XPath, který načte CartId
, vytvořen pomocí dialogových oken korelace v návrháři pracovního postupu, vygeneruje se následující nesprávný dotaz XPath.
sm:body()/xg0:AddItemMessage/xg0:CartId
Tento dotaz XPath by byl správný, pokud Receive aktivita používala parametry pro data, ale protože používá kontrakt zpráv, je nesprávný. Následující dotaz XPath je správný dotaz XPath pro načtení CartId
z hlavičky.
sm:header()/tempuri:CartId
To lze potvrdit prozkoumáním textu zprávy.
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IService/AddItem</Action>
<h:CartId xmlns:h="http://tempuri.org/">80c95b41-c98d-4660-a6c1-99412206e54c</h:CartId>
</s:Header>
<s:Body>
<AddItemMessage xmlns="http://tempuri.org/">
<Item>Books</Item>
</AddItemMessage>
</s:Body>
</s:Envelope>
Následující příklad ukazuje aktivitu nakonfigurovanou ReceiveAddItem
pro operaci, která k příjmu dat používá předchozí kontrakt zprávy. Dotaz XPath je správně nakonfigurovaný.
<Receive CorrelatesWith="[CCHandle] OperationName="AddItem" ServiceContractName="p:IService">
<Receive.CorrelatesOn>
<XPathMessageQuery x:Key="key1">
<XPathMessageQuery.Namespaces>
<ssx:XPathMessageContextMarkup>
<x:String x:Key="xg0">http://schemas.datacontract.org/2004/07/MessageContractWFService</x:String>
</ssx:XPathMessageContextMarkup>
</XPathMessageQuery.Namespaces>sm:header()/tempuri:CartId</XPathMessageQuery>
</Receive.CorrelatesOn>
<ReceiveMessageContent DeclaredMessageType="m:AddItemMessage">
<p1:OutArgument x:TypeArguments="m:AddItemMessage">[AddItemMessage]</p1:OutArgument>
</ReceiveMessageContent>
</Receive>