All Products
Search
Document Center

Alibaba Cloud Service Mesh:Gunakan ASMAdaptiveConcurrency untuk menerapkan kontrol konkurensi adaptif

Last Updated:Mar 11, 2026

Pemutusan sirkuit statis mengharuskan Anda memperkirakan dan menetapkan secara manual ambang batas konkurensi tetap untuk setiap layanan. Jika perkiraan terlalu rendah, lalu lintas sah akan diblokir; jika terlalu tinggi, layanan akan kelebihan beban sebelum pemutus sirkuit aktif. CustomResourceDefinition (CRD) ASMAdaptiveConcurrency menghilangkan ketidakpastian ini dengan menyesuaikan batas konkurensi secara dinamis berdasarkan pengukuran latensi waktu nyata, sehingga menjaga batas tersebut mendekati kapasitas aktual layanan tanpa perlu penyetelan manual.

Ketika permintaan konkuren melebihi batas yang dihitung, proxy sidecar mengembalikan kode status HTTP 503 dengan pesan error reached concurrency limit.

Cara kerja

Pengontrol konkurensi adaptif menggunakan algoritma berbasis gradien yang secara berkala mengukur latensi dasar layanan (MinRTT) dan membandingkannya dengan latensi permintaan yang diambil sampelnya (SampleRTT) untuk menyesuaikan batas konkurensi.

Perhitungan gradien

Pengontrol menghitung nilai gradien dari latensi yang diambil sampelnya:

gradient = (minRTT + buffer) / sampleRTT

Buffer menyerap variasi latensi normal, sehingga gradien hanya menurun ketika latensi sampel melebihi garis dasar dalam jumlah yang signifikan:

buffer = minRTT * buffer_pct

Gradien kemudian memperbarui batas konkurensi:

new_limit = gradient * current_limit + headroom

Ketika layanan dalam kondisi sehat, sampleRTT tetap mendekati minRTT, gradien tetap mendekati 1,0, dan batas tetap stabil atau meningkat. Saat layanan mulai kelebihan beban, sampleRTT meningkat, gradien turun di bawah 1,0, dan batas berkurang—menolak permintaan berlebih sebelum layanan mengalami degradasi lebih lanjut.

Perhitungan ulang MinRTT

Pengontrol secara berkala menghitung ulang MinRTT dengan sementara mengurangi batas konkurensi ke nilai min_concurrency. Selama jendela ini, hanya sejumlah kecil permintaan yang diteruskan agar layanan dapat merespons pada latensi minimum sebenarnya.

Penting

Batas konkurensi turun secara signifikan selama perhitungan ulang MinRTT, yang dapat menyebabkan lonjakan respons 503. Untuk mengurangi dampak ini, buat aturan tujuan (destination rule) yang mengaktifkan retry untuk layanan target. Hal ini memungkinkan proxy sidecar melakukan retry terhadap permintaan yang ditolak pada host lain yang tidak sedang dalam jendela perhitungan ulang MinRTT.

Prasyarat

Sebelum memulai, pastikan Anda telah memiliki:

Langkah 1: Deploy aplikasi contoh

Tutorial ini menggunakan dua aplikasi untuk mendemonstrasikan kontrol konkurensi adaptif:

ApplicationRoleConfiguration
testserverTarget serviceMenangani hingga 500 permintaan konkuren, masing-masing memerlukan waktu pemrosesan 1.000 ms. Permintaan yang melebihi batas konkurensi akan masuk antrian.
gotestLoad generatorSetiap replika mengirim 200 permintaan konkuren ke testserver.

Deploy testserver

  1. Buat file bernama testserver.yaml dengan konten berikut:

    View 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

    Flag -m mengatur jumlah maksimum permintaan bersamaan (500). Flag -t mengatur waktu pemrosesan per permintaan dalam milidetik (1.000).

  2. Terapkan Deployment:

    kubectl apply -f testserver.yaml

Buat Service testserver

  1. Buat file bernama testservice.yaml dengan konten berikut:

    View 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. Terapkan Service:

    kubectl apply -f testservice.yaml

Deploy gotest

  1. Buat file bernama gotest.yaml dengan konten berikut:

    View 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

    Jumlah replika awal adalah 0. Tingkatkan jumlahnya di Langkah 4 untuk menghasilkan beban.

  2. Terapkan Deployment:

    kubectl apply -f gotest.yaml

Langkah 2: Buat CRD ASMAdaptiveConcurrency

  1. Hubungkan kubectl ke instans ASM Anda. Untuk informasi selengkapnya, lihat Gunakan kubectl pada lapisan kontrol untuk mengakses resource Istio.

  2. Buat file bernama adaptiveconcurrency.yaml dengan konten berikut:

    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

    Konfigurasi ini dapat dijelaskan sebagai berikut:

    • Targetkan workload testserver dan tetapkan batas atas menjadi 500 permintaan konkuren.

    • Perbarui batas konkurensi setiap 15 detik menggunakan persentil ke-60 dari latensi yang diambil sampelnya sebagai SampleRTT.

    • Hitung ulang MinRTT setiap 60 detik (dengan jitter acak hingga 15%) menggunakan 100 permintaan sampel. Selama perhitungan ulang MinRTT, batasi konkurensi menjadi 50 permintaan.

    • Perlakukan fluktuasi latensi dalam rentang 25% dari MinRTT sebagai hal yang normal.

  3. Terapkan CRD:

    kubectl apply -f adaptiveconcurrency.yaml

Referensi parameter

ParameterTypeRequiredDefaultDescription
workload_selectorWorkloadSelectorYes--Memilih pod target berdasarkan label.
labelsmapYes--Label untuk mencocokkan pod target.
sample_aggregate_percentilePercentYes--Persentil yang digunakan untuk mengagregasi latensi sampel menjadi SampleRTT. Nilai valid: 0 hingga 100.
concurrency_limit_paramsObjectYes--Pengaturan batas konkurensi.
max_concurrency_limitintNo1000Batas atas untuk permintaan konkuren.
concurrency_update_intervaldurationYes--Frekuensi pembaruan batas konkurensi oleh pengontrol. Contoh: 60s.
min_rtt_calc_paramsObjectYes--Pengaturan perhitungan MinRTT.
intervaldurationNo--Frekuensi perhitungan ulang MinRTT. Contoh: 120s.
request_countintNo50Jumlah permintaan yang diambil sampelnya untuk menghitung MinRTT.
jitterPercentNo15Jitter acak yang ditambahkan ke interval perhitungan ulang MinRTT. Misalnya, jika interval adalah 120s dan jitter adalah 50, interval aktualnya adalah random(120, 120 + 120 * 50%) detik.
min_concurrencyintNo3Batas konkurensi selama perhitungan ulang MinRTT. Juga berfungsi sebagai batas awal saat pengontrol dimulai. Tetapkan nilai ini jauh di bawah kapasitas aktual layanan untuk mendapatkan pengukuran garis dasar yang akurat.
bufferPercentNo25Fluktuasi latensi yang dapat diterima sebagai persentase dari MinRTT. Misalnya, jika MinRTT adalah 100 ms dan buffer adalah 10, latensi hingga 110 ms dianggap normal.

Langkah 3: Siapkan pemantauan dengan Prometheus

Ekspor metrik konkurensi adaptif ke Managed Service for Prometheus untuk mengamati perilaku pengontrol dan menyetel parameter.

  1. Aktifkan Managed Service for Prometheus untuk kluster Anda. Untuk informasi selengkapnya, lihat Gunakan Managed Service for Prometheus.

  2. Buat ServiceMonitor untuk mengambil metrik dari proxy sidecar testserver.

    1. Buat file bernama servicemonitor.yaml dengan konten berikut:

      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. Hubungkan kubectl ke kluster ACK dan terapkan ServiceMonitor:

      kubectl apply -f servicemonitor.yaml
  3. Impor Dasbor Grafana untuk memvisualisasikan metrik pengontrol. Unduh JSON dasbor dan impor melalui konsol Managed Service for Grafana. Untuk petunjuk impor, lihat dokumentasi ARMS.

    View 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
    }

Langkah 4: Verifikasi pengontrol konkurensi

Hasilkan beban terhadap testserver untuk memastikan bahwa CRD ASMAdaptiveConcurrency membatasi konkurensi sesuai harapan.

  1. Skalakan Deployment gotest menjadi 5 replika. Dengan 200 permintaan konkuren per replika, ini menghasilkan 1.000 permintaan simultan—dua kali lipat kapasitas testserver sebesar 500 permintaan.

    1. Masuk ke Konsol ACK. Di panel navigasi kiri, klik Clusters.

    2. Di halaman Clusters, temukan kluster Anda dan klik nama kluster tersebut atau klik Details di kolom Actions.

    3. Di panel navigasi kiri, pilih Workloads > Deployments.

    4. Di halaman Deployments, atur Namespace ke default. Di kolom Actions untuk aplikasi gotest, pilih More > View in YAML.

    5. Di kotak dialog Edit YAML, atur replicas menjadi 5 dan klik Update.

  2. Buka Dasbor Grafana yang Anda impor di Langkah 3. Atur Service ke testserver dan Pod ke ALL.

  3. Periksa panel ConcurrencyLimit. Batas konkurensi harus stabil di bawah 500, yang mengonfirmasi bahwa pengontrol melindungi testserver dari kelebihan beban. Panel RqBlocked menampilkan jumlah kumulatif permintaan yang ditolak.

Referensi metrik

Pengontrol konkurensi adaptif mengekspos metrik Prometheus berikut melalui proxy sidecar. Gunakan metrik ini untuk memantau perilaku pengontrol dan menyetel parameter CRD.

MetricTypeDescription
rq_blockedCounterTotal permintaan yang ditolak oleh pengontrol konkurensi.
burst_queue_sizeGaugeNilai headroom saat ini yang digunakan dalam perhitungan batas konkurensi.
concurrency_limitGaugeBatas konkurensi saat ini yang diberlakukan oleh pengontrol.
gradientGaugeNilai gradien saat ini.
min_rtt_msecsGaugePengukuran MinRTT saat ini dalam milidetik.
sample_rtt_msecsGaugeAgregat SampleRTT saat ini dalam milidetik.
min_rtt_calculation_activeGaugeBernilai 1 saat pengontrol sedang menghitung ulang MinRTT.

Semua metrik menggunakan awalan namespace envoy_http_inbound_0_0_0_0_8080_adaptive_concurrency_gradient_controller_.

Terapkan pada layanan produksi

  • Aktifkan retry: Buat destination rule dengan kebijakan retry untuk layanan target guna menangani respons 503 selama jendela perhitungan ulang MinRTT.

  • Setel parameter: Sesuaikan concurrency_update_interval, min_concurrency, dan buffer berdasarkan pengamatan di Dasbor Grafana. Nilai buffer yang lebih kecil membuat pengontrol lebih sensitif terhadap perubahan latensi; nilai yang lebih besar memungkinkan fluktuasi lebih besar.

  • Targetkan workload Anda sendiri: Ganti label workload_selector untuk menargetkan workload produksi Anda. Mulailah dengan pengaturan konservatif (min_concurrency jauh di bawah kapasitas yang diharapkan) dan lakukan iterasi berdasarkan metrik.