Todos os produtos
Search
Central de documentação

Alibaba Cloud Service Mesh:Configure a connection pool to implement circuit breaking

Última atualização: Jun 28, 2026

Quando microsserviços sofrem sobrecarga ou falhas parciais, o tráfego não controlado pode se propagar pelo sistema e derrubar serviços saudáveis. O circuit breaking no nível de rede — por meio dos proxies sidecar do Service Mesh (ASM) — rejeita o excesso de tráfego antes que ele chegue ao backend, sem exigir alterações de código em cada serviço. Abordagens tradicionais, como Resilience4j, exigem incorporar a lógica de circuit breaking diretamente no código da aplicação.

Configure o campo connectionPool em uma DestinationRule para limitar conexões simultâneas e requisições pendentes para um serviço de destino. As seções abaixo detalham os parâmetros, demonstram o comportamento em quatro topologias de dimensionamento de pods e explicam como monitorar o circuit breaking em produção.

Pré-requisitos

Antes de começar, verifique se você tem:

Como funciona o circuit breaking do pool de conexões

Crie uma DestinationRule com configurações de connectionPool para ativar o circuit breaking em um serviço alvo. Para obter a referência completa dos campos, consulte Destination Rule.

Três parâmetros controlam o comportamento do pool de conexões:

Parâmetro

Tipo

Obrigatório

Padrão

Descrição

tcp.maxConnections

int32

Não

2^32-1

Número máximo de conexões HTTP/1.1 ou TCP para um host de destino. Os proxies sidecar aplicam esse limite tanto no lado do cliente quanto no do servidor. Um único pod cliente não pode abrir mais conexões do que esse valor, e um único pod servidor não pode aceitar mais. Capacidade efetiva do lado do servidor: min(pods clientes, pods servidores) x maxConnections.

http.http1MaxPendingRequests

int32

Não

1024

Quantidade máxima de requisições enfileiradas enquanto aguardam uma conexão disponível. Definir este valor como 0 reverte para o padrão (1024); portanto, utilize pelo menos 1.

http.http2MaxRequests

int32

Não

1024

Limite de requisições ativas para um backend.

O campo connectionPool limita conexões e requisições enfileiradas, mas não remove hosts não saudáveis do pool de balanceamento de carga. Para remover hosts com base nas taxas de erro, combine connectionPool com outlierDetection na mesma DestinationRule. Consulte Destination Rule para ver os campos de outlierDetection.

Com um único pod cliente e um único pod servidor, esses parâmetros apresentam comportamento previsível. Em produção, os serviços geralmente executam vários pods. Os cenários a seguir mostram como o circuit breaking se comporta em quatro topologias comuns:

  • Um pod cliente, um pod de serviço de destino

  • Um pod cliente, vários pods de serviço de destino

  • Vários pods clientes, um pod de serviço de destino

  • Vários pods clientes, vários pods de serviço de destino

Implante as aplicações de exemplo

A configuração de exemplo possui dois componentes:

  • Servidor: Uma aplicação Flask escutando na porta 9080 no endpoint /hello. Cada requisição leva 5 segundos para processamento (simulando um backend lento).

  • Cliente: Um script Python que envia 10 requisições paralelas por lote. Os lotes são disparados nos segundos 0, 20 e 40 de cada minuto, permitindo que múltiplos pods clientes enviem requisições simultaneamente.

  1. Salve o YAML a seguir e execute kubectl apply -f <file-name>.yaml para implantar as aplicações de exemplo.

    Server script

    #!/usr/bin/env python3
    from flask import Flask
    import time
    
    app = Flask(__name__)
    
    @app.route('/hello')
    def get():
        time.sleep(5)
        return 'hello world!'
    
    if __name__ == '__main__':
        app.run(debug=True, host='0.0.0.0', port='9080', threaded=True)

    Client script

    #!/usr/bin/env python3
    import requests
    import time
    import sys
    from datetime import datetime
    import _thread
    
    def timedisplay(t):
      return t.strftime("%H:%M:%S")
    
    def get(url):
      try:
        stime = datetime.now()
        start = time.time()
        response = requests.get(url)
        etime = datetime.now()
        end = time.time()
        elapsed = end-start
        sys.stderr.write("Status: " + str(response.status_code) + ", Start: " + timedisplay(stime) + ", End: " + timedisplay(etime) + ", Elapsed Time: " + str(elapsed)+"\n")
        sys.stdout.flush()
      except Exception as myexception:
        sys.stderr.write("Exception: " + str(myexception)+"\n")
        sys.stdout.flush()
    
    time.sleep(30)
    
    while True:
      sc = int(datetime.now().strftime('%S'))
      time_range = [0, 20, 40]
    
      if sc not in time_range:
        time.sleep(1)
        continue
    
      sys.stderr.write("\n----------Info----------\n")
      sys.stdout.flush()
    
      # Send 10 requests in parallel
      for i in range(10):
        _thread.start_new_thread(get, ("http://circuit-breaker-sample-server:9080/hello", ))
    
      time.sleep(2)

    Deployment YAML

    ##################################################################################################
    #  circuit-breaker-sample-server services
    ##################################################################################################
    apiVersion: v1
    kind: Service
    metadata:
      name: circuit-breaker-sample-server
      labels:
        app: circuit-breaker-sample-server
        service: circuit-breaker-sample-server
    spec:
      ports:
      - port: 9080
        name: http
      selector:
        app: circuit-breaker-sample-server
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: circuit-breaker-sample-server
      labels:
        app: circuit-breaker-sample-server
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: circuit-breaker-sample-server
          version: v1
      template:
        metadata:
          labels:
            app: circuit-breaker-sample-server
            version: v1
        spec:
          containers:
          - name: circuit-breaker-sample-server
            image: registry.cn-hangzhou.aliyuncs.com/acs/istio-samples:circuit-breaker-sample-server.v1
            imagePullPolicy: Always
            ports:
            - containerPort: 9080
    ---
    ##################################################################################################
    #  circuit-breaker-sample-client services
    ##################################################################################################
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: circuit-breaker-sample-client
      labels:
        app: circuit-breaker-sample-client
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: circuit-breaker-sample-client
          version: v1
      template:
        metadata:
          labels:
            app: circuit-breaker-sample-client
            version: v1
        spec:
          containers:
          - name: circuit-breaker-sample-client
            image: registry.cn-hangzhou.aliyuncs.com/acs/istio-samples:circuit-breaker-sample-client.v1
            imagePullPolicy: Always
  2. Verifique se os pods estão em execução. Saída esperada:

    kubectl get po | grep circuit
    circuit-breaker-sample-client-d4f64d66d-fwrh4   2/2     Running   0             1m22s
    circuit-breaker-sample-server-6d6ddb4b-gcthv    2/2     Running   0             1m22s

Sem uma DestinationRule, o servidor processa todas as 10 requisições simultâneas e cada resposta retorna 200:

----------Info----------
Status: 200, Start: 02:39:20, End: 02:39:25, Elapsed Time: 5.016539812088013
Status: 200, Start: 02:39:20, End: 02:39:25, Elapsed Time: 5.012614488601685
Status: 200, Start: 02:39:20, End: 02:39:25, Elapsed Time: 5.015984535217285
Status: 200, Start: 02:39:20, End: 02:39:25, Elapsed Time: 5.015599012374878
Status: 200, Start: 02:39:20, End: 02:39:25, Elapsed Time: 5.012874364852905
Status: 200, Start: 02:39:20, End: 02:39:25, Elapsed Time: 5.018714904785156
Status: 200, Start: 02:39:20, End: 02:39:25, Elapsed Time: 5.010422468185425
Status: 200, Start: 02:39:20, End: 02:39:25, Elapsed Time: 5.012431621551514
Status: 200, Start: 02:39:20, End: 02:39:25, Elapsed Time: 5.011001348495483
Status: 200, Start: 02:39:20, End: 02:39:25, Elapsed Time: 5.01432466506958

Crie uma DestinationRule para circuit breaking

Defina uma DestinationRule para o serviço de destino a fim de ativar o circuit breaking. Para mais informações, consulte Gerenciar regras de destino.

A regra a seguir limita as conexões TCP a 5:

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: circuit-breaker-sample-server
spec:
  host: circuit-breaker-sample-server
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 5

Cenário 1: Um pod cliente, um pod de serviço de destino

  1. Reinicie o pod cliente e verifique seus logs. Todas as 10 requisições têm sucesso, mas apenas 5 terminam em aproximadamente 5 segundos. As demais aguardam mais de 10 segundos porque ficam enfileiradas até que uma conexão seja liberada. Com apenas tcp.maxConnections definido, as requisições excedentes são enfileiradas em vez de falhar — a profundidade padrão da fila é 2^32 - 1.

    ----------Info----------
    Status: 200, Start: 02:49:40, End: 02:49:45, Elapsed Time: 5.0167787075042725
    Status: 200, Start: 02:49:40, End: 02:49:45, Elapsed Time: 5.011920690536499
    Status: 200, Start: 02:49:40, End: 02:49:45, Elapsed Time: 5.017078161239624
    Status: 200, Start: 02:49:40, End: 02:49:45, Elapsed Time: 5.018405437469482
    Status: 200, Start: 02:49:40, End: 02:49:45, Elapsed Time: 5.018689393997192
    Status: 200, Start: 02:49:40, End: 02:49:50, Elapsed Time: 10.018936395645142
    Status: 200, Start: 02:49:40, End: 02:49:50, Elapsed Time: 10.016417503356934
    Status: 200, Start: 02:49:40, End: 02:49:50, Elapsed Time: 10.019930601119995
    Status: 200, Start: 02:49:40, End: 02:49:50, Elapsed Time: 10.022735834121704
    Status: 200, Start: 02:49:40, End: 02:49:55, Elapsed Time: 15.02303147315979
  2. Para um circuit breaking com falha rápida, limite também http.http1MaxPendingRequests. Atualize a DestinationRule. Para mais informações, consulte Gerenciar regras de destino.

    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: circuit-breaker-sample-server
    spec:
      host: circuit-breaker-sample-server
      trafficPolicy:
        connectionPool:
          tcp:
            maxConnections: 5
          http:
            http1MaxPendingRequests: 1
  3. Reinicie o pod cliente e verifique seus logs. Quatro requisições são rejeitadas imediatamente (503), cinco chegam ao destino e uma fica enfileirada (concluindo em aproximadamente 10 segundos após aguardar uma conexão livre).

    ----------Info----------
    Status: 503, Start: 02:56:40, End: 02:56:40, Elapsed Time: 0.005339622497558594
    Status: 503, Start: 02:56:40, End: 02:56:40, Elapsed Time: 0.007254838943481445
    Status: 503, Start: 02:56:40, End: 02:56:40, Elapsed Time: 0.0044133663177490234
    Status: 503, Start: 02:56:40, End: 02:56:40, Elapsed Time: 0.008964776992797852
    Status: 200, Start: 02:56:40, End: 02:56:45, Elapsed Time: 5.018309116363525
    Status: 200, Start: 02:56:40, End: 02:56:45, Elapsed Time: 5.017424821853638
    Status: 200, Start: 02:56:40, End: 02:56:45, Elapsed Time: 5.019804954528809
    Status: 200, Start: 02:56:40, End: 02:56:45, Elapsed Time: 5.01643180847168
    Status: 200, Start: 02:56:40, End: 02:56:45, Elapsed Time: 5.025975227355957
    Status: 200, Start: 02:56:40, End: 02:56:50, Elapsed Time: 10.01716136932373
  4. Verifique a contagem de conexões ativas no proxy sidecar do cliente. Saída esperada: Cinco conexões ativas do proxy cliente para o pod de destino, correspondendo ao limite de maxConnections.

    kubectl exec $(kubectl get pod --selector app=circuit-breaker-sample-client --output jsonpath='{.items[0].metadata.name}') -c istio-proxy -- curl -X POST http://localhost:15000/clusters | grep circuit-breaker-sample-server | grep cx_active
    outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local::172.20.192.124:9080::cx_active::5

Cenário 2: Um pod cliente, vários pods de serviço de destino

Este cenário testa se o limite de conexão se aplica por pod ou por serviço. Com um cliente e três pods de destino:

  • Limite por pod: Cada pod permite 5 conexões, totalizando 15. Todas as 10 requisições devem ter sucesso em aproximadamente 5 segundos.

  • Limite por serviço: Apenas 5 conexões no total, independentemente da quantidade de pods. O comportamento de limitação corresponde ao Cenário 1.

  1. Dimensione o serviço de destino para três réplicas.

    kubectl scale deployment/circuit-breaker-sample-server --replicas=3
  2. Reinicie o pod cliente e verifique seus logs. O padrão de limitação é idêntico ao do Cenário 1. Adicionar mais pods de destino não aumenta o limite de conexão do cliente. O limite de conexão aplica-se por serviço, não por pod.

    ----------Info----------
    Status: 503, Start: 03:06:20, End: 03:06:20, Elapsed Time: 0.011791706085205078
    Status: 503, Start: 03:06:20, End: 03:06:20, Elapsed Time: 0.0032286643981933594
    Status: 503, Start: 03:06:20, End: 03:06:20, Elapsed Time: 0.012153387069702148
    Status: 503, Start: 03:06:20, End: 03:06:20, Elapsed Time: 0.011871814727783203
    Status: 200, Start: 03:06:20, End: 03:06:25, Elapsed Time: 5.012892484664917
    Status: 200, Start: 03:06:20, End: 03:06:25, Elapsed Time: 5.013102769851685
    Status: 200, Start: 03:06:20, End: 03:06:25, Elapsed Time: 5.016939163208008
    Status: 200, Start: 03:06:20, End: 03:06:25, Elapsed Time: 5.014261484146118
    Status: 200, Start: 03:06:20, End: 03:06:25, Elapsed Time: 5.01246190071106
    Status: 200, Start: 03:06:20, End: 03:06:30, Elapsed Time: 10.021712064743042
  3. Verifique a distribuição de conexões ativas. Saída esperada: O proxy distribui as conexões entre os pods — duas por pod, seis no total em vez de cinco. Conforme mencionado na documentação do Envoy e do Istio, um proxy permite certa margem de variação na quantidade de conexões.

    kubectl exec $(kubectl get pod --selector app=circuit-breaker-sample-client --output jsonpath='{.items[0].metadata.name}') -c istio-proxy -- curl -X POST http://localhost:15000/clusters | grep circuit-breaker-sample-server | grep cx_active
    outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local::172.20.192.124:9080::cx_active::2
    outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local::172.20.192.158:9080::cx_active::2
    outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local::172.20.192.26:9080::cx_active::2

Cenário 3: Vários pods clientes, um pod de serviço de destino

  1. Ajuste as réplicas: dimensione o servidor para 1 e o cliente para 3.

    kubectl scale deployment/circuit-breaker-sample-server --replicas=1
    kubectl scale deployment/circuit-breaker-sample-client --replicas=3
  2. Reinicie os pods clientes e verifique seus logs.

    Client logs

    Cliente 1

    ----------Info----------
    Status: 503, Start: 03:10:40, End: 03:10:40, Elapsed Time: 0.008828878402709961
    Status: 503, Start: 03:10:40, End: 03:10:40, Elapsed Time: 0.010806798934936523
    Status: 503, Start: 03:10:40, End: 03:10:40, Elapsed Time: 0.012855291366577148
    Status: 503, Start: 03:10:40, End: 03:10:40, Elapsed Time: 0.004465818405151367
    Status: 503, Start: 03:10:40, End: 03:10:40, Elapsed Time: 0.007823944091796875
    Status: 503, Start: 03:10:40, End: 03:10:40, Elapsed Time: 0.06221342086791992
    Status: 503, Start: 03:10:40, End: 03:10:40, Elapsed Time: 0.06922149658203125
    Status: 503, Start: 03:10:40, End: 03:10:40, Elapsed Time: 0.06859922409057617
    Status: 200, Start: 03:10:40, End: 03:10:45, Elapsed Time: 5.015282392501831
    Status: 200, Start: 03:10:40, End: 03:10:50, Elapsed Time: 9.378434181213379

    Cliente 2

    ----------Info----------
    Status: 503, Start: 03:11:00, End: 03:11:00, Elapsed Time: 0.007795810699462891
    Status: 503, Start: 03:11:00, End: 03:11:00, Elapsed Time: 0.00595545768737793
    Status: 503, Start: 03:11:00, End: 03:11:00, Elapsed Time: 0.013380765914916992
    Status: 503, Start: 03:11:00, End: 03:11:00, Elapsed Time: 0.004278898239135742
    Status: 503, Start: 03:11:00, End: 03:11:00, Elapsed Time: 0.010999202728271484
    Status: 200, Start: 03:11:00, End: 03:11:05, Elapsed Time: 5.015426874160767
    Status: 200, Start: 03:11:00, End: 03:11:05, Elapsed Time: 5.0184690952301025
    Status: 200, Start: 03:11:00, End: 03:11:05, Elapsed Time: 5.019806146621704
    Status: 200, Start: 03:11:00, End: 03:11:05, Elapsed Time: 5.0175628662109375
    Status: 200, Start: 03:11:00, End: 03:11:05, Elapsed Time: 5.031521558761597

    Cliente 3

    ----------Info----------
    Status: 503, Start: 03:13:20, End: 03:13:20, Elapsed Time: 0.012019157409667969
    Status: 503, Start: 03:13:20, End: 03:13:20, Elapsed Time: 0.012546539306640625
    Status: 503, Start: 03:13:20, End: 03:13:20, Elapsed Time: 0.013760805130004883
    Status: 503, Start: 03:13:20, End: 03:13:20, Elapsed Time: 0.014089822769165039
    Status: 503, Start: 03:13:20, End: 03:13:20, Elapsed Time: 0.014792442321777344
    Status: 503, Start: 03:13:20, End: 03:13:20, Elapsed Time: 0.015463829040527344
    Status: 503, Start: 03:13:20, End: 03:13:20, Elapsed Time: 0.01661539077758789
    Status: 200, Start: 03:13:20, End: 03:13:20, Elapsed Time: 0.02904224395751953
    Status: 200, Start: 03:13:20, End: 03:13:20, Elapsed Time: 0.03912043571472168
    Status: 200, Start: 03:13:20, End: 03:13:20, Elapsed Time: 0.06436014175415039

    A taxa de erros 503 aumenta em cada cliente. Cada proxy cliente aplica seu próprio limite de 5 conexões de forma independente, mas o único proxy do serviço de destino também impõe um limite de 5 conexões. Apenas 5 requisições de todos os clientes combinados podem ter sucesso simultaneamente.

  3. Verifique os logs do proxy cliente para identificar as flags de resposta.

    Client proxy logs

    {"authority":"circuit-breaker-sample-server:9080","bytes_received":"0","bytes_sent":"81","downstream_local_address":"192.168.142.207:9080","downstream_remote_address":"172.20.192.31:44610","duration":"0","istio_policy_status":"-","method":"GET","path":"/hello","protocol":"HTTP/1.1","request_id":"d9d87600-cd01-421f-8a6f-dc0ee0ac8ccd","requested_server_name":"-","response_code":"503","response_flags":"UO","route_name":"default","start_time":"2023-02-28T03:14:00.095Z","trace_id":"-","upstream_cluster":"outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local","upstream_host":"-","upstream_local_address":"-","upstream_service_time":"-","upstream_transport_failure_reason":"-","user_agent":"python-requests/2.21.0","x_forwarded_for":"-"}
    {"authority":"circuit-breaker-sample-server:9080","bytes_received":"0","bytes_sent":"81","downstream_local_address":"192.168.142.207:9080","downstream_remote_address":"172.20.192.31:43294","duration":"58","istio_policy_status":"-","method":"GET","path":"/hello","protocol":"HTTP/1.1","request_id":"931d080a-3413-4e35-91f4-0c906e7ee565","requested_server_name":"-","response_code":"503","response_flags":"URX","route_name":"default","start_time":"2023-02-28T03:12:20.995Z","trace_id":"-","upstream_cluster":"outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local","upstream_host":"172.20.192.84:9080","upstream_local_address":"172.20.192.31:58742","upstream_service_time":"57","upstream_transport_failure_reason":"-","user_agent":"python-requests/2.21.0","x_forwarded_for":"-"}

    Requisições limitadas retornam um erro 503 com uma de duas flags de resposta:

    Flag

    Significado

    Onde ocorre

    UO

    Overflow upstream (circuit breaking)

    O proxy cliente limita a requisição localmente

    URX

    Limite de nova tentativa/conexão upstream excedido

    O proxy do serviço de destino rejeita a requisição

    Distinga as duas examinando DURATION, UPSTREAM_HOST e UPSTREAM_CLUSTER no log de acesso. Requisições com UO não possuem host upstream (limitadas antes do envio), enquanto requisições com URX chegaram ao proxy de destino e foram rejeitadas lá.

  4. Confirme verificando os logs do proxy do serviço de destino.

    Destination service proxy logs

    {"authority":"circuit-breaker-sample-server:9080","bytes_received":"0","bytes_sent":"81","downstream_local_address":"172.20.192.84:9080","downstream_remote_address":"172.20.192.31:59510","duration":"0","istio_policy_status":"-","method":"GET","path":"/hello","protocol":"HTTP/1.1","request_id":"7684cbb0-8f1c-44bf-b591-40c3deff6b0b","requested_server_name":"outbound_.9080_._.circuit-breaker-sample-server.default.svc.cluster.local","response_code":"503","response_flags":"UO","route_name":"default","start_time":"2023-02-28T03:14:00.095Z","trace_id":"-","upstream_cluster":"inbound|9080||","upstream_host":"-","upstream_local_address":"-","upstream_service_time":"-","upstream_transport_failure_reason":"-","user_agent":"python-requests/2.21.0","x_forwarded_for":"-"}

    O proxy do serviço de destino também retorna 503 com a flag UO. Isso confirma que as entradas URX nos logs do proxy cliente originam-se da rejeição de conexões excedentes pelo proxy do serviço de destino.

Resumo do fluxo de requisições:

Cada proxy cliente aplica um limite de 5 conexões independentemente. Com 3 clientes, até 15 requisições podem sair dos proxies clientes em paralelo. No entanto, o único proxy do serviço de destino também impõe um limite de 5 conexões, aceitando apenas 5 e rejeitando o restante. As requisições rejeitadas aparecem como URX nos logs do proxy cliente.

image

Cenário 4: Vários pods clientes, vários pods de serviço de destino

Dimensionar o serviço de destino aumenta a taxa geral de sucesso porque o proxy de cada pod de destino permite independentemente 5 conexões.

  1. Defina o servidor para 2 réplicas e o cliente para 3. Com 2 pods de destino (cada um aceitando 5), 10 das 30 requisições totais (de 3 clientes) têm sucesso por lote.

    kubectl scale deployment/circuit-breaker-sample-server --replicas=2
    kubectl scale deployment/circuit-breaker-sample-client --replicas=3
  2. Dimensione o servidor para 3 réplicas. 15 requisições têm sucesso por lote.

    kubectl scale deployment/circuit-breaker-sample-server --replicas=3
  3. Dimensione o servidor para 4 réplicas. Ainda assim, apenas 15 requisições têm sucesso. O limite do proxy cliente restringe a 5 por cliente, independentemente de quantos pods de destino estejam disponíveis. Com 3 clientes, o máximo é 3 x 5 = 15 requisições simultâneas bem-sucedidas.

    kubectl scale deployment/circuit-breaker-sample-server --replicas=4

Resumo das restrições de cliente e servidor

Função

Como o limite se aplica

Cliente

Cada proxy cliente aplica o limite independentemente. Se maxConnections for 100 e houver N pods clientes, até N x 100 requisições podem estar em trânsito em todos os clientes. O limite aplica-se a todo o serviço de destino, não a pods de destino individuais. Mesmo com 200 pods de destino, um único proxy cliente limita a 100 conexões.

Serviço de destino

O proxy de cada pod de destino aplica o limite independentemente. Com 50 pods ativos e maxConnections definido como 100, cada pod aceita até 100 conexões de proxies clientes antes de retornar 503.

Monitore métricas de circuit breaking

Quando o circuit breaking é ativado, o Envoy gera métricas para detectar e diagnosticar limitações.

Métrica

Tipo

Descrição

envoy_cluster_circuit_breakers_default_cx_open

Gauge

1 se o circuit breaker do pool de conexões estiver aberto (ativo); 0 caso contrário.

envoy_cluster_circuit_breakers_default_rq_pending_open

Gauge

1 se a fila de requisições pendentes tiver excedido seu limite; 0 caso contrário.

Ative métricas de circuit breaking

  1. Configure proxyStatsMatcher para o proxy sidecar. Selecione Regular Expression Match e defina o valor como .*circuit_breaker.*. Para mais informações, consulte proxyStatsMatcher.

  2. Reimplante os Deployments circuit-breaker-sample-server e circuit-breaker-sample-client. Para mais informações, consulte Reimplantar cargas de trabalho.

  3. Execute novamente o teste de circuit breaking dos cenários anteriores.

  4. Consulte as métricas do proxy cliente. Saída esperada:

    kubectl exec -it deploy/circuit-breaker-sample-client -c istio-proxy -- curl localhost:15090/stats/prometheus | grep circuit_breaker | grep circuit-breaker-sample-server
    envoy_cluster_circuit_breakers_default_cx_open{cluster_name="outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local"} 1
    envoy_cluster_circuit_breakers_default_cx_pool_open{cluster_name="outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local"} 0
    envoy_cluster_circuit_breakers_default_remaining_cx{cluster_name="outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local"} 0
    envoy_cluster_circuit_breakers_default_remaining_cx_pools{cluster_name="outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local"} 18446744073709551613
    envoy_cluster_circuit_breakers_default_remaining_pending{cluster_name="outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local"} 1
    envoy_cluster_circuit_breakers_default_remaining_retries{cluster_name="outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local"} 4294967295
    envoy_cluster_circuit_breakers_default_remaining_rq{cluster_name="outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local"} 4294967295
    envoy_cluster_circuit_breakers_default_rq_open{cluster_name="outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local"} 0
    envoy_cluster_circuit_breakers_default_rq_pending_open{cluster_name="outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local"} 0
    envoy_cluster_circuit_breakers_default_rq_retry_open{cluster_name="outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local"} 0
    envoy_cluster_circuit_breakers_high_cx_open{cluster_name="outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local"} 0
    envoy_cluster_circuit_breakers_high_cx_pool_open{cluster_name="outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local"} 0
    envoy_cluster_circuit_breakers_high_rq_open{cluster_name="outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local"} 0
    envoy_cluster_circuit_breakers_high_rq_pending_open{cluster_name="outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local"} 0
    envoy_cluster_circuit_breakers_high_rq_retry_open{cluster_name="outbound|9080||circuit-breaker-sample-server.default.svc.cluster.local"} 0

Configure alertas para circuit breaking

Use o Managed Service for Prometheus para coletar métricas de circuit breaking e configurar regras de alerta. Para detalhes sobre integração de componentes, consulte Gerenciar componentes.

Se você já utiliza uma instância autogerenciada do Prometheus para coletar métricas do ASM (consulte Monitorar instâncias do ASM usando uma instância autogerenciada do Prometheus ), pule a etapa 1.
  1. No Managed Service for Prometheus, conecte o cluster do plano de dados ao componente Alibaba Cloud ASM ou atualize-o para a versão mais recente.

  2. Crie uma regra de alerta com uma instrução PromQL personalizada. Para mais informações, consulte Usar uma instrução PromQL personalizada para criar uma regra de alerta. Utilize os seguintes parâmetros como referência:

    Parâmetro

    Exemplo

    Descrição

    Instruções PromQL personalizadas

    (sum by(cluster_name, pod_name, namespace) (envoy_cluster_circuit_breakers_default_cx_open)) != 0

    Verifica se o circuit breaking está ativo em algum pool de conexões. Agrupa por nome do serviço upstream, pod e namespace para que você possa identificar exatamente onde ocorre a limitação.

    Mensagem de alerta

    Circuit breaking is active. The TCP connection limit has been reached. Namespace: {{$labels.namespace}}, Pod: {{$labels.pod_name}}, Upstream service: {{$labels.cluster_name}}

    Identifica o pod afetado, seu namespace e o serviço upstream.