Delen via


Procedure: Foutafhandeling

In dit onderwerp worden de basisstappen beschreven die nodig zijn voor het maken van een routeringsconfiguratie die gebruikmaakt van foutafhandeling. In dit voorbeeld worden berichten doorgestuurd naar een doeleindpunt. Als een bericht niet kan worden bezorgd vanwege een netwerk- of communicatiegerelateerde fout (CommunicationException), wordt het bericht opnieuw verzonden naar een alternatief eindpunt.

Notitie

Als u een netwerkfout wilt simuleren, bevat het doeleindpunt dat in dit voorbeeld wordt gebruikt een onjuist adres. Berichten die naar dit eindpunt worden doorgestuurd, mislukken omdat er geen service luistert op het opgegeven adres.

Notitie

Hoewel in het voorbeeld in dit onderwerp niet expliciet time-outinstellingen worden besproken, moet u rekening houden met deze instellingen bij het gebruik van foutafhandeling. Wanneer er fouten optreden, is er een extra vertraging opgetreden voordat de client een antwoord ontvangt. Dit komt doordat de fout wordt ontvangen bij de routeringsservice, die vervolgens probeert het bericht naar een back-upeindpunt te verzenden. Als de time-outwaarden die zijn gekoppeld aan de primaire en back-upbestemmingseindpunten groot zijn, kan de client een lange vertraging ondervinden wanneer het bericht een failover van meerdere eindpunten in de back-uplijst uitvoert voordat het wordt verzonden.

Omdat de routeringsservice een maximale vertraging kan ondervinden die gelijk is aan de som van de time-outwaarde voor alle eindpunten die zijn gekoppeld aan een filter, raden we u aan de verwachte time-out bij de client dienovereenkomstig te verhogen.

Foutafhandeling implementeren

  1. Maak de basisconfiguratie van de routeringsservice door het service-eindpunt op te geven dat door de service wordt weergegeven. In het volgende voorbeeld wordt één service-eindpunt gedefinieerd, dat wordt gebruikt voor het ontvangen van berichten. Het definieert ook de clienteindpunten die worden gebruikt voor het verzenden van berichten; deadDestination en realDestination. Het deadDestination-eindpunt bevat een adres dat niet verwijst naar een actieve service en wordt gebruikt om een netwerkfout te simuleren bij het verzenden van berichten naar dit eindpunt.

    <services>
      <service behaviorConfiguration="routingConfiguration"
               name="System.ServiceModel.Routing.RoutingService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost/routingservice/" />
          </baseAddresses>
        </host>
        <!-- Create the Routing Service endpoint -->
        <endpoint address="router"
                  binding="basicHttpBinding"
                  name="RoutingServiceEndpoint"
                  contract="System.ServiceModel.Routing.IRequestReplyRouter" />
      </service>
    </services>
    
    <!-- Create the destination endpoints that we want to send to -->
    <client>
      <!-- Create a dummy endpoint that we know will be down -->
      <endpoint name="deadDestination"
                address="net.tcp://localhost:9090/servicemodelsamples/fakeDestination"
                binding="netTcpBinding"
                contract="*" />
    
      <!-- Now create the real service endpoint -->
      <endpoint name="realDestination"
                address="net.tcp://localhost:8080/servicemodelsamples/service"
                binding="netTcpBinding"
                contract="*" />
    </client>
    
  2. Definieer de filters die worden gebruikt om berichten naar de doeleindpunten te routeren. In dit voorbeeld wordt een MatchAll-filter gebruikt om alle berichten te vinden die door de routeringsservice worden ontvangen.

    <filters>
      <!-- Create a MatchAll filter which will catch all messages -->
      <filter name="MatchAllFilter1" filterType="MatchAll" />
    </filters>
    
  3. Definieer de lijst met back-upeindpunten, die de eindpunten bevat waarnaar een bericht wordt verzonden in het geval van een netwerk- of communicatiefout bij het verzenden naar het primaire doeleindpunt. In het volgende voorbeeld wordt een back-uplijst gedefinieerd die één eindpunt bevat; Er kunnen echter meerdere eindpunten worden opgegeven in een back-uplijst.

    Als de back-uplijst meerdere eindpunten bevat, probeert de routeringsservice het bericht naar het eerste eindpunt in de lijst te verzenden wanneer er een netwerk- of communicatiefout optreedt. Als er een netwerk- of communicatiefout optreedt bij het verzenden naar dit eindpunt, probeert de routeringsservice het bericht te verzenden naar het volgende eindpunt in de lijst. De service blijft het bericht verzenden naar elk eindpunt in de lijst met back-upeindpunten totdat het bericht is verzonden, alle back-upeindpunten retourneren een netwerk- of communicatiegerelateerde fout, of het bericht wordt verzonden en het eindpunt retourneert een niet-netwerkfout, niet-communicatiegerelateerde fout.

    <backupLists>
      <backupList name="backupEndpointList">
          <add endpointName="realDestination" />
      </backupList>
    </backupLists>
    
  4. Definieer de filtertabel, die het filter koppelt aan het deadDestination-eindpunt en de lijst met back-upeindpunten. De routeringsservice probeert het bericht eerst te verzenden naar het doeleindpunt dat is gekoppeld aan het filter. Omdat de deadDestination een adres bevat dat niet verwijst naar een actieve service, resulteert dit in een netwerkfout. De routeringsservice probeert vervolgens het bericht te verzenden naar het eindpunt dat is opgegeven in de backupEndpointList.

    <filterTables>
            <!-- Set up the Routing Service's Message Filter Table -->
            <filterTable name="filterTable1">
                <!-- Add an entity that maps the MatchAllMessageFilter to the dead destination -->
                <!-- If that endpoint is down, tell the Routing Service to try the endpoints -->
                <!-- Listed in the backupEndpointList -->
                <add filterName="MatchAllFilter1" endpointName="deadDestination" backupList="backupEndpointList"/>
            </filterTable>
          </filterTables>
    
  5. Als u binnenkomende berichten wilt evalueren op basis van het filter in de filtertabel, moet u de filtertabel koppelen aan de service-eindpunten met behulp van het routeringsgedrag. In het volgende voorbeeld ziet u hoe u filterTable1 aan de service-eindpunten kunt koppelen.

    <behaviors>
      <serviceBehaviors>
        <!-- Set up the Routing Behavior -->
        <behavior name="routingConfiguration">
          <routing filterTableName="filterTable1" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    

Opmerking

Hier volgt een volledige lijst van het configuratiebestand:

<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright (c) Microsoft Corporation.  All Rights Reserved. -->
<configuration>
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="routingConfiguration"
               name="System.ServiceModel.Routing.RoutingService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost/routingservice/" />
          </baseAddresses>
        </host>
        <!-- Create the Routing Service endpoint -->
        <endpoint address="router"
                  binding="basicHttpBinding"
                  name="RoutingServiceEndpoint"
                  contract="System.ServiceModel.Routing.IRequestReplyRouter" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <!-- Set up the Routing Behavior -->
        <behavior name="routingConfiguration">
          <routing filterTableName="filterTable1" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <!-- Create the destination endpoints that we want to send to -->
    <client>
      <!-- Create a dummy endpoint that we know will be down -->
      <endpoint name="deadDestination"
                address="net.tcp://localhost:9090/servicemodelsamples/fakeDestination"
                binding="netTcpBinding"
                contract="*" />

      <!-- Now create the real service endpoint -->
      <endpoint name="realDestination"
                address="net.tcp://localhost:8080/servicemodelsamples/service"
                binding="netTcpBinding"
                contract="*" />
    </client>
    <routing>
      <filters>
        <!-- Create a MatchAll filter which will catch all messages -->
        <filter name="MatchAllFilter1" filterType="MatchAll" />
      </filters>
      <filterTables>
        <!-- Set up the Routing Service's Message Filter Table -->
        <filterTable name="filterTable1">
            <!-- Add an entry that maps the MatchAllMessageFilter to the dead destination -->
            <!-- If that endpoint is down, tell the Routing Service to try the endpoints -->
            <!-- Listed in the backupEndpointList -->
            <add filterName="MatchAllFilter1" endpointName="deadDestination" backupList="backupEndpointList"/>
        </filterTable>
      </filterTables>
      <!-- Create the backup endpoint list -->
      <backupLists>
        <backupList name="backupEndpointList">
            <add endpointName="realDestination" />
        </backupList>
      </backupLists>
      </routing>
  </system.serviceModel>
</configuration>