Tüm Ürünler
Search
Belge Merkezi

Alibaba Cloud Service Mesh:RateLimitingPolicy kullanarak kullanıcıya özel kısıtlama uygulayın

Son Güncelleme:Oct 07, 2026

Service Mesh (ASM) trafik planlama paketi, belirli bir hizmete yönlendirilen trafik için genel kısıtlama, kullanıcıya özel kısıtlama, ani trafik pencereleri ve özel istek belirteci tüketim oranları gibi gelişmiş kısıtlama özellikleri sunar. RateLimitingPolicy kullanarak kullanıcıya özel kısıtlama uygulayabilirsiniz.

Genel bilgiler

ASM trafik planlama paketinin kısıtlama ilkeleri token bucket algoritmasını kullanır. Sistem sabit bir hızda belirteçler oluşturur ve paket kapasitesine ulaşana kadar bunları bir belirteç paketine ekler. Hizmetler arasındaki istekler paketten belirteç tüketir. Yeterli sayıda belirteç varsa istek işlenir. Belirteç yetersiz kalırsa istek sıraya alınabilir veya reddedilebilir. Bu yaklaşım, ortalama veri iletim hızının belirteç oluşturma hızını aşmamasını sağlarken belirli ölçüde ani trafike izin verir.

image

Ön koşullar

Hazırlıklar

Örnek HTTPBin ve sleep hizmetlerini dağıtın ve sleep hizmetinin HTTPBin hizmetine erişip erişemediğini kontrol edin.

  1. Aşağıdaki içeriği içeren bir httpbin.yaml dosyası oluşturun:

    YAML dosyasını göster

    ##################################################################################################
    # Sample HTTPBin service 
    ##################################################################################################
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: httpbin
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: httpbin
      labels:
        app: httpbin
        service: httpbin
    spec:
      ports:
      - name: http
        port: 8000
        targetPort: 80
      selector:
        app: httpbin
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: httpbin
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: httpbin
          version: v1
      template:
        metadata:
          labels:
            app: httpbin
            version: v1
        spec:
          serviceAccountName: httpbin
          containers:
          - image: registry.cn-hangzhou.aliyuncs.com/acs/httpbin:latest
            imagePullPolicy: IfNotPresent
            name: httpbin
            ports:
            - containerPort: 80
  2. HTTPBin hizmetini dağıtmak için aşağıdaki komutu çalıştırın:

    kubectl apply -f httpbin.yaml -n default
  3. Aşağıdaki içeriği içeren bir sleep.yaml dosyası oluşturun:

    YAML dosyasını göster

    ##################################################################################################
    # Sample sleep service 
    ##################################################################################################
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: sleep
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: sleep
      labels:
        app: sleep
        service: sleep
    spec:
      ports:
      - port: 80
        name: http
      selector:
        app: sleep
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sleep
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: sleep
      template:
        metadata:
          labels:
            app: sleep
        spec:
          terminationGracePeriodSeconds: 0
          serviceAccountName: sleep
          containers:
          - name: sleep
            image: registry.cn-hangzhou.aliyuncs.com/acs/curl:8.1.2
            command: ["/bin/sleep", "infinity"]
            imagePullPolicy: IfNotPresent
            volumeMounts:
            - mountPath: /etc/sleep/tls
              name: secret-volume
          volumes:
          - name: secret-volume
            secret:
              secretName: sleep-secret
              optional: true
    ---
  4. sleep hizmetini dağıtmak için aşağıdaki komutu çalıştırın:

    kubectl apply -f sleep.yaml -n default
  5. sleep pod'una erişmek için aşağıdaki komutu çalıştırın:

    kubectl exec -it deploy/sleep -- sh
  6. HTTPBin hizmetine istek göndermek için aşağıdaki komutu çalıştırın:

    curl -I http://httpbin:8000/headers

    Beklenen çıktı:

    HTTP/1.1 200 OK
    server: envoy
    date: Tue, 26 Dec 2023 07:23:49 GMT
    content-type: application/json
    content-length: 353
    access-control-allow-origin: *
    access-control-allow-credentials: true
    x-envoy-upstream-service-time: 1

    200 OK yanıtı, erişimin başarılı olduğunu gösterir.

Adım 1: RateLimitingPolicy kullanarak bir kısıtlama ilkesi oluşturun

  1. kubectl kullanarak ASM örneğine bağlanın. Daha fazla bilgi için bkz. Kontrol düzleminde kubectl üzerinden Istio kaynaklarına erişme.

  2. Aşağıdaki içeriği içeren bir ratelimitingpolicy.yaml dosyası oluşturun:

    apiVersion: istio.alibabacloud.com/v1
    kind: RateLimitingPolicy
    metadata:
      name: ratelimit
      namespace: istio-system
    spec:
      rate_limiter:
        bucket_capacity: 2
        fill_amount: 2
        parameters:
          interval: 30s
          limit_by_label_key: http.request.header.user_id
        selectors:
        - agent_group: default
          control_point: ingress
          service: httpbin.default.svc.cluster.local

    Aşağıdaki tabloda bazı alanlar açıklanmaktadır. Daha fazla bilgi için bkz. RateLimitingPolicy alan referansı.


    Alan


    Açıklama


    fill_amount


    interval alanında belirtilen her zaman aralığında pakete eklenen belirteç sayısıdır. Bu örnekte değer 2'dir; bu, her aralıktan sonra iki belirtecin eklendiği anlamına gelir.


    interval


    Belirteçlerin belirteç paketine eklendiği aralıktır. Bu örnekte değer 30s'dir; bu, her 30 saniyede bir iki belirtecin eklendiği anlamına gelir.


    bucket_capacity


    Belirteç paketindeki maksimum belirteç sayısıdır. İstek oranı doldurma hızından düşük olduğunda, belirteçler bucket_capacity değerine ulaşana kadar birikir. Daha yüksek bir bucket_capacity değeri, belirli ölçüde ani trafike izin verir. Bu örnekte değer fill_amount ile aynı şekilde 2'dir, dolayısıyla ani trafiğe izin verilmez.


    limit_by_label_key


    Kısıtlama ilkesi için istekleri gruplandırmada kullanılan etiket anahtarıdır. Farklı etiket değerlerine sahip istekler bağımsız belirteç paketleri kullanılarak ayrı ayrı kısıtlanır. Bu örnekte, http.request.header.user_id istekleri user_id istek üstbilgisine göre gruplandırarak kullanıcıya özel kısıtlamayı simüle eder. Bu örnek, farklı kullanıcılardan gelen isteklerin farklı used_id istek üstbilgilerine sahip olduğunu varsayar.


    selectors


    Kısıtlama ilkesinin uygulandığı hizmetlerdir. Bu örnekte, service: httpbin.default.svc.cluster.local kısıtlamayı httpbin.default.svc.cluster.local hizmetine uygular.

  1. RateLimitingPolicy kullanarak bir kısıtlama ilkesi oluşturmak için aşağıdaki komutu çalıştırın:

    kubectl apply -f ratelimitingpolicy.yaml

Adım 2: Kullanıcıya özel kısıtlama sonucunu doğrulayın

  1. kubectl kullanarak ACK kümesine bağlanın ve ardından sleep hizmeti için bash kabuğunu başlatmak üzere aşağıdaki komutu çalıştırın:

    kubectl exec -it deploy/sleep -- sh
  2. user1 olarak HTTPBin hizmetinin /headers yoluna art arda iki kez erişmek için aşağıdaki komutları çalıştırın:

    curl -H "user_id: user1" httpbin:8000/headers -v
    curl -H "user_id: user1" httpbin:8000/headers -v

    Beklenen çıktı:

    < HTTP/1.1 429 Too Many Requests
    < retry-after: 14
    < date: Mon, 17 Jun 2024 11:48:53 GMT
    < server: envoy
    < content-length: 0
    < x-envoy-upstream-service-time: 1
    <
    * Connection #0 to host httpbin left intact
  3. Önceki adımın yürütülmesinden sonraki 30 saniye içinde, user2 olarak HTTPBin hizmetinin /headers yoluna bir kez erişmek için aşağıdaki komutu çalıştırın:

    curl -H "user_id: user2" httpbin:8000/headers -v

    Beklenen çıktı:

    < HTTP/1.1 200 OK
    < server: envoy
    < date: Mon, 17 Jun 2024 12:42:17 GMT
    < content-type: application/json
    < content-length: 378
    < access-control-allow-origin: *
    < access-control-allow-credentials: true
    < x-envoy-upstream-service-time: 5
    <
    {
      "headers": {
        "Accept": "*/*",
        "Host": "httpbin:8000",
        "User-Agent": "curl/8.1.2",
        "User-Id": "user2",
        "X-Envoy-Attempt-Count": "1",
        "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=ddab183a1502e5ededa933f83e90d3d5266e2ddf87555fb3da1ad40dde3c722e;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep"
      }
    }
    * Connection #0 to host httpbin left intact

    Çıktı, aynı yola erişen user2 için kısıtlamanın tetiklenmediğini gösterir; bu da kullanıcıya özel kısıtlamanın beklendiği gibi çalıştığını doğrular.

İlgili konular

RateLimitingPolicy'nin etkili olup olmadığını Grafana'da doğrulayabilirsiniz. Grafana için Prometheus örneğinin ASM trafik planlama paketi ile yapılandırıldığından emin olun.

Bir RateLimitingPolicy panosu oluşturmak için aşağıdaki içeriği Grafana'ya aktarın.

Ayrıntıları görüntülemek için tıklayın

{
  "annotations": {
    "list": [
      {
        "builtIn": 1,
        "datasource": {
          "type": "grafana",
          "uid": "-- Grafana --"
        },
        "enable": true,
        "hide": true,
        "iconColor": "rgba(0, 211, 255, 1)",
        "name": "Annotations & Alerts",
        "type": "dashboard"
      }
    ]
  },
  "editable": true,
  "fiscalYearStartMonth": 0,
  "graphTooltip": 0,
  "id": 38,
  "links": [],
  "liveNow": false,
  "panels": [
    {
      "datasource": {
        "type": "prometheus",
        "uid": "${datasource}"
      },
      "description": "Signal derived from periodic execution of query: (sum(rate(rate_limiter_counter_total{policy_name=\"ratelimit\",component_id=\"root.0\",decision_type=\"DECISION_TYPE_ACCEPTED\"}[30s])) / sum(rate(rate_limiter_counter_total{policy_name=\"ratelimit\",component_id=\"root.0\"}[30s]))) * 100",
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "palette-classic"
          },
          "custom": {
            "axisCenteredZero": false,
            "axisColorMode": "text",
            "axisLabel": "",
            "axisPlacement": "auto",
            "barAlignment": 0,
            "drawStyle": "line",
            "fillOpacity": 10,
            "gradientMode": "none",
            "hideFrom": {
              "legend": false,
              "tooltip": false,
              "viz": false
            },
            "lineInterpolation": "linear",
            "lineWidth": 1,
            "pointSize": 5,
            "scaleDistribution": {
              "type": "linear"
            },
            "showPoints": "auto",
            "spanNulls": false,
            "stacking": {
              "group": "A",
              "mode": "none"
            },
            "thresholdsStyle": {
              "mode": "off"
            }
          },
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "red",
                "value": 80
              }
            ]
          },
          "unit": ""
        },
        "overrides": []
      },
      "gridPos": {
        "h": 10,
        "w": 24,
        "x": 0,
        "y": 0
      },
      "id": 1,
      "interval": "10s",
      "options": {
        "legend": {
          "calcs": [],
          "displayMode": "list",
          "placement": "bottom",
          "showLegend": true
        },
        "tooltip": {
          "mode": "single",
          "sort": "none"
        }
      },
      "pluginVersion": "v10.1.0",
      "targets": [
        {
          "datasource": {
            "type": "prometheus",
            "uid": "${datasource}"
          },
          "editorMode": "code",
          "expr": "(sum by (policy_name) (rate(rate_limiter_counter_total{component_id=\"root.0\",decision_type=\"DECISION_TYPE_ACCEPTED\"}[30s])) / sum by (policy_name) (rate(rate_limiter_counter_total{component_id=\"root.0\"}[30s]))) * 100",
          "intervalFactor": 1,
          "legendFormat": "policy_name={{policy_name}}",
          "range": true,
          "refId": "A"
        }
      ],
      "title": "Accept percentage",
      "type": "timeseries"
    },
    {
      "datasource": {
        "type": "prometheus",
        "uid": "${datasource}"
      },
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "thresholds"
          },
          "mappings": [],
          "noValue": "No data",
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "blue",
                "value": null
              }
            ]
          },
          "unit": "short"
        },
        "overrides": []
      },
      "gridPos": {
        "h": 10,
        "w": 8,
        "x": 0,
        "y": 10
      },
      "id": 2,
      "options": {
        "colorMode": "value",
        "graphMode": "area",
        "justifyMode": "center",
        "orientation": "horizontal",
        "reduceOptions": {
          "calcs": [
            "lastNotNull"
          ],
          "fields": "",
          "values": false
        },
        "textMode": "auto"
      },
      "pluginVersion": "10.0.9",
      "targets": [
        {
          "datasource": {
            "type": "prometheus",
            "uid": "${datasource}"
          },
          "editorMode": "code",
          "expr": "sum by (policy_name) (increase(rate_limiter_counter_total{component_id=\"root.0\"}[$__range]))",
          "instant": false,
          "intervalFactor": 1,
          "legendFormat": "{{ policy_name }}",
          "range": true,
          "refId": "A"
        }
      ],
      "title": "Total Requests",
      "type": "stat"
    },
    {
      "datasource": {
        "type": "prometheus",
        "uid": "${datasource}"
      },
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "thresholds"
          },
          "mappings": [],
          "noValue": "No data",
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              }
            ]
          },
          "unit": "short"
        },
        "overrides": []
      },
      "gridPos": {
        "h": 10,
        "w": 8,
        "x": 8,
        "y": 10
      },
      "id": 3,
      "options": {
        "colorMode": "value",
        "graphMode": "area",
        "justifyMode": "center",
        "orientation": "horizontal",
        "reduceOptions": {
          "calcs": [
            "lastNotNull"
          ],
          "fields": "",
          "values": false
        },
        "textMode": "auto"
      },
      "pluginVersion": "10.0.9",
      "targets": [
        {
          "datasource": {
            "type": "prometheus",
            "uid": "${datasource}"
          },
          "editorMode": "code",
          "expr": "sum by (policy_name) (increase(rate_limiter_counter_total{component_id=\"root.0\", decision_type=\"DECISION_TYPE_ACCEPTED\"}[$__range]))",
          "instant": false,
          "intervalFactor": 1,
          "legendFormat": "{{ policy_name }}",
          "range": true,
          "refId": "A"
        }
      ],
      "title": "Total Accepted Requests",
      "type": "stat"
    },
    {
      "datasource": {
        "type": "prometheus",
        "uid": "${datasource}"
      },
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "thresholds"
          },
          "mappings": [],
          "noValue": "No rejected requests",
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "red",
                "value": null
              }
            ]
          },
          "unit": "short"
        },
        "overrides": []
      },
      "gridPos": {
        "h": 10,
        "w": 8,
        "x": 16,
        "y": 10
      },
      "id": 4,
      "options": {
        "colorMode": "value",
        "graphMode": "area",
        "justifyMode": "center",
        "orientation": "horizontal",
        "reduceOptions": {
          "calcs": [
            "lastNotNull"
          ],
          "fields": "",
          "values": false
        },
        "textMode": "auto"
      },
      "pluginVersion": "10.0.9",
      "targets": [
        {
          "datasource": {
            "type": "prometheus",
            "uid": "${datasource}"
          },
          "editorMode": "code",
          "expr": "sum by (policy_name) (increase(rate_limiter_counter_total{component_id=\"root.0\", decision_type=\"DECISION_TYPE_REJECTED\"}[$__range]))",
          "instant": false,
          "intervalFactor": 1,
          "legendFormat": "{{policy_name}}",
          "range": true,
          "refId": "A"
        }
      ],
      "title": "Total Rejected Requests",
      "type": "stat"
    },
    {
      "datasource": {
        "type": "prometheus",
        "uid": "${datasource}"
      },
      "description": "",
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "palette-classic"
          },
          "custom": {
            "axisCenteredZero": false,
            "axisColorMode": "text",
            "axisLabel": "Decisions",
            "axisPlacement": "auto",
            "barAlignment": 0,
            "drawStyle": "line",
            "fillOpacity": 10,
            "gradientMode": "none",
            "hideFrom": {
              "legend": false,
              "tooltip": false,
              "viz": false
            },
            "lineInterpolation": "linear",
            "lineWidth": 1,
            "pointSize": 5,
            "scaleDistribution": {
              "type": "linear"
            },
            "showPoints": "auto",
            "spanNulls": false,
            "stacking": {
              "group": "A",
              "mode": "none"
            },
            "thresholdsStyle": {
              "mode": "off"
            }
          },
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "red",
                "value": 80
              }
            ]
          },
          "unit": "reqps"
        },
        "overrides": []
      },
      "gridPos": {
        "h": 10,
        "w": 24,
        "x": 0,
        "y": 20
      },
      "id": 5,
      "interval": "10s",
      "options": {
        "legend": {
          "calcs": [],
          "displayMode": "list",
          "placement": "bottom",
          "showLegend": true
        },
        "tooltip": {
          "mode": "single",
          "sort": "none"
        }
      },
      "pluginVersion": "v10.1.0",
      "targets": [
        {
          "datasource": {
            "type": "prometheus",
            "uid": "${datasource}"
          },
          "editorMode": "code",
          "expr": "sum by(decision_type, policy_name) (rate(rate_limiter_counter_total{component_id=\"root.0\"}[$__rate_interval]))",
          "intervalFactor": 1,
          "range": true,
          "refId": "A"
        }
      ],
      "title": "Rate Limiter Decision Overview",
      "type": "timeseries"
    }
  ],
  "refresh": "",
  "schemaVersion": 38,
  "style": "dark",
  "tags": [],
  "templating": {
    "list": [
      {
        "hide": 0,
        "includeAll": false,
        "label": "Data Source",
        "multi": false,
        "name": "datasource",
        "options": [],
        "query": "prometheus",
        "queryValue": "",
        "refresh": 1,
        "regex": "",
        "skipUrlSync": false,
        "type": "datasource"
      }
    ]
  },
  "time": {
    "from": "now-1h",
    "to": "now"
  },
  "timepicker": {},
  "timezone": "browser",
  "title": "Policy Summary - ratelimit",
  "version": 15,
  "weekStart": ""
}

Aşağıdaki görselde pano gösterilmektedir.

image