Partilhar via


Como: Tratamento de erros

Este tópico descreve as etapas básicas necessárias para criar uma configuração de roteamento que usa tratamento de erros. Neste exemplo, as mensagens são roteadas para um ponto de extremidade de destino. Se uma mensagem não puder ser entregue devido a uma falha relacionada à rede ou às comunicações (CommunicationException), a mensagem será reenviada para um ponto de extremidade alternativo.

Nota

Para simular uma falha de rede, o ponto de extremidade de destino usado neste exemplo contém um endereço incorreto. As mensagens encaminhadas para este ponto de extremidade falham, pois nenhum serviço está escutando no endereço especificado.

Nota

Embora o exemplo contido neste tópico não discuta explicitamente as configurações de tempo limite, você deve levá-las em consideração ao usar o tratamento de erros. Quando forem encontrados erros, haverá um atraso adicional antes que o cliente receba uma resposta. Isso ocorre porque o erro é recebido no Serviço de Roteamento, que tenta enviar a mensagem para um ponto de extremidade de backup. Se os valores de tempo limite associados aos pontos de extremidade de destino primário e de backup forem grandes, o cliente poderá sofrer um longo atraso, pois a mensagem fará failover em vários pontos de extremidade na lista de backup antes de ser enviada com êxito.

Como o Serviço de Roteamento pode encontrar um atraso máximo igual à soma do valor de tempo limite para todos os pontos de extremidade associados a um filtro, recomendamos que você aumente o tempo limite esperado no cliente de acordo.

Implementar tratamento de erros

  1. Crie a configuração básica do Serviço de Roteamento especificando o ponto de extremidade do serviço exposto pelo serviço. O exemplo a seguir define um único ponto de extremidade de serviço, que é usado para receber mensagens. Ele também define os pontos de extremidade do cliente que são usados para enviar mensagens; deadDestination e realDestination. O ponto de extremidade deadDestination contém um endereço que não faz referência a um serviço em execução e é usado para simular uma falha de rede ao enviar mensagens para esse ponto de extremidade.

    <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. Defina os filtros usados para rotear mensagens para os pontos de extremidade de destino. Neste exemplo, um filtro MatchAll é usado para corresponder a todas as mensagens recebidas pelo Serviço de Roteamento.

    <filters>
      <!-- Create a MatchAll filter which will catch all messages -->
      <filter name="MatchAllFilter1" filterType="MatchAll" />
    </filters>
    
  3. Defina a lista de pontos de extremidade de backup, que contém os pontos de extremidade para os quais uma mensagem é enviada no caso de uma falha de rede ou comunicação ao enviar para o ponto de extremidade de destino principal. O exemplo a seguir define uma lista de backup que contém um ponto de extremidade; no entanto, vários pontos de extremidade podem ser especificados em uma lista de backup.

    Se a lista de backup contiver vários pontos de extremidade, quando ocorrer uma falha de rede ou comunicação, o Serviço de Roteamento tentará enviar a mensagem para o primeiro ponto de extremidade da lista. Se ocorrer uma falha de rede ou de comunicação ao enviar para esse ponto de extremidade, o Serviço de Roteamento tentará enviar a mensagem para o próximo ponto de extremidade contido na lista. O serviço continua enviando a mensagem para cada ponto de extremidade na lista de pontos de extremidade de backup até que a mensagem seja enviada com êxito, todos os pontos de extremidade de backup retornem um erro relacionado à rede ou às comunicações ou a mensagem seja enviada e o ponto de extremidade retorne um erro não relacionado à rede e não relacionado às comunicações.

    <backupLists>
      <backupList name="backupEndpointList">
          <add endpointName="realDestination" />
      </backupList>
    </backupLists>
    
  4. Defina a tabela de filtros, que associa o filtro ao ponto de extremidade deadDestination e à lista de pontos de extremidade de backup. O Serviço de Roteamento primeiro tenta enviar a mensagem para o ponto de extremidade de destino associado ao filtro. Como o deadDestination contém um endereço que não se refere a um serviço em execução, isso resulta em um erro de rede. Em seguida, o Serviço de Roteamento tenta enviar a mensagem para o ponto de extremidade especificado na 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. Para avaliar as mensagens de entrada em relação ao filtro contido na tabela de filtros, você deve associar a tabela de filtros aos pontos de extremidade de serviço usando o comportamento de roteamento. O exemplo a seguir demonstra a associação de "filterTable1" com os pontos de extremidade de serviço.

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

Exemplo

A seguir está uma lista completa do arquivo de configuração:

<?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>