Todos os produtos
Search
Central de documentação

Alibaba Cloud Service Mesh:Use ASMAdaptiveConcurrency to implement adaptive concurrency control

Última atualização: Jun 28, 2026

O circuit breaking estático exige a estimativa e definição manual de um limiar fixo de concorrência para cada serviço. Se a estimativa for muito baixa, o sistema bloqueará tráfego legítimo. Se for muito alta, o serviço sobrecarregará antes da ativação do circuit breaker. A CustomResourceDefinition (CRD) ASMAdaptiveConcurrency elimina essa incerteza ao ajustar dinamicamente o limite de concorrência com base em medições de latência em tempo real, mantendo o limite próximo da capacidade real do serviço sem necessidade de ajustes manuais.

Quando as requisições simultâneas excedem o limite calculado, o sidecar proxy retorna o código de status HTTP 503 com a mensagem de erro reached concurrency limit.

Como funciona

O controlador de concorrência adaptativa utiliza um algoritmo baseado em gradiente que mede periodicamente a latência de linha de base de um serviço (MinRTT) e a compara com a latência das requisições amostradas (SampleRTT) para ajustar o limite de concorrência.

Cálculo do gradiente

O controlador calcula um valor de gradiente a partir das latências amostradas:

gradient = (minRTT + buffer) / sampleRTT

O buffer absorve a variância normal de latência, de modo que o gradiente só diminui quando a latência amostrada excede a linha de base por uma margem significativa:

buffer = minRTT * buffer_pct

Em seguida, o gradiente atualiza o limite de concorrência:

new_limit = gradient * current_limit + headroom

Quando o serviço está saudável, o sampleRTT permanece próximo do minRTT, o gradiente se mantém perto de 1.0 e o limite permanece estável ou aumenta. À medida que o serviço fica sobrecarregado, o sampleRTT sobe, o gradiente cai abaixo de 1.0 e o limite diminui, rejeitando requisições excedentes antes que o serviço sofra maior degradação.

Recálculo do MinRTT

Periodicamente, o controlador recalcula o MinRTT reduzindo temporariamente o limite de concorrência para o valor de min_concurrency. Durante essa janela, apenas um pequeno número de requisições é encaminhado, permitindo que o serviço responda com sua verdadeira latência mínima.

Importante

O limite de concorrência cai significativamente durante o recálculo do MinRTT, o que pode causar um pico nas respostas 503. Para mitigar isso, crie uma destination rule que ative retentativas para o serviço de destino. Isso permite que o sidecar proxy tente novamente as requisições rejeitadas em outros hosts que não estejam em uma janela de recálculo de MinRTT.

Pré-requisitos

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

Etapa 1: Implantar aplicações de exemplo

Este tutorial usa duas aplicações para demonstrar o controle de concorrência adaptativa:

Aplicação

Função

Configuração

testserver

Serviço de destino

Processa até 500 requisições simultâneas, cada uma levando 1.000 ms para ser processada. Requisições além do limite de concorrência são enfileiradas.

gotest

Gerador de carga

Cada réplica envia 200 requisições simultâneas para o testserver.

Implantar o testserver

  1. Crie um arquivo chamado testserver.yaml com o seguinte conteúdo:

    Visualize testserver.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: testserver
      name: testserver
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: testserver
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: testserver
        spec:
          containers:
          - args:
            - -m
            - "500"
            - -t
            - "1000"
            command:
            - /usr/local/bin/limited-concurrency-http-server
            image: registry.cn-hangzhou.aliyuncs.com/acs/asm-limited-concurrency-http-server:v0.1.1-gee0b08f-aliyun
            imagePullPolicy: IfNotPresent
            name: testserver
            ports:
            - containerPort: 8080
              protocol: TCP

    A flag -m define o máximo de requisições simultâneas (500). A flag -t define o tempo de processamento por requisição em milissegundos (1.000).

  2. Aplique o Deployment:

    kubectl apply -f testserver.yaml

Criar o Service testserver

  1. Crie um arquivo chamado testservice.yaml com o seguinte conteúdo:

    Visualize testservice.yaml

    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: testserver
      name: testserver
      namespace: default
    spec:
      internalTrafficPolicy: Cluster
      ipFamilies:
        - IPv4
      ipFamilyPolicy: SingleStack
      ports:
        - name: http
          port: 8080
          protocol: TCP
          targetPort: 8080
        - name: metrics
          port: 15020
          protocol: TCP
          targetPort: 15020
      selector:
        app: testserver
      type: ClusterIP
  2. Aplique o Service:

    kubectl apply -f testservice.yaml

Implantar o gotest

  1. Crie um arquivo chamado gotest.yaml com o seguinte conteúdo:

    Visualize gotest.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: gotest
      name: gotest
      namespace: default
    spec:
      replicas: 0
      selector:
        matchLabels:
          app: gotest
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: gotest
        spec:
          containers:
          - args:
            - -c
            - "200"
            - -n
            - "10000"
            - -u
            - testserver:8080
            command:
            - /root/go-stress-testing-linux
            image: xocoder/go-stress-testing-linux:v0.1
            imagePullPolicy: Always
            name: gotest
            resources:
              limits:
                cpu: 500m

    A contagem inicial de réplicas é 0. Escale-a na Etapa 4 para gerar carga.

  2. Aplique o Deployment:

    kubectl apply -f gotest.yaml

Etapa 2: Criar uma CRD ASMAdaptiveConcurrency

  1. Conecte o kubectl à sua instância do ASM. Para mais informações, consulte Usar kubectl no plano de controle para acessar recursos do Istio.

  2. Crie um arquivo chamado adaptiveconcurrency.yaml com o seguinte conteúdo:

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ASMAdaptiveConcurrency
    metadata:
      name: sample-adaptive-concurrency
      namespace: default
    spec:
      workload_selector:
        labels:
          app: testserver
      sample_aggregate_percentile:
        value: 60
      concurrency_limit_params:
        max_concurrency_limit: 500
        concurrency_update_interval: 15s
      min_rtt_calc_params:
        interval: 60s
        request_count: 100
        jitter:
          value: 15
        min_concurrency: 50
        buffer:
          value: 25

    Esta configuração deve ser interpretada da seguinte forma:

    • Direciona o workload testserver e define o limite superior de 500 requisições simultâneas.

    • Atualiza o limite de concorrência a cada 15 segundos, usando o percentil 60 das latências amostradas como SampleRTT.

    • Recalcula o MinRTT a cada 60 segundos (com até 15% de jitter aleatório) utilizando 100 requisições amostradas. Durante o recálculo do MinRTT, limita a concorrência a 50 requisições.

    • Considera normais as flutuações de latência dentro de 25% do MinRTT.

  3. Aplique a CRD:

    kubectl apply -f adaptiveconcurrency.yaml

Referência de parâmetros

Parâmetro

Tipo

Obrigatório

Padrão

Descrição

workload_selector

WorkloadSelector

Sim

--

Seleciona o pod de destino por rótulo.

labels

map

Sim

--

Rótulos para corresponder ao pod de destino.

sample_aggregate_percentile

Percent

Sim

--

Percentil usado para agregar latências amostradas no SampleRTT. Valores válidos: 0 a 100.

concurrency_limit_params

Object

Sim

--

Configurações do limite de concorrência.

max_concurrency_limit

int

Não

1000

Limite superior para requisições simultâneas.

concurrency_update_interval

duration

Sim

--

Frequência com que o controlador atualiza o limite de concorrência. Exemplo: 60s.

min_rtt_calc_params

Object

Sim

--

Configurações de cálculo do MinRTT.

interval

duration

Não

--

Frequência de recálculo do MinRTT. Exemplo: 120s.

request_count

int

Não

50

Número de requisições amostradas para calcular o MinRTT.

jitter

Percent

Não

15

Jitter aleatório adicionado ao intervalo de recálculo do MinRTT. Por exemplo, se interval for 120s e jitter for 50, o intervalo real será random(120, 120 + 120 * 50%) segundos.

min_concurrency

int

Não

3

Limite de concorrência durante o recálculo do MinRTT. Também serve como limite inicial quando o controlador inicia. Defina este valor bem abaixo da capacidade real do serviço para obter medições precisas da linha de base.

buffer

Percent

Não

25

Flutuação aceitável de latência como porcentagem do MinRTT. Por exemplo, se o MinRTT for 100 ms e o buffer for 10, latências de até 110 ms são consideradas normais.

Etapa 3: Configurar monitoramento com Prometheus

Exporte métricas de concorrência adaptativa para o Managed Service for Prometheus a fim de observar o comportamento do controlador e ajustar parâmetros.

  1. Ative o Managed Service for Prometheus para seu cluster. Para mais informações, consulte Usar o Managed Service for Prometheus.

  2. Crie um ServiceMonitor para coletar métricas do sidecar proxy do testserver.

    1. Crie um arquivo chamado servicemonitor.yaml com o seguinte conteúdo:

      apiVersion: monitoring.coreos.com/v1
      kind: ServiceMonitor
      metadata:
        name: testserver-envoy-metrics
        namespace: default
      spec:
        endpoints:
          - interval: 5s
            path: /stats/prometheus
            port: metrics
        namespaceSelector:
          any: true
        selector:
          matchLabels:
            app: testserver
    2. Conecte o kubectl ao cluster ACK e aplique o ServiceMonitor:

      kubectl apply -f servicemonitor.yaml
  3. Importe o painel do Grafana para visualizar as métricas do controlador. Baixe o JSON do painel e importe-o no console do Managed Service for Grafana. Para instruções de importação, consulte a documentação do ARMS.

    Visualize Grafana dashboard JSON

    {
      "annotations": {
        "list": [
          {
            "builtIn": 1,
            "datasource": "-- Grafana --",
            "enable": true,
            "hide": true,
            "iconColor": "rgba(0, 211, 255, 1)",
            "name": "Annotations & Alerts",
            "type": "dashboard"
          }
        ]
      },
      "description": "monitoring ASM Adaptive Concurrency",
      "editable": true,
      "gnetId": 6693,
      "graphTooltip": 0,
      "id": 3239002,
      "iteration": 1651922323976,
      "links": [],
      "panels": [
        {
          "aliasColors": {},
          "bars": false,
          "dashLength": 10,
          "dashes": false,
          "datasource": "$cluster",
          "fieldConfig": {
            "defaults": { "custom": {} },
            "overrides": []
          },
          "fill": 1,
          "fillGradient": 0,
          "gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 },
          "hiddenSeries": false,
          "id": 22,
          "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false },
          "lines": true,
          "linewidth": 1,
          "nullPointMode": "null",
          "options": { "alertThreshold": true },
          "percentage": false,
          "pluginVersion": "7.4.0-pre",
          "pointradius": 2,
          "points": false,
          "renderer": "flot",
          "seriesOverrides": [],
          "spaceLength": 10,
          "stack": false,
          "steppedLine": false,
          "targets": [
            {
              "expr": "envoy_http_inbound_0_0_0_0_8080_adaptive_concurrency_gradient_controller_rq_blocked{service=\"$service\", pod=\"$pod\"}",
              "interval": "",
              "legendFormat": "{{service}}-{{pod}}",
              "queryType": "randomWalk",
              "refId": "A"
            }
          ],
          "thresholds": [],
          "timeFrom": null,
          "timeRegions": [],
          "timeShift": null,
          "title": "RqBlocked",
          "tooltip": { "shared": true, "sort": 0, "value_type": "individual" },
          "type": "graph",
          "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] },
          "yaxes": [
            { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true },
            { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true }
          ],
          "yaxis": { "align": false, "alignLevel": null }
        },
        {
          "aliasColors": {},
          "bars": false,
          "dashLength": 10,
          "dashes": false,
          "datasource": "$cluster",
          "fieldConfig": {
            "defaults": { "custom": {} },
            "overrides": []
          },
          "fill": 1,
          "fillGradient": 0,
          "gridPos": { "h": 8, "w": 12, "x": 12, "y": 0 },
          "hiddenSeries": false,
          "id": 24,
          "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false },
          "lines": true,
          "linewidth": 1,
          "nullPointMode": "null",
          "options": { "alertThreshold": true },
          "percentage": false,
          "pluginVersion": "7.4.0-pre",
          "pointradius": 2,
          "points": false,
          "renderer": "flot",
          "seriesOverrides": [],
          "spaceLength": 10,
          "stack": false,
          "steppedLine": false,
          "targets": [
            {
              "expr": "envoy_http_inbound_0_0_0_0_8080_adaptive_concurrency_gradient_controller_burst_queue_size{service=\"$service\", pod=\"$pod\"}",
              "format": "time_series",
              "interval": "",
              "legendFormat": "{{service}}-{{pod}}",
              "queryType": "randomWalk",
              "refId": "A"
            }
          ],
          "thresholds": [],
          "timeFrom": null,
          "timeRegions": [],
          "timeShift": null,
          "title": "HeadRoom",
          "tooltip": { "shared": true, "sort": 0, "value_type": "individual" },
          "type": "graph",
          "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] },
          "yaxes": [
            { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true },
            { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true }
          ],
          "yaxis": { "align": false, "alignLevel": null }
        },
        {
          "aliasColors": {},
          "bars": false,
          "dashLength": 10,
          "dashes": false,
          "datasource": "$cluster",
          "fieldConfig": {
            "defaults": { "custom": {} },
            "overrides": []
          },
          "fill": 1,
          "fillGradient": 0,
          "gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 },
          "hiddenSeries": false,
          "id": 26,
          "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false },
          "lines": true,
          "linewidth": 1,
          "nullPointMode": "null",
          "options": { "alertThreshold": true },
          "percentage": false,
          "pluginVersion": "7.4.0-pre",
          "pointradius": 2,
          "points": false,
          "renderer": "flot",
          "seriesOverrides": [],
          "spaceLength": 10,
          "stack": false,
          "steppedLine": false,
          "targets": [
            {
              "expr": "envoy_http_inbound_0_0_0_0_8080_adaptive_concurrency_gradient_controller_concurrency_limit{service=\"$service\",pod=\"$pod\"}",
              "interval": "",
              "legendFormat": "{{service}}-{{pod}}",
              "queryType": "randomWalk",
              "refId": "A"
            }
          ],
          "thresholds": [],
          "timeFrom": null,
          "timeRegions": [],
          "timeShift": null,
          "title": "ConcurrencyLimit",
          "tooltip": { "shared": true, "sort": 0, "value_type": "individual" },
          "type": "graph",
          "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] },
          "yaxes": [
            { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true },
            { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true }
          ],
          "yaxis": { "align": false, "alignLevel": null }
        },
        {
          "aliasColors": {},
          "bars": false,
          "dashLength": 10,
          "dashes": false,
          "datasource": "$cluster",
          "fieldConfig": {
            "defaults": { "custom": {} },
            "overrides": []
          },
          "fill": 1,
          "fillGradient": 0,
          "gridPos": { "h": 8, "w": 12, "x": 12, "y": 8 },
          "hiddenSeries": false,
          "id": 28,
          "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false },
          "lines": true,
          "linewidth": 1,
          "nullPointMode": "null",
          "options": { "alertThreshold": true },
          "percentage": false,
          "pluginVersion": "7.4.0-pre",
          "pointradius": 2,
          "points": false,
          "renderer": "flot",
          "seriesOverrides": [],
          "spaceLength": 10,
          "stack": false,
          "steppedLine": false,
          "targets": [
            {
              "expr": "envoy_http_inbound_0_0_0_0_8080_adaptive_concurrency_gradient_controller_gradient{service=\"$service\",pod=\"$pod\"}",
              "interval": "",
              "legendFormat": "{{service}}-{{pod}}",
              "queryType": "randomWalk",
              "refId": "A"
            }
          ],
          "thresholds": [],
          "timeFrom": null,
          "timeRegions": [],
          "timeShift": null,
          "title": "Gradient",
          "tooltip": { "shared": true, "sort": 0, "value_type": "individual" },
          "type": "graph",
          "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] },
          "yaxes": [
            { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true },
            { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true }
          ],
          "yaxis": { "align": false, "alignLevel": null }
        },
        {
          "aliasColors": {},
          "bars": false,
          "dashLength": 10,
          "dashes": false,
          "datasource": "$cluster",
          "fieldConfig": {
            "defaults": { "custom": {} },
            "overrides": []
          },
          "fill": 1,
          "fillGradient": 0,
          "gridPos": { "h": 8, "w": 12, "x": 0, "y": 16 },
          "hiddenSeries": false,
          "id": 32,
          "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false },
          "lines": true,
          "linewidth": 1,
          "nullPointMode": "null",
          "options": { "alertThreshold": true },
          "percentage": false,
          "pluginVersion": "7.4.0-pre",
          "pointradius": 2,
          "points": false,
          "renderer": "flot",
          "seriesOverrides": [],
          "spaceLength": 10,
          "stack": false,
          "steppedLine": false,
          "targets": [
            {
              "expr": "envoy_http_inbound_0_0_0_0_8080_adaptive_concurrency_gradient_controller_min_rtt_msecs{service=\"$service\",pod=\"$pod\"}",
              "interval": "",
              "legendFormat": "{{service}}-{{pod}}",
              "queryType": "randomWalk",
              "refId": "A"
            }
          ],
          "thresholds": [],
          "timeFrom": null,
          "timeRegions": [],
          "timeShift": null,
          "title": "MinRTT(msec)",
          "tooltip": { "shared": true, "sort": 0, "value_type": "individual" },
          "type": "graph",
          "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] },
          "yaxes": [
            { "format": "ms", "label": null, "logBase": 1, "max": null, "min": null, "show": true },
            { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true }
          ],
          "yaxis": { "align": false, "alignLevel": null }
        },
        {
          "aliasColors": {},
          "bars": false,
          "dashLength": 10,
          "dashes": false,
          "datasource": "$cluster",
          "fieldConfig": {
            "defaults": { "custom": {} },
            "overrides": []
          },
          "fill": 1,
          "fillGradient": 0,
          "gridPos": { "h": 8, "w": 12, "x": 12, "y": 16 },
          "hiddenSeries": false,
          "id": 34,
          "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false },
          "lines": true,
          "linewidth": 1,
          "nullPointMode": "null",
          "options": { "alertThreshold": true },
          "percentage": false,
          "pluginVersion": "7.4.0-pre",
          "pointradius": 2,
          "points": false,
          "renderer": "flot",
          "seriesOverrides": [],
          "spaceLength": 10,
          "stack": false,
          "steppedLine": false,
          "targets": [
            {
              "expr": "envoy_http_inbound_0_0_0_0_8080_adaptive_concurrency_gradient_controller_sample_rtt_msecs{service=\"$service\",pod=\"$pod\"}",
              "interval": "",
              "legendFormat": "{{service}}-{{pod}}",
              "queryType": "randomWalk",
              "refId": "A"
            }
          ],
          "thresholds": [],
          "timeFrom": null,
          "timeRegions": [],
          "timeShift": null,
          "title": "SampleRTT(msec)",
          "tooltip": { "shared": true, "sort": 0, "value_type": "individual" },
          "type": "graph",
          "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] },
          "yaxes": [
            { "format": "ms", "label": null, "logBase": 1, "max": null, "min": null, "show": true },
            { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true }
          ],
          "yaxis": { "align": false, "alignLevel": null }
        },
        {
          "aliasColors": {},
          "bars": false,
          "dashLength": 10,
          "dashes": false,
          "datasource": "test-adaptive-concurrency_1217520382582089",
          "fieldConfig": {
            "defaults": { "custom": {} },
            "overrides": []
          },
          "fill": 1,
          "fillGradient": 0,
          "gridPos": { "h": 8, "w": 12, "x": 0, "y": 24 },
          "hiddenSeries": false,
          "id": 30,
          "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false },
          "lines": true,
          "linewidth": 1,
          "nullPointMode": "null",
          "options": { "alertThreshold": true },
          "percentage": false,
          "pluginVersion": "7.4.0-pre",
          "pointradius": 2,
          "points": false,
          "renderer": "flot",
          "seriesOverrides": [],
          "spaceLength": 10,
          "stack": false,
          "steppedLine": false,
          "targets": [
            {
              "expr": "envoy_http_inbound_0_0_0_0_8080_adaptive_concurrency_gradient_controller_min_rtt_calculation_active{service=\"$service\",pod=\"$pod\"}",
              "interval": "",
              "legendFormat": "{{service}}-{{pod}}",
              "queryType": "randomWalk",
              "refId": "A"
            }
          ],
          "thresholds": [],
          "timeFrom": null,
          "timeRegions": [],
          "timeShift": null,
          "title": "MinRTTCalc",
          "tooltip": { "shared": true, "sort": 0, "value_type": "individual" },
          "type": "graph",
          "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] },
          "yaxes": [
            { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true },
            { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true }
          ],
          "yaxis": { "align": false, "alignLevel": null }
        }
      ],
      "refresh": "5s",
      "schemaVersion": 26,
      "style": "dark",
      "tags": [],
      "templating": {
        "list": [
          {
            "current": { "selected": true, "text": "edas120_1217520382582089", "value": "edas120_1217520382582089" },
            "error": null,
            "hide": 0,
            "includeAll": false,
            "label": null,
            "multi": false,
            "name": "cluster",
            "options": [],
            "query": "prometheus",
            "queryValue": "",
            "refresh": 1,
            "regex": "",
            "skipUrlSync": false,
            "type": "datasource"
          },
          {
            "allValue": null,
            "current": { "isNone": true, "selected": false, "text": "None", "value": "" },
            "datasource": "$cluster",
            "definition": "label_values(envoy_http_inbound_0_0_0_0_8080_adaptive_concurrency_gradient_controller_burst_queue_size,service)",
            "error": null,
            "hide": 0,
            "includeAll": false,
            "label": null,
            "multi": false,
            "name": "service",
            "options": [],
            "query": "label_values(envoy_http_inbound_0_0_0_0_8080_adaptive_concurrency_gradient_controller_burst_queue_size,service)",
            "refresh": 2,
            "regex": "",
            "skipUrlSync": false,
            "sort": 1,
            "tagValuesQuery": "",
            "tags": [],
            "tagsQuery": "",
            "type": "query",
            "useTags": false
          },
          {
            "allValue": null,
            "current": { "selected": false, "text": "All", "value": "$__all" },
            "datasource": "$cluster",
            "definition": "label_values(envoy_http_inbound_0_0_0_0_8080_adaptive_concurrency_gradient_controller_concurrency_limit, pod)",
            "error": null,
            "hide": 0,
            "includeAll": true,
            "label": null,
            "multi": true,
            "name": "pod",
            "options": [],
            "query": "label_values(envoy_http_inbound_0_0_0_0_8080_adaptive_concurrency_gradient_controller_concurrency_limit, pod)",
            "refresh": 2,
            "regex": "",
            "skipUrlSync": false,
            "sort": 0,
            "tagValuesQuery": "",
            "tags": [],
            "tagsQuery": "",
            "type": "query",
            "useTags": false
          }
        ]
      },
      "time": { "from": "now-15m", "to": "now" },
      "timepicker": {
        "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
        "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
      },
      "timezone": "",
      "title": "ASM Adaptive Concurrency",
      "uid": "000000084",
      "version": 3
    }

Etapa 4: Verificar o controlador de concorrência

Gere carga contra o testserver para confirmar que a CRD ASMAdaptiveConcurrency limita a concorrência conforme esperado.

  1. Escale o Deployment gotest para 5 réplicas. Com 200 requisições simultâneas por réplica, isso produz 1.000 requisições simultâneas — o dobro da capacidade de 500 requisições do testserver.

    1. Faça login no console do ACK. No painel de navegação à esquerda, clique em Clusters.

    2. Na página Clusters, localize seu cluster e clique no nome dele ou clique em Details na coluna Actions.

    3. No painel de navegação à esquerda, escolha Workloads > Deployments.

    4. Na página Deployments, defina o Namespace como default. Na coluna Actions da aplicação gotest, escolha More > View in YAML.

    5. Na caixa de diálogo Edit YAML, defina replicas como 5 e clique em Update.

  2. Abra o painel do Grafana importado na Etapa 3. Defina Service como testserver e Pod como ALL.

  3. Verifique o painel ConcurrencyLimit. O limite de concorrência deve estabilizar abaixo de 500, confirmando que o controlador protege o testserver contra sobrecarga. O painel RqBlocked mostra a contagem acumulada de requisições rejeitadas.

Referência de métricas

O controlador de concorrência adaptativa expõe as seguintes métricas do Prometheus por meio do sidecar proxy. Utilize-as para monitorar o comportamento do controlador e ajustar os parâmetros da CRD.

Métrica

Tipo

Descrição

rq_blocked

Counter

Total de requisições rejeitadas pelo controlador de concorrência.

burst_queue_size

Gauge

Valor atual de headroom usado no cálculo do limite de concorrência.

concurrency_limit

Gauge

Limite de concorrência atual imposto pelo controlador.

gradient

Gauge

Valor atual do gradiente.

min_rtt_msecs

Gauge

Medição atual do MinRTT em milissegundos.

sample_rtt_msecs

Gauge

Agregado atual do SampleRTT em milissegundos.

min_rtt_calculation_active

Gauge

Definido como 1 quando o controlador está recalculando o MinRTT.

Todas as métricas usam o prefixo de namespace envoy_http_inbound_0_0_0_0_8080_adaptive_concurrency_gradient_controller_.

Aplicar a serviços de produção

  • Ative retentativas: Crie uma destination rule com políticas de retentativa para o serviço de destino, a fim de lidar com respostas 503 durante as janelas de recálculo do MinRTT.

  • Ajuste parâmetros: Modifique concurrency_update_interval, min_concurrency e buffer com base nas observações do painel do Grafana. Um buffer menor torna o controlador mais sensível a mudanças de latência; um valor maior permite mais flutuação.

  • Direcione seus próprios workloads: Substitua os rótulos de workload_selector para atingir seus workloads de produção. Comece com configurações conservadoras (min_concurrency bem abaixo da capacidade esperada) e itere com base nas métricas.