Tratamento Avançado de Erros em Fluxos de Verificação de Identidade Assíncronos (PT-BR)
Dominar o tratamento de erros em verificações de identidade assíncronas é crucial. Este guia explora estratégias como retentativas com backoff, circuit breakers e logging abrangente em Python, garantindo resiliência e sistemas.

Retentativas RobustasImplemente backoff exponencial e jitter para erros transitórios em chamadas de API para serviços externos de verificação de identidade, evitando sobrecarga do sistema e melhorando as taxas de sucesso.
Padrões de Circuit BreakerProteja seu sistema contra falhas em cascata, interrompendo temporariamente as requisições para serviços que estão falhando, permitindo que se recuperem e preservando a estabilidade geral da aplicação.
Logging e Monitoramento AbrangentesUtilize logging estruturado, IDs de correlação e monitoramento em tempo real para identificar, diagnosticar e resolver rapidamente problemas em pipelines assíncronos de verificação de identidade distribuídos.
Resiliência Integrada da DiditA plataforma modular e nativa de IA da Didit oferece fluxos de trabalho orquestrados e design de API robusto, abstraindo o tratamento complexo de erros para verificações essenciais de KYC, prova de vida e AML, melhorando a confiabilidade e a experiência do desenvolvedor.
No mundo da verificação de identidade, velocidade e confiabilidade são primordiais. À medida que as empresas crescem, fluxos de trabalho assíncronos tornam-se essenciais para lidar com grandes volumes de requisições sem bloquear o thread principal da aplicação. No entanto, essa natureza distribuída e não bloqueante introduz complexidades significativas, especialmente quando se trata de tratamento de erros. Problemas de rede, interrupções de serviço, inconsistências de dados e respostas inesperadas de API podem atrapalhar um processo de verificação de identidade, levando a uma má experiência do usuário, riscos de conformidade e ineficiências operacionais.
Esta publicação no blog aborda estratégias avançadas de tratamento de erros para fluxos de trabalho assíncronos de verificação de identidade, com foco específico em implementações Python. Exploraremos como construir sistemas mais resilientes e tolerantes a falhas, garantindo que, mesmo quando as coisas dão errado, seus processos de verificação permaneçam robustos.
O Desafio dos Erros Assíncronos na Verificação de Identidade
A verificação de identidade assíncrona geralmente envolve vários serviços externos: um provedor de verificação de identidade como a Didit para OCR e verificações de prova de vida, um serviço de triagem AML, um banco de dados de comprovante de endereço e, potencialmente, outras fontes de dados. Cada uma dessas interações é um potencial ponto de falha. O tratamento de erros síncrono tradicional (por exemplo, um simples bloco try-except) é insuficiente quando as operações podem ser concluídas muito mais tarde, em um processo diferente ou até mesmo falhar silenciosamente sem feedback imediato.
Considere um fluxo de trabalho KYC típico: um usuário carrega seu documento de identificação, uma verificação de prova de vida é realizada e, em seguida, uma triagem AML é iniciada. Se o serviço de verificação de prova de vida experimentar um problema de rede transitório, simplesmente tentar novamente imediatamente pode agravar o problema. Se o serviço AML estiver completamente inoperante, tentativas repetidas apenas desperdiçarão recursos e atrasarão a integração do usuário.
Implementando Retentativas Robustas com Backoff Exponencial e Jitter
Um dos tipos de erro mais comuns em sistemas distribuídos são as falhas transitórias. São problemas temporários como falhas de rede, erros de serviço ocupado ou contenção de banco de dados que se resolvem após um curto período. Tentar novamente cegamente imediatamente após uma falha pode sobrecarregar um serviço que está com problemas, levando a uma falha em cascata. A solução são retentativas inteligentes usando backoff exponencial e jitter.
O backoff exponencial envolve o aumento do tempo de espera entre as retentativas exponencialmente. Por exemplo, espere 1 segundo, depois 2, depois 4, depois 8 e assim por diante. Isso dá tempo para o serviço se recuperar. O jitter adiciona um pequeno atraso aleatório ao tempo de backoff, impedindo que todos os clientes tentem novamente no exato mesmo momento, o que poderia criar um problema de "thundering herd" (manada de requisições).
import asyncio
import random
async def call_didit_api(data, attempt=0):
max_retries = 5
base_delay = 1 # seconds
try:
# Simulate an API call to Didit's ID Verification or Liveness service
if random.random() < 0.6 and attempt < 3: # Simulate transient failure
raise ConnectionError(f"Simulated API error on attempt {attempt+1}")
print(f"Successfully called Didit API on attempt {attempt+1} with data: {data}")
return {"status": "success", "result": "verification_data"}
except (ConnectionError, asyncio.TimeoutError) as e:
if attempt < max_retries - 1:
delay = base_delay * (2 ** attempt) + random.uniform(0, 0.5) # Exponential backoff + jitter
print(f"Attempt {attempt+1} failed: {e}. Retrying in {delay:.2f} seconds...")
await asyncio.sleep(delay)
return await call_didit_api(data, attempt + 1)
else:
print(f"All {max_retries} attempts failed for data: {data}")
raise # Re-raise the last exception if all retries fail
async def main():
try:
# Example usage for Didit's ID Verification
result = await call_didit_api({"document_image": "base64_id_scan"})
print(f"Final result: {result}")
# Example usage for Didit's Liveness
result_liveness = await call_didit_api({"liveness_video": "base64_video"})
print(f"Final liveness result: {result_liveness}")
except Exception as e:
print(f"Workflow failed after retries: {e}")
if __name__ == "__main__":
asyncio.run(main())
Este padrão é inestimável ao integrar com serviços externos, incluindo a Verificação de Identidade, Prova de Vida Passiva e Ativa ou APIs de Triagem AML da Didit, todos os quais se beneficiam de comunicação resiliente.
Implementando o Padrão Circuit Breaker
Embora as retentativas ajudem com erros transitórios, elas podem piorar a situação se um serviço estiver passando por interrupções prolongadas. O padrão circuit breaker impede que sua aplicação invoque repetidamente um serviço que provavelmente falhará. Ele funciona monitorando falhas e, se elas excederem um certo limite dentro de um determinado tempo, ele "dispara" o circuito, abrindo-o para evitar mais chamadas ao serviço com falha. Após um tempo limite configurável, ele entra em um estado "half-open" (meio-aberto), permitindo algumas requisições de teste para ver se o serviço se recuperou.
import asyncio
import time
from collections import deque
class CircuitBreaker:
def __init__(self, failure_threshold=3, recovery_timeout=10, half_open_attempts=1):
self.state = "CLOSED"
self.failure_threshold = failure_threshold
self.recovery_timeout = recovery_timeout
self.half_open_attempts = half_open_attempts
self.failures = 0
self.last_failure_time = None
self.successes_in_half_open = 0
async def __call__(self, func, *args, **kwargs):
if self.state == "OPEN":
if time.time() - self.last_failure_time > self.recovery_timeout:
self.state = "HALF_OPEN"
self.successes_in_half_open = 0
print("Circuit Breaker: Moving to HALF_OPEN state.")
else:
raise CircuitBreakerOpenError("Circuit is OPEN. Service is likely down.")
try:
result = await func(*args, **kwargs)
self._on_success()
return result
except Exception as e:
self._on_failure(e)
raise
def _on_success(self):
if self.state == "HALF_OPEN":
self.successes_in_half_open += 1
if self.successes_in_half_open >= self.half_open_attempts:
self.state = "CLOSED"
self.failures = 0
print("Circuit Breaker: Service recovered. Moving to CLOSED state.")
elif self.state == "CLOSED":
self.failures = 0 # Reset failures on success in closed state
def _on_failure(self, error):
if self.state == "HALF_OPEN":
self.state = "OPEN"
self.last_failure_time = time.time()
print(f"Circuit Breaker: Failure in HALF_OPEN. Moving to OPEN state. Error: {error}")
elif self.state == "CLOSED":
self.failures += 1
if self.failures >= self.failure_threshold:
self.state = "OPEN"
self.last_failure_time = time.time()
print(f"Circuit Breaker: Failures exceeded threshold. Moving to OPEN state. Error: {error}")
class CircuitBreakerOpenError(Exception):
pass
# Example usage with a simulated Didit AML Screening call
async def simulate_aml_screening():
if random.random() < 0.7: # Simulate frequent failures
raise ConnectionError("AML service unavailable")
await asyncio.sleep(0.1)
return {"aml_status": "clear"}
async def main():
cb = CircuitBreaker()
for i in range(20):
try:
print(f"--- Attempt {i+1} ---")
result = await cb(simulate_aml_screening)
print(f"AML Screening Success: {result}")
except CircuitBreakerOpenError as e:
print(f"Caught: {e}")
await asyncio.sleep(1) # Wait a bit before next attempt if circuit is open
except ConnectionError as e:
print(f"Caught: {e}")
await asyncio.sleep(0.5)
if __name__ == "__main__":
asyncio.run(main())
Este padrão é particularmente útil para serviços críticos como a Triagem AML da Didit ou operações de Busca Facial em larga escala, onde uma dependência com falha pode impactar muitos usuários.
Logging, Monitoramento e Alerta Abrangentes
Mesmo com retentativas robustas e circuit breakers, erros ocorrerão. A chave é saber quando eles acontecem, entender o porquê e reagir rapidamente. Logging abrangente, monitoramento em tempo real e alertas proativos são inegociáveis para fluxos de trabalho assíncronos.
- Logging Estruturado: As mensagens de log devem estar em um formato legível por máquina (por exemplo, JSON) e incluir contexto como
session_id,workflow_id, nome do serviço, timestamp e tipo de erro. Isso permite fácil agregação e análise. - IDs de Correlação: Atribua um ID de correlação único a cada requisição de verificação de identidade em seu ponto de entrada e passe-o por todas as chamadas de serviço subsequentes. Isso permite rastrear a jornada de um único usuário através de um sistema distribuído complexo, mesmo ao usar serviços modulares como a Verificação de Identidade e a Estimativa de Idade da Didit.
- Dashboards de Monitoramento: Visualize métricas chave como taxas de sucesso de API, latência, taxas de erro e tamanhos de fila para cada componente do seu fluxo de trabalho. Ferramentas como Prometheus, Grafana ou serviços de monitoramento nativos da nuvem são inestimáveis.
- Alertas: Configure alertas para limites críticos (por exemplo, taxa de erro excedendo 5% por 5 minutos, ou um serviço específico inacessível). Os alertas devem ser enviados para a equipe certa via PagerDuty, Slack ou e-mail, permitindo ação imediata.
Por exemplo, quando um usuário inicia uma sessão de verificação usando os Fluxos de Trabalho Orquestrados da Didit, um session_id é gerado. Este ID deve ser capturado em seus logs para cada etapa, desde a chamada inicial da API para a Didit até o callback final do webhook com os resultados da verificação. Se surgir um problema, você pode filtrar rapidamente os logs por este session_id para identificar o ponto exato da falha.
Como a Didit Ajuda
A Didit, como uma plataforma de identidade nativa de IA e focada no desenvolvedor, foi projetada para simplificar fluxos de trabalho complexos de verificação de identidade, incluindo seus desafios inerentes de tratamento de erros. Nossa arquitetura modular significa que, embora você possa construir soluções altamente personalizadas, grande parte da resiliência subjacente é tratada para você.
- Fluxos de Trabalho Orquestrados: O motor de fluxo de trabalho sem código da Didit permite definir sequências complexas de verificação (por exemplo, Verificação de Identidade + Prova de Vida + Triagem AML) sem escrever código extenso para orquestração ou gerenciamento de estado. A Didit lida com as retentativas internas e transições de estado, reduzindo significativamente o ônus do tratamento de erros do seu lado.
- APIs e Webhooks Robustos: Nossas APIs limpas são construídas para confiabilidade, e nosso sistema de webhook fornece atualizações em tempo real sobre o status da verificação. A Didit gerencia a entrega desses webhooks com mecanismos de retentativa integrados, garantindo que você receba atualizações críticas mesmo que seu endpoint esteja temporariamente indisponível.
- KYC Essencial Gratuito: Comece com a verificação de identidade essencial, incluindo Verificação de Identidade (OCR, MRZ, códigos de barras) e Prova de Vida Passiva e Ativa, sem custos iniciais. Isso permite que você implemente uma verificação robusta sem se preocupar com a resiliência da infraestrutura subjacente.
- Confiabilidade Nativa de IA: Nossos sistemas baseados em IA são inerentemente projetados para alta disponibilidade e desempenho, minimizando erros internos e fornecendo resultados consistentes para produtos como Comparação Facial 1:1 e Estimativa de Idade.
- Dados de Identidade Estruturados: Todos os resultados da verificação são fornecidos como dados estruturados, tornando mais fácil para seus sistemas processar resultados e lidar com exceções programaticamente.
Ao aproveitar a plataforma da Didit, você pode descarregar grande parte da complexidade do tratamento de erros assíncronos, focando em sua lógica de negócios principal, enquanto garante uma experiência de verificação de identidade confiável e segura para seus usuários.
Pronto para Começar?
Pronto para ver a Didit em ação? Obtenha uma demonstração gratuita hoje mesmo.
Comece a verificar identidades gratuitamente com o nível gratuito da Didit.