A manipulação de erros em endpoints é uma situação crítica e importante em qualquer publicação da WSO2 Enterprise Service Bus. Neste artigo, Supun Kamburugamuva descreveu como manipular os erros no nível de endpoint.
Nota de tradução: O artigo original foi escrito em inglês e pode ser lido em: WSO2 Enterprise Service Bus – Endpoint Error Handling
WSO2 Enterprise Service Bus – Manipulando erros em endpoints
Conteúdo
Service Provider endpoint: WSO2 Enterprise Service Bus atua como uma central de distribuição, entregando as mensagens recebidas dos clientes aos service provider endpoints.
WSO2 Enterprise Service Bus Endpoint: Esta é a representação do service provider endpoint, omitida internamente na configuração do WSO2 Enterprise Service Bus.
Corporações são complexamente estruturadas e compostas por centenas de aplicações com semânticas completamente diferentes. Algumas dessas aplicações são desenvolvidas personalizadamente, algumas são adquiridas de terceiros e outras podem ser a combinação de ambas; e podem ser operadas em diferentes ambientes e sistemas. Muitas aplicações rodam em diferentes sistemas, o que faz isso ser muito complexo. E devido a esses fatores, isto é vital a integração entre as diferentes aplicações.
O WSO2 Enterprise Service Bus tem a capacidade de prover a tecnologia para integrar essas aplicações, as quais podem ser definidas como o estado da arte para EAI, baseadas nos princípios do SOA. Com a WSO2 Enterprise Service Bus, o processo completo pode ser alcançado pela realização de várias tarefas na mensagem – transformação (transformation), roteamento (routing) e troca de transporte (transport switching) – antes do envio ao service provider.
A configuração no WSO2 Enterprise Service Bus é feita em etapas, são elas:
- Mediators
- Proxy services
- Endpoints
- Tasks
Os Mediators são componentes funcionais dentro do WSO2 Enterprise Service Bus, eles fazem várias coisas como gravação de log (logging), transformação (XSLT transformation), envia mensagens externas, filtros baseados em XPath, etc. Então os mediators são o núcleo da mensagem processada dentro do WSO2 Enterprise Service Bus. A última etapa da mensagem dentro do WSO2 Enterprise Service Bus é o envio da mensagem de resposta para um services provider. Quanto ao WSO2 Enterprise Service Bus é responsável pelo envio da mensagem para um serviço de escuta de endpoint. As mensagens enviadas do WSO2 Enterprise Service Bus podem ser muito diferentes da mensagem recebida. Por exemplo, as mensagens recebidas podem ser SOAP 1.1 over HTTP. Mas WSO2 Enterprise Service Bus pode enviar a mensagem para o serviço como SOAP 1.2 over JMS. Neste caso o endpoint exposto para o cliente é SOAP 1.1 over HTTP, o atual endpoint é SOAP 1.2 over JMS.
Um Endpoint é uma abstração do services provider. Uma vez que a mensagem é enviada usando um Mediator, ele deve saber qual é o endpoint services provider. O Endpoint é capaz de prover essa informação. No cenário ideal o serviço de endpoint aceita requisições de mesmo tipo, WSO2 ESB pode ser usado para balanceamento de carga (Load Balancer). A principal razão por trás disso tudo é que esses endpoints tem mesmas funcionalidades e é natural vê-las como uma coisa só.
WSO2 Enterprise Service Bus tem o conceito de construção de endpoints para representar endpoint services provider. Seguindo os Endpoints construídos sobre o WSO2 Enterprise Service Bus.
- Address Endpoint
- WSDL Endpoint
- Default Endpoint
- Load Balancing Endpoint
- Fail-Over Endpoint
Dos itens mencionados acima, os mais utilizados são o Address e o WSDL Endpoints. Cada Endpoint tem seu próprio XML de configuração, escrito na linguagem Synapse. Synapse é uma linguagem XML usada para configurar a Enterprise Service Bus.
Até o Endpoint enviar a mensagem de resposta, pode encontrar vários erros de transporte. Por exemplo, a conexão pode dar timeout ou pode ser fechada pelo serviço atual.
WSO2 Enterprise Service Bus é uma aplicação de longa duração e nesse tempo falhas podem ocorrer. Retiring on transient failures enhances the fault tolerance of a system. Para a WSO2 Enterprise Service Bus, essas falhas podem ser falha de conexão entre o services provider e a WSO2 Enterprise Service bus, erro em alguma operação do banco de dados e assim por diante, sendo que as falhas de comunicação são mais frequentes.
Então a manipulação de erros é a chave para o sucesso de qualquer publicação na Enterprise Service Bus. Muitas vezes nós utilizamos TCP, as pessoas podem perguntar, como podem ocorrem erros? O protocolo TCP é muito confiável, não é? Mas não na vida real. Mensagens pode falhar ou se perder devido a diversas razões na rede TCP. Esses erros são muito raros, mas podem ocorrer. Para entender a importância da manipulação de erros vamos considerar o seguinte cenário.
Se a WSO2 Enterprise Service Bus não estiver devidamente configurada para aceitar erros, ocasionalmente, quando eles ocorrerem, o Endpoint será marcado com uma falha. Isto leva para uma mensagem de falha. Por padrão, o Endpoint será marcado como falho por um longo tempo. Os erros encontrados na WSO2 Enterprise Service Bus podem ser um problema intermitente que ocorrem uma vez por semana, mas devido a singularidade do erro, mensagens posteriores poderão ser perdidas. Claro que você pode configurar a WSO2 Enterprise Service Bus para manipular estas situações e este artigo dará a você uma maior compreensão sobre como trabalhar com Endpoints e otimizar as suas configurações.
Nós chamamos Address, Default and WSDL Endpoints como Leaf Endpoints, que enviam a mensagem. A Load Balance ou Fail-Over Endpoints usa um ou vários Leaf Endpoints para enviar a mensagem. Então um Load Balance ou Fail-Over Endpoint é um agrupamento lógico de Leaf Endpoints. Um Load Balance ou Fail-Over Endpoint nunca envia uma mensagem diretamente, ao invés de enviar ela delega aos Leaf Endpoints, dependendo da configuração e da situação (status).
Endpoint é uma abstração do servidor remoto, onde o WSO2 Enterprise Service Bus envia a mensagem de saída. Ela pode especificar quais as propriedades usadas para enviar a mensagem, por exemplo, pode especificar o formato – como SOAP 1.1 – ou pode especificar a necessidade de utilizar uma política de segurança com WS Security para responder a mensagem.
WSO2 Enterprise Service Bus Endpoint tem configurações para especificar o comportamento diante de erros, que podem ocorrer entre a WSO2 Enterprise Service Bus e o atual Endpoint.
Um Endpoint tem uma situação, mas antes vamos para as configurações de Endpoint para vermos como as transições acontecem.
Em alguns momentos a situação do Endpoint pode ser Active, Timeout, Suspended ou Off. A situação de transição do Endpoint normalmente acontece na base de mensagens. E para colocarmos uma situação de Off num Endpoint (utilizando para issoJMX), então esta situação não é a Situação do Diagrama de Transição. Vamos analisar as diferentes situações do endpoint em detalhes:
- Active: O endpoint está ativo e funcionando.
- Timeout: Foram encontrados erros no endpoint, que passa a ser um candidato a ser suspenso, mas pode continuar enviando mensagens. Se os erros persisterem o endpoint será suspenso.
- Suspended: Foram encontrados erros no endpoint e é enviado para a situação onde não pode enviar requisições. Ele não pode enviar mensagens e mensagens recebidas por ele resultarão em falhas.
- Off: O endpoint não está ativo.

Toda situação de transição acontece na mensagem. Por exemplo, se a duração da suspensão é expirada, na situação Suspended, o endpoint continuará na situação Suspensed até que uma nova mensagem chegue e seja bem sucedida.
Toda situação de transição acontece na mensagem. Por exemplo, se a duração da suspensão é expirada, na situação Suspended, o endpoint continuará na situação Suspensed até que uma nova mensagem chegue e seja bem sucedida.
Quando o WSO2 Enterprise Service Bus inicializa, os endpoints estão ativos (na situação Active) e prontos para enviar mensagens. Se o usuário não desligar os endpoints (situação Off), será Active até que ocorra um erro.
Quando ocorrer um erro, o Endpoint poderá ser configurado como: Active, Timeout ou Suspended. Todo erro tem um código. As configurações de Endpoint possibilitam que você defina os erros que colocarão o Endpoint nos modos Timeout e Suspension. Se um erro não foi definido como Timeout ou Suspended, será ignorado.
Os erros são manipulados de três formas:
- Endpoint na situação SUSPENDED
- Endpoint na situação TIMEOUT
- Ignorado e mantido no ACTIVE
Se um erro específico não possui um timeout configurado, então a conexão será fechada e o erro será tratado como TIMEOUT. Todos os outros erros terão o Endpoint colocado como SUSPENDED.
Quando um erro ocorrer no Endpoint, será visto primeiramente se ele é um erro para colocar na situação TIMEOUT. Caso contrário, será verificado se é para colocar na situação SUSPENDED.
Nesta situação o Endpoint pode ter na mensagem encaminhada um número máximo de tentativas. Se as falhas persistirem e o número máximo for excedido, o Endpoint será marcado como SUSPENDED. Mas se alguma mensagem for processada o Endpoint será marcado como ACTIVE.
Por exemplo, vamos dizer que o número de tentativas é 3 para esta situção. Se as próximas três mensagens são enviadas usando este Endpoint, e encontramos um erro, o endpoint é colocado como SUSPENDED. Mas se alguma das mensagens anteriores for bem sucedida neste Endpoint, que estava SUSPENDED, ele então será colocado como ACTIVE.
Um endpoint suspended não pode ser usado para enviar mensagens. Depois que o endpoint é colocado nesta situação, pode ser tentado novamente após o tempo configurado. Depois deste de passado o tempo de expiração, o WSO2 Enterprise Service Bus tentará encaminhar as mensagens deste endpoint. Se a mensagem for bem-sucedida, então o WSO2 Enterprise Service Bus marcará este endpoint como ACTIVE. Se a próxima mensagem falhar, o endpoint será colocado como SUSPENDED ou TIMEOUT dependendo do erro que ocorrer.
O próximo período é calculado usando a seguinte fórmula:
Next suspension time period = Max (Initial Suspension duration * (progression factor try count), Maximum Duration)
Todas as variáveis da fórmula acima são valores configurados usados para calcular o número de tentativas (contabilizadas após o endpoint ser marcado SUSPENDED). Com a incrementação do número de tentativas (try count), o próximo período de suspensão (next suspension time period) também será incrementado. O incremento é vinculado a máxima duração (maximum duration).
Esta é a configuração do endereço do endpoint. Uma vez que estamos interessados apenas nas configurações de erros, as mesmas também podem ser aplicadas aos WSDL Endpoints. As configurações de maninpulação de erros são:
- timeout
- markForSuspension
- suspendOnFailure
Vamos ver as configurações individualmente.
<address uri="endpoint address" [format="soap11|soap12|pox|get"]
[optimize="mtom|swa"] [encoding="charset encoding"]
[statistics="enable|disable"] [trace="enable|disable"]>
<enableRM [policy="key"]/>?
<enableSec [policy="key"]/>?
<enableAddressing [version="final|submission"] [separateListener="true|false"]/>?
<timeout>
<duration>timeout duration in seconds</duration>
<action>discard|fault</action>
</timeout>?
<markForSuspension>
[<errorCodes>xxx,yyy</errorCodes>]
<retriesBeforeSuspension>m</retriesBeforeSuspension>
<retryDelay>d</retryDelay>
</markForSuspension>
<suspendOnFailure>
[<errorCodes>xxx,yyy</errorCodes>]
<initialDuration>n</initialDuration>
<progressionFactor>r</progressionFactor>
<maximumDuration>l</maximumDuration>
</suspendOnFailure>
</address>
Timeout
| Nome |
Valores |
Default |
Descrição |
| duration |
miliseconds |
60000 |
Tempo máximo de conexão. Se o endpoint remoto não responder neste tempo, ele será tratado como timeout |
| action |
discard, fault, none |
none |
Tempo para descartar, invocará uma exceção (fault handler) ou responderá como tempo de execução excedido |
markForSuspension
| Nome |
Valores |
Padrão |
Descrição |
| errorCodes |
Códigos de erro separados por vírgula |
101504, 101505 |
Lista de erros que envia o endpoint na situação “TIMEOUT retriesBeforeSuspension” |
| retriesBeforeSuspension |
Integer |
0 |
Na situação TIMEOUT o número de tentativas é igual ao número de requisições menos um e pode falhar antes do endpoint ser marcado como “SUSPENDED retryDelay”. Esta configuração é por Endpoint e não por mensagem. Muitas mensagens podem ser tentadas ao mesmo tempo e falhar, com isso o número de tentativas restantes será reduzido. |
| retryDelay |
|
|
|
suspendOnFailure
| Nome |
Valores |
Padrão |
Descrição |
| errorCodes |
Códigos de erro separados por vírgula |
Todos os erros, exceto os especificados em markForSuspension |
Erros que enviam o endpoint para a situação SUSPENDED |
| initialDuration |
miliseconds |
60 x 60 x 1000 |
Depois que um endpoint fica SUSPENDED, esperará por essa quantidade de tempo antes de tentar enviar a mensagem. Todas as mensagens que forem recebidas durante este período resultarão na ativação de fault sequence. |
| progressionFactor |
Integer |
1 |
O endpoint tentará enviar as mensagens depois da initialDuration. Utilizando a fórmula: next duration = Max(initialDuration x progressionFactor ^ retry count, maximumDuration) |
| maximunDuration |
miliseconds |
Long.MAX_VALUE |
Limite superior da duração de tentativas |
<endpoint name="Sample_First" statistics="enable" >
<address uri="http://localhost/myendpoint" statistics="enable" trace="disable">
<timeout>
<duration>60000</duration>
</timeout>
<markForSuspension>
<errorCodes>101504, 101505</errorCodes>
<retriesBeforeSuspension>3</retriesBeforeSuspension>
<retryDelay>1</retryDelay>
</markForSuspension>
<suspendOnFailure>
<errorCodes>101500, 101501, 101506, 101507, 101508</errorCodes>
<initialDuration>1000</initialDuration>
<progressionFactor>2</progressionFactor>
<maximumDuration>64000</maximumDuration>
</suspendOnFailure>
</address>
</endpoint>
Aqui nós mudamos a situação TIMEOUT do endpoint para os erros 101504 e 101505. Depois desse processo, três requisições podem falhar por um ou desses erros antes de alterar a situação do endpoint para SUSPENDED.
Nós colocamos o endpoint em suspensão para os erros 101500, 101501, 101506, 101507 e 101508. Mas como você pode ver, nós ignoramos o erro 101503. Se o erro 101503 ocorrer, o endpoint será marcado como ACTIVE.
Para mais informações sobre códigos de erro, ver APÊNDICE A.
Com essa configuração, se ocorrer um erro durante o processo de transmissão da mensagem, a mesma será perdida. A mensagem que falhou não terá uma nova tentativa de envio. Esses erros ocorrem raramente, mas falhas em mensagens ainda podem ocorrer. Em algumas aplicações essas falhas nas mensagens perdidas são aceitáveis, mas algumas vezes essas falhas não são aceitáveis e o Fail-Over endpoint é a solução ideal.
Abaixo uma configuração para fail-over endpoints. No nível de configuração, um fail-over é um agrupamento lógico de um ou mais endpoints.
<failover>
<endpoint .../>+
</failover>
Quando uma mensagem chega a situação Fail-Over, será atráves da lista de fail-over endpoints que escolherá a primeira situação entre ACTIVE ou TIMEOUT. Então será enviada a mensagem usando esse endpoint. Se ocorrer um erro enquanto a mensagem é enviada, o fail-over, através da lista de endpoints, irá começar novamente e tentará enviar a mensagem usando o primeiro endpoint.
Alguns erros colocam o endpoint na situação TIMEOUT e outros deixam o endpoint com a situação ACTIVE. Nesses casos as tentativas acontecem usando o mesmo endpoint. Se ocorrer um erro com o primeiro endpoint do grupo fail-over e esse erro não colocar o endpoint como SUSPENDED, as próximas tentativas ocorrerão usando o mesmo endpoint.
O fail-over dá a prioridade para o primeiro endpoint que não esteja como SUSPENDED. Então será enviada a mensagem através do primeiro endpoint do grupo fail-over, enquanto não for marcado como SUSPENDED. Quando o primeiro endpoint é marcado como SUSPENDED as requisições serão enviadas usando o segundo endpoint. Quando o primeiro endpoint estiver pronto para ser utilizado novamente, ele tentará de novo, mesmo que o segundo endpoint ainda esteja ativo.
Se houver apenas um serviço endpoint e falhas não são toleráveis, os fail-overs são possíveis com apenas um endpoint.
Abaixo um exemplo de fail-over com um endpoint.
<endpoint name="SampleFailover">
<failover>
<endpoint name="Sample_First" statistics="enable" >
<address uri="http://localhost/myendpoint" statistics="enable" trace="disable">
<timeout>
<duration>60000</duration>
</timeout>
<markForSuspension>
<errorCodes>101504, 101505, 101500</errorCodes>
<retriesBeforeSuspension>3</retriesBeforeSuspension>
<retryDelay>1</retryDelay>
</markForSuspension>
<suspendOnFailure>
<initialDuration>1000</initialDuration>
<progressionFactor>2</progressionFactor>
<maximumDuration>64000</maximumDuration>
</suspendOnFailure>
</address>
</endpoint>
</failover>
</endpoint>
Nesse exemplo (Sample_First) o endpoint é marcado como TIMEOUT quando a conexão excede o tempo máximo de duração, a conexão é fechada ou envia erros de IO, respectivamente, os códigos de erro: 101504, 101505 e 101500. Para todos os outros erros, será marcado como SUSPENDED. Quando esse erro ocorrer, o fail-over tentará usando o primeiro endpoint que não estiver SUSPENDED, neste caso é o mesmo endpoint (Sample_First). O número de tentativas inicia com a configuração retriesBeforeSuspension e será reduzida a cada mensagem que falhar, até chegar ao zero. É importante notar que a configuração da contagem de tentativas não é por mensagem, mas sim por endpoint.
Nesta configuração nós assumimos que os erros são raros e quando acontecem, basta tentar novamente. Mas se ocorrem frequentemente e continuamente é necessário atenção imediata para que voltem para a situação normal.
A manipulação de erros é crucial para a publicação de endpoints. Os erros devem ser descobertos nos testes, é recomendado executar muitos testes de carga e melhorar a performance das configurações do endpoint preparando-o para os variados erros que podem ocorrer.
Códigos de erro
| Código |
Descrição |
| 101000 |
Receiver IO error sending |
| 101001 |
Receiver IO error receiving |
| 101500 |
Sender IO error sending |
| 101501 |
Sender IO error receiving |
| 101503 |
Connection failed |
| 101504 |
Connection timed out |
| 101505 |
Connection closed |
| 101506 |
HTTP protocol violation |
| 101507 |
Connect cancel |
| 101508 |
Connect timeout |
| 101509 |
Send abort |
Autor
Supun Kamburugamuva, Software Engineer, WSO2, supun@wso2.com