专栏名称: 阿里云云原生
发布云原生技术最新资讯、汇集云原生技术最全内容,定期举办云原生活动、直播,阿里产品及用户最佳实践发布。与你并肩探索云原生技术点滴,分享你需要的云原生内容。
目录
相关文章推荐
财联社AI daily  ·  AI会玩宝可梦了!Claude打赢道馆馆主 ·  4 小时前  
财联社AI daily  ·  AI会玩宝可梦了!Claude打赢道馆馆主 ·  4 小时前  
51好读  ›  专栏  ›  阿里云云原生

在服务网格中为应用配置限流规则的最佳实践

阿里云云原生  · 公众号  ·  · 2024-07-14 09:00

正文

限流防护是一种限制发送到服务端的请求数量的机制。它指定客户端在给定时间段内可以向服务端发送的最大请求数,通常表示为一段时间内的请求数,例如每分钟 300 个请求或每秒 10 个请求等。限流的目的是防止服务因来自同一客户端 IP 或来自任何客户端的全局请求而过载。以每分钟 300 个请求的限流机制为例,向服务发送 301 个请求,限流器将拒绝第 301 个请求。同时,限流器会返回一个 429 HTTP 状态码(Too Many Requests),并在请求到达服务之前进行拒绝。

网格代理 Envoy 支持两种类型的限流防护方式:本地限流和全局限流。本地限流用于限制每个服务实例的请求速率。全局限流使用全局的 gRPC 服务为整个网格提供限流能力。本地限流可以与全局限流结合使用,以提供不同层面的限流功能。

服务网格通过令牌桶算法来实现限流。令牌桶算法是一种限制发送到服务端的请求数量的方法,基于一定数量的令牌桶。存储桶以恒定的速率不断填充令牌,当向服务发送请求时,会从存储桶中删除一个令牌。如果存储桶为空,则请求将被拒绝。

本文以云原生应用 demo boutique 应用为例,介绍在服务网格中为不同应用配置全局限流以及本地限流的最佳实践。

前提条件




Cloud Native

  • 已添加 Kubernetes 托管版集群到 ASM 实例,且 ASM 实例为 1.18.0.131 及以上。具体操作,请参见添加集群到 ASM 实例 [ 1]

  • 已为 Kubernetes 集群中的 default 命名空间开启自动注入。具体操作,请参见启用自动注入 [ 2]

  • 已创建名为 ingressgateway 的入口网关,并开启 8000 端口。具体操作,请参见创建入口网关 [ 3]

01

部署应用

Cloud Native


1. 部署 boutique 应用
boutique 是一个以云原生架构部署的实例应用程序,由 11 个服务组成。

在部署应用后,访问应用将会得到一个仿真的电子商店应用,包含查看商品列表、加入购物车、下单等功能。本文将以该应用为例,演示服务网格限流在实际应用中起到的效果。

首先创建 demo 命名空间以部署应用,同步至 ASM 全局命名空间,并开启自动注入。有关如何向服务网格 ASM 的全局命名空间进行同步,以及如何为命名空间开启自动注入,可以参考管理全局命名空间 [ 4]
kubectl create namespace demo

使用以下内容创建 boutique.yaml:

apiVersion: apps/v1




    
kind: Deploymentmetadata:  name: emailservicespec:  selector:    matchLabels:      app: emailservice  template:    metadata:      labels:        app: emailservice    spec:      serviceAccountName: default      terminationGracePeriodSeconds: 5      securityContext:




    
        fsGroup: 1000        runAsGroup: 1000        runAsNonRoot: true        runAsUser: 1000      containers:      - name: server        securityContext:          allowPrivilegeEscalation: false          capabilities:            drop:              - ALL          privileged: false          readOnlyRootFilesystem: true        image: registry.cn-shanghai.aliyuncs.com/asm-samples/emailservice:v0.9.0-aliyun        imagePullPolicy: Always        ports:        - containerPort: 8080        env:        - name: PORT          value: "8080"        - name: DISABLE_PROFILER          value: "1"        readinessProbe:          periodSeconds: 5          grpc:            port: 8080        livenessProbe:          periodSeconds: 5          grpc:            port: 8080        resources:          requests:            cpu: 100m            memory: 64Mi          limits:            cpu: 200m            memory: 128Mi---apiVersion: v1kind: Servicemetadata:  name: emailservicespec:  type: ClusterIP  selector:    app: emailservice  ports:  - name: grpc    port: 5000    targetPort: 8080---apiVersion: apps/v1kind: Deploymentmetadata:  name: checkoutservicespec:  selector:    matchLabels:      app: checkoutservice  template:    metadata:      labels:        app: checkoutservice    spec:      serviceAccountName: default      securityContext:        fsGroup: 1000        runAsGroup: 1000        runAsNonRoot: true        runAsUser: 1000      containers:        - name: server          securityContext:            allowPrivilegeEscalation: false            capabilities:              drop:                - ALL            privileged: false            readOnlyRootFilesystem: true          image: registry.cn-shanghai.aliyuncs.com/asm-samples/checkoutservice:v0.9.0-aliyun          imagePullPolicy: Always          ports:          - containerPort: 5050          readinessProbe:            grpc:              port: 5050          livenessProbe:            grpc:              port: 5050          env:          - name: PORT            value: "5050"          - name: PRODUCT_CATALOG_SERVICE_ADDR            value: "productcatalogservice:3550"          - name: SHIPPING_SERVICE_ADDR            value: "shippingservice:50051"          - name: PAYMENT_SERVICE_ADDR            value: "paymentservice:50051"          - name: EMAIL_SERVICE_ADDR            value: "emailservice:5000"          - name: CURRENCY_SERVICE_ADDR            value: "currencyservice:7000"          - name: CART_SERVICE_ADDR            value: "cartservice:7070"          resources:            requests:              cpu: 100m              memory: 64Mi            limits:              cpu: 200m              memory: 128Mi---apiVersion: v1kind: Servicemetadata:  name: checkoutservicespec:  type: ClusterIP  selector:    app: checkoutservice  ports:  - name: grpc    port: 5050    targetPort: 5050---apiVersion: apps/v1kind: Deploymentmetadata:  name: recommendationservicespec:  selector:    matchLabels:      app: recommendationservice  template:    metadata:      labels:        app: recommendationservice    spec:      serviceAccountName: default      terminationGracePeriodSeconds: 5      securityContext:        fsGroup: 1000        runAsGroup: 1000        runAsNonRoot: true        runAsUser: 1000      containers:      - name: server        securityContext:          allowPrivilegeEscalation: false          capabilities:            drop:              - ALL          privileged: false          readOnlyRootFilesystem: true        image: registry.cn-shanghai.aliyuncs.com/asm-samples/recommendationservice:v0.9.0-aliyun        imagePullPolicy: Always        ports:        - containerPort: 8080        readinessProbe:          periodSeconds: 5          grpc:            port: 8080        livenessProbe:          periodSeconds: 5          grpc:            port: 8080        env:        - name: PORT          value: "8080"        - name: PRODUCT_CATALOG_SERVICE_ADDR          value: "productcatalogservice:3550"        - name: DISABLE_PROFILER          value: "1"        resources:          requests:            cpu: 100m            memory: 220Mi          limits:            cpu: 200m            memory: 450Mi---apiVersion: v1kind: Servicemetadata:  name: recommendationservicespec:  type: ClusterIP  selector:    app: recommendationservice  ports:  - name: grpc    port: 8080    targetPort: 8080---apiVersion: apps/v1kind: Deploymentmetadata:  name: frontendspec:  selector:    matchLabels:      app: frontend  template:    metadata:      labels:        app: frontend      annotations:        sidecar.istio.io/rewriteAppHTTPProbers: "true"    spec:      serviceAccountName: default      securityContext:        fsGroup: 1000        runAsGroup: 1000        runAsNonRoot: true        runAsUser: 1000      containers:        - name: server          securityContext:            allowPrivilegeEscalation: false            capabilities:              drop:                - ALL            privileged: false            readOnlyRootFilesystem: true          image: registry.cn-shanghai.aliyuncs.com/asm-samples/frontend:v0.9.0-1-aliyun          imagePullPolicy: Always          ports:          - containerPort: 8080          readinessProbe:            initialDelaySeconds: 10            httpGet:              path: "/_healthz"              port: 8080              httpHeaders:              - name: "Cookie"                value: "shop_session-id=x-readiness-probe"          livenessProbe:            initialDelaySeconds: 10            httpGet:              path: "/_healthz"              port: 8080              httpHeaders:              - name: "Cookie"                value: "shop_session-id=x-liveness-probe"          env:          - name: PORT            value: "8080"          - name: PRODUCT_CATALOG_SERVICE_ADDR




    
            value: "productcatalogservice:3550"          - name: CURRENCY_SERVICE_ADDR            value: "currencyservice:7000"          - name: CART_SERVICE_ADDR            value: "cartservice:7070"          - name: RECOMMENDATION_SERVICE_ADDR            value: "recommendationservice:8080"          - name: SHIPPING_SERVICE_ADDR            value: "shippingservice:50051"          - name: CHECKOUT_SERVICE_ADDR            value: "checkoutservice:5050"          - name: AD_SERVICE_ADDR            value: "adservice:9555"          # # ENV_PLATFORM: One of: local, gcp, aws, azure, onprem, alibaba          # # When not set, defaults to "local" unless running in GKE, otherwies auto-sets to gcp          - name: ENV_PLATFORM            value: "alibaba"          - name: ENABLE_PROFILER            value: "0"          # - name: CYMBAL_BRANDING          #   value: "true"          # - name: FRONTEND_MESSAGE          #   value: "Replace this with a message you want to display on all pages."          resources:            requests:              cpu: 100m              memory: 64Mi            limits:              cpu: 200m              memory: 128Mi---apiVersion: v1kind: Servicemetadata:  name: frontendspec:  type: ClusterIP  selector:    app: frontend  ports:  - name: http    port: 80    targetPort: 8080---apiVersion: v1kind: Servicemetadata:  name: frontend-externalspec:  type: LoadBalancer  selector:    app: frontend  ports:  - name: http    port: 80    targetPort: 8080---apiVersion: apps/v1kind: Deploymentmetadata:  name: paymentservicespec:  selector:    matchLabels:      app: paymentservice  template:    metadata:      labels:        app: paymentservice    spec:      serviceAccountName: default      terminationGracePeriodSeconds: 5      securityContext:        fsGroup: 1000        runAsGroup: 1000        runAsNonRoot: true        runAsUser: 1000      containers:      - name: server        securityContext:          allowPrivilegeEscalation: false          capabilities:            drop:              - ALL          privileged: false          readOnlyRootFilesystem: true        image: registry.cn-shanghai.aliyuncs.com/asm-samples/paymentservice:v0.9.0-aliyun        imagePullPolicy: Always        ports:        - containerPort: 50051        env:        - name: PORT          value: "50051"        - name: DISABLE_PROFILER          value: "1"        readinessProbe:          grpc:            port: 50051        livenessProbe:          grpc:            port: 50051        resources:          requests:            cpu: 100m            memory: 64Mi          limits:            cpu: 200m            memory: 128Mi---apiVersion: v1kind: Servicemetadata:  name: paymentservicespec:  type: ClusterIP  selector:    app: paymentservice  ports:  - name: grpc    port: 50051    targetPort: 50051---apiVersion: apps/v1kind: Deploymentmetadata:  name: productcatalogservicespec:  selector:    matchLabels:      app: productcatalogservice  template:    metadata:      labels:        app: productcatalogservice    spec:      serviceAccountName: default      terminationGracePeriodSeconds: 5      securityContext:        fsGroup: 1000        runAsGroup: 1000        runAsNonRoot: true        runAsUser: 1000      containers:      - name: server        securityContext:          allowPrivilegeEscalation: false          capabilities:            drop:              - ALL          privileged: false          readOnlyRootFilesystem: true        image: registry.cn-shanghai.aliyuncs.com/asm-samples/productcatalogservice:v0.9.0-aliyun        imagePullPolicy: Always        ports:        - containerPort: 3550        env:        - name: PORT          value: "3550"        - name: DISABLE_PROFILER          value: "1"        readinessProbe:          grpc:            port: 3550        livenessProbe:          grpc:            port: 3550        resources:          requests:            cpu: 100m            memory: 64Mi          limits:            cpu: 200m            memory: 128Mi---apiVersion: v1kind: Servicemetadata:  name: productcatalogservicespec:  type: ClusterIP  selector:    app: productcatalogservice  ports:  - name: grpc    port: 3550    targetPort: 3550---apiVersion: apps/v1kind: Deploymentmetadata:  name: cartservicespec:  selector:    matchLabels:      app: cartservice  template:    metadata:      labels:        app: cartservice    spec:      serviceAccountName: default      terminationGracePeriodSeconds: 5      securityContext:        fsGroup: 1000        runAsGroup: 1000        runAsNonRoot: true        runAsUser: 1000      containers:      - name: server        securityContext:          allowPrivilegeEscalation: false          capabilities:            drop:              - ALL          privileged: false          readOnlyRootFilesystem: true        image: registry.cn-shanghai.aliyuncs.com/asm-samples/cartservice:v0.9.0-aliyun        imagePullPolicy: Always        ports:        - containerPort: 7070        env:        - name: REDIS_ADDR          value: "redis-cart:6379"        resources:          requests:            cpu: 200m            memory: 64Mi          limits:            cpu: 300m            memory: 128Mi        readinessProbe:          initialDelaySeconds: 15          grpc:            port: 7070        livenessProbe:          initialDelaySeconds: 15          periodSeconds: 10          grpc:            port: 7070---apiVersion: v1kind: Servicemetadata:  name: cartservicespec:  type: ClusterIP  selector:    app: cartservice  ports:  - name: grpc    port: 7070    targetPort: 7070




    
---apiVersion: apps/v1kind: Deploymentmetadata:  name: loadgeneratorspec:  selector:    matchLabels:      app: loadgenerator  replicas: 0  template:    metadata:      labels:        app: loadgenerator      annotations:        sidecar.istio.io/rewriteAppHTTPProbers: "true"    spec:      serviceAccountName: default      terminationGracePeriodSeconds: 5      restartPolicy: Always      securityContext:        fsGroup: 1000        runAsGroup: 1000        runAsNonRoot: true        runAsUser: 1000      initContainers:      - command:        - /bin/sh        - -exc        - |          echo "Init container pinging frontend: ${FRONTEND_ADDR}..."          STATUSCODE=$(wget --server-response http://${FRONTEND_ADDR} 2>&1 | awk '/^  HTTP/{print $2}')          if test $STATUSCODE -ne 200; then              echo "Error: Could not reach frontend - Status code: ${STATUSCODE}"              exit 1          fi        name: frontend-check        securityContext:          allowPrivilegeEscalation: false          capabilities:            drop:              - ALL          privileged: false          readOnlyRootFilesystem: true        image: registry-cn-hangzhou.ack.aliyuncs.com/dev/busybox:latest        env:        - name: FRONTEND_ADDR          value: "frontend:80"      containers:      - name: main        securityContext:          allowPrivilegeEscalation: false          capabilities:            drop:              - ALL          privileged: false          readOnlyRootFilesystem: true        image: registry.cn-shanghai.aliyuncs.com/asm-samples/loadgenerator:v0.9.0-aliyun        imagePullPolicy: Always        env:        - name: FRONTEND_ADDR          value: "frontend:80"        - name: USERS          value: "10"        resources:          requests:            cpu: 300m            memory: 256Mi          limits:            cpu: 500m            memory: 512Mi---apiVersion: apps/v1kind: Deploymentmetadata:  name: currencyservicespec:  selector:    matchLabels:      app: currencyservice  template:    metadata:      labels:        app: currencyservice    spec:      serviceAccountName: default      terminationGracePeriodSeconds: 5      securityContext:        fsGroup: 1000        runAsGroup: 1000        runAsNonRoot: true        runAsUser: 1000      containers:      - name: server        securityContext:          allowPrivilegeEscalation: false          capabilities:            drop:              - ALL          privileged: false          readOnlyRootFilesystem: true        image: registry.cn-shanghai.aliyuncs.com/asm-samples/currencyservice:v0.9.0-aliyun        imagePullPolicy: Always        ports:        - name: grpc          containerPort: 7000        env:        - name: PORT          value: "7000"        - name: DISABLE_PROFILER          value: "1"        readinessProbe:          grpc:            port: 7000        livenessProbe:          grpc:            port: 7000        resources:          requests:            cpu: 100m            memory: 64Mi          limits:            cpu: 200m            memory: 128Mi---apiVersion: v1kind: Servicemetadata:  name: currencyservicespec:  type: ClusterIP  selector:    app: currencyservice  ports:  - name: grpc    port: 7000    targetPort: 7000---apiVersion: apps/v1kind: Deploymentmetadata:  name: shippingservicespec:  selector:    matchLabels:      app: shippingservice  template:    metadata:      labels:        app: shippingservice    spec:      serviceAccountName: default      securityContext:        fsGroup: 1000        runAsGroup: 1000        runAsNonRoot: true        runAsUser: 1000      containers:      - name: server        securityContext:          allowPrivilegeEscalation: false          capabilities:            drop:              - ALL          privileged: false          readOnlyRootFilesystem: true        image: registry.cn-shanghai.aliyuncs.com/asm-samples/shippingservice:v0.9.0-aliyun        imagePullPolicy: Always        ports:        - containerPort: 50051        env:        - name: PORT          value: "50051"        - name: DISABLE_PROFILER          value: "1"        readinessProbe:          periodSeconds: 5          grpc:            port: 50051        livenessProbe:          grpc:            port: 50051        resources:          requests:            cpu: 100m            memory: 64Mi          limits:            cpu: 200m            memory: 128Mi---apiVersion: v1kind: Servicemetadata:  name: shippingservicespec:  type: ClusterIP  selector:    app: shippingservice  ports:  - name: grpc    port: 50051    targetPort: 50051---apiVersion: apps/v1kind: Deploymentmetadata:  name: redis-cartspec:  selector:    matchLabels:      app: redis-cart  template:    metadata:      labels:        app: redis-cart    spec:      securityContext:        fsGroup: 1000        runAsGroup: 1000        runAsNonRoot: true        runAsUser: 1000      containers:      - name: redis        securityContext:          allowPrivilegeEscalation: false          capabilities:            drop:              - ALL          privileged: false          readOnlyRootFilesystem: true        image: registry-cn-hangzhou.ack.aliyuncs.com/dev/redis:alpine        ports:        - containerPort: 6379        readinessProbe:          periodSeconds: 5          tcpSocket:            port: 6379        livenessProbe:          periodSeconds: 5          tcpSocket:            port: 6379        volumeMounts:        - mountPath: /data          name: redis-data        resources:          limits:            memory: 256Mi            cpu: 125m          requests:            cpu: 70m            memory: 200Mi




    
      volumes:      - name: redis-data        emptyDir: {}---apiVersion: v1kind: Servicemetadata:  name: redis-cartspec:  type: ClusterIP  selector:    app: redis-cart  ports:  - name: tcp-redis    port: 6379    targetPort: 6379---apiVersion: apps/v1kind: Deploymentmetadata:  name: adservicespec:  selector:    matchLabels:      app: adservice  template:    metadata:      labels:        app: adservice    spec:      serviceAccountName: default      terminationGracePeriodSeconds: 5      securityContext:        fsGroup: 1000        runAsGroup: 1000        runAsNonRoot: true        runAsUser: 1000      containers:      - name: server        securityContext:          allowPrivilegeEscalation: false          capabilities:            drop:              - ALL          privileged: false          readOnlyRootFilesystem: true        image: registry.cn-shanghai.aliyuncs.com/asm-samples/adservice:v0.9.0-aliyun        imagePullPolicy: Always        ports:        - containerPort: 9555        env:        - name: PORT          value: "9555"        resources:          requests:            cpu: 200m            memory: 180Mi          limits:            cpu: 300m            memory: 300Mi        readinessProbe:          initialDelaySeconds: 20          periodSeconds: 15          grpc:            port: 9555        livenessProbe:          initialDelaySeconds: 20          periodSeconds: 15          grpc:            port: 9555---apiVersion: v1kind: Servicemetadata:  name: adservicespec:  type: ClusterIP  selector:    app: adservice  ports:  - name: grpc    port: 9555    targetPort: 9555

执行指令创建应用:

kubectl apply -f boutique.yaml -n demo

使用以下内容创建 boutique-gateway.yaml:

apiVersion: networking.istio.io/v1beta1kind: Gatewaymetadata:  name: boutique-gatewayspec:  selector:    istio: ingressgateway  servers:    - hosts:        - '*'      port:        name: http        number: 8000        protocol: HTTP---apiVersion: networking.istio.io/v1beta1kind: VirtualServicemetadata:  name: boutiquespec:  gateways:    - boutique-gateway  hosts:    - '*'  http:    - name: boutique-route      route:        - destination:            host: frontend

执行指令创建应用的路由规则:

kubectl apply -f boutique-gateway.yaml -n demo

2. 部署作为示例的全局限流服务
apiVersion: v1kind: ServiceAccountmetadata:  name: redis---apiVersion: v1kind: Servicemetadata:  name: redis  labels:    app: redisspec:  ports:  - name: redis    port: 6379  selector:    app: redis---apiVersion: apps/v1kind: Deploymentmetadata:  name: redisspec:  replicas: 1  selector:    matchLabels:      app: redis  template:   metadata:      labels:        app: redis        sidecar.istio.io/inject: "false"   spec:      containers:      - image: registry-cn-hangzhou.ack.aliyuncs.com/dev/redis:alpine        imagePullPolicy: Always        name: redis        ports:        - name: redis          containerPort: 6379      restartPolicy: Always      serviceAccountName: redis---apiVersion: v1kind: ConfigMapmetadata:  name: ratelimit-configdata:  config.yaml: |    {}---apiVersion: v1kind: Servicemetadata:




    
  name: ratelimit  labels:    app: ratelimitspec:  ports:  - name: http-port    port: 8080    targetPort: 8080    protocol: TCP  - name: grpc-port    port: 8081    targetPort: 8081    protocol: TCP  - name: http-debug    port: 6070    targetPort: 6070    protocol: TCP  selector:    app: ratelimit---apiVersion: apps/v1kind: Deploymentmetadata:  name: ratelimitspec:  replicas: 1  selector:    matchLabels:      app: ratelimit  strategy:    type: Recreate  template:    metadata:      labels:        app: ratelimit        sidecar.istio.io/inject: "false"    spec:      containers:        # Latest image from https://hub.docker.com/r/envoyproxy/ratelimit/tags      - image: registry-cn-hangzhou.ack.aliyuncs.com/dev/ratelimit:e059638d        imagePullPolicy: Always        name: ratelimit        command: ["/bin/ratelimit"]        env:        - name: LOG_LEVEL          value: debug        - name: REDIS_SOCKET_TYPE          value: tcp        - name: REDIS_URL          value: redis.default.svc.cluster.local:6379        - name: USE_STATSD          value: "false"        - name: RUNTIME_ROOT          value: /data        - name: RUNTIME_SUBDIRECTORY          value: ratelimit        - name: RUNTIME_WATCH_ROOT          value: "false"        - name: RUNTIME_IGNOREDOTFILES          value: "true"        ports:        - containerPort: 8080        - containerPort: 8081        - containerPort: 6070        volumeMounts:        - name: config-volume          # $RUNTIME_ROOT/$RUNTIME_SUBDIRECTORY/$RUNTIME_APPDIRECTORY/config.yaml          mountPath: /data/ratelimit/config      volumes:      - name: config-volume        configMap:          name: ratelimit-config

执行以下指令部署限流服务:

kubectl apply -f ratelimitsvc.yaml
02

部署全局限流规则

Cloud Native

全局限流允许跨多个服务对请求进行请求速率限制,这种方式基于集群中所有服务共享集中的限流服务实现。因此,全局限流的最佳实践是配置在整个系统的流量入口(典型为配置于入口网关),从而得以限制进入系统的流量总数,保证系统整体的压力可控。

本文将演示在入口网关处部署全局限流。

通过 kubeconfig 连接 ASM 实例、并执行以下指令,部署全局限流服务。
kubectl apply -f- <apiVersion: istio.alibabacloud.com/v1beta1kind: ASMGlobalRateLimitermetadata:  name: global-limit  namespace: istio-systemspec:  workloadSelector:    labels:      app: istio-ingressgateway  rateLimitService:    host: ratelimit.default.svc.cluster.local    port: 8081    timeout:      seconds: 5  isGateway: true  configs:  - name: boutique    limit:      unit: SECOND      quota: 100000    match:      vhost:        name: '*'        port: 8000        route:          name_match: boutique-route  # 该名称需要和virtualservice下的route name一致。    limit_overrides:    - request_match:        header_match:        - name: :path          prefix_match: /product      limit:        unit: MINUTE        quota: 5EOF

对于 boutique 应用来说,入口是一个前端服务,每次访问该应用,都会产生大量对于 jpg、css、js 等文件的静态请求,这些请求不会对系统造成太多压力。我们主要需要限制实际对后端服务造成压力的请求,因此这里在网关入口处配置总的限流为每秒 100000 次请求(几乎没有限制);而对于路径以 /product 开头的请求(这些请求会造成集群中的东西向流量访问),则使用 limit_overrides 单独给予一个较小的限流数值(为演示目的,这里设定成 1 分钟 5 次请求)。

接下来通过执行指令重新获取全局限流 yaml。
kubectl get asmglobalratelimiter -n istio-system global-limit -oyaml

预期输出:

apiVersion: istio.alibabacloud.com/v1kind: ASMGlobalRateLimitermetadata:  annotations:    kubectl.kubernetes.io/last-applied-configuration: |      {"apiVersion":"istio.alibabacloud.com/v1beta1","kind":"ASMGlobalRateLimiter","metadata":{"annotations":{},"name":"global-limit","namespace":"istio-system"},"spec":{"configs":[{"limit":{"quota":100000,"unit":"SECOND"},"limit_overrides":[{"limit":{"quota":5,"unit":"MINUTE"},"request_match":{"header_match":[{"name":":path","prefix_match":"/product"}]}}],"match":{"vhost":{"name":"*","port":8000,"route":{"name_match":"boutique-route"}}},"name":"boutique"}],"isGateway":true,"rateLimitService":{"host":"ratelimit.default.svc.cluster.local","port":8081,"timeout":{"seconds":5}},"workloadSelector":{"labels":{"app":"istio-ingressgateway"}}}}  creationTimestamp: "2024-06-11T12:19:11Z"  generation: 1  name: global-limit  namespace: istio-system  resourceVersion: "1620810225"  uid: e7400112-20bb-4751-b0ca-f611e6da0197spec:  configs:  - limit:      quota: 100000      unit: SECOND    limit_overrides:    - limit:        quota: 5        unit: MINUTE      request_match:        header_match:        - name: :path          prefix_match: /product    match:      vhost:        name: '*'        port: 8000        route:          name_match: boutique-route    name: boutique  isGateway: true  rateLimitService:    host: ratelimit.default.svc.cluster.local    port: 8081    timeout:      seconds: 5  workloadSelector:    labels:      app: istio-ingressgatewaystatus:  config.yaml: |    descriptors:    - descriptors:      - key: header_match        rate_limit:          requests_per_unit: 5          unit: MINUTE        value: RateLimit[global-limit.istio-system]-Id[238116753]      key: generic_key      rate_limit:        requests_per_unit: 100000        unit: SECOND      value: RateLimit[global-limit.istio-system]-Id[828717099]    domain: ratelimit.default.svc.cluster.local  message: ok  status: successful

接下来要把 status 中的 config.yaml 字段拷贝至限流服务的配置中,该配置是一个叫做 ratelimit-config 的 configmap(在全局限流服务的部署列表中可以找到)。因为实际判断是否对请求限流的是限流服务。

将 kubectl 连接到 ACK 集群,执行以下指令:
kubectl apply -f- <apiVersion: v1data:  config.yaml: |    descriptors:    - descriptors:      - key: header_match        rate_limit:          requests_per_unit: 5          unit: MINUTE        value: RateLimit[global-limit.istio-system]-Id[238116753]      key: generic_key      rate_limit:        requests_per_unit: 100000        unit: SECOND      value: RateLimit[global-limit.istio-system]-Id[828717099]    domain: ratelimit.default.svc.cluster.localkind: ConfigMapmetadata:  name: ratelimit-config  namespace: defaultEOF
03

部署本地限流规则

Cloud Native







请到「今天看啥」查看全文