实验 6:全局速率限制

在这个实验中,我们将学习如何配置一个全局速率限制器。我们将使用速率限制器服务和一个 Redis 实例来跟踪令牌。我们将使用 Docker Compose 来运行 Redis 和速率限制器服务容器。

让我们首先创建速率限制器服务的配置。

domain: my_domain
descriptors:
- key: generic_key
  value: instance_1
  descriptors:
    - key: header_match
      value: get_request
      rate_limit:
        unit: MINUTE
        requests_per_unit: 5

我们指定一个通用键(instance_1)和一个名为 header_match 的描述符,速率限制为 5 个请求 / 分钟。

将上述文件保存到 /config/rl-config.yaml 文件中。

现在我们可以运行 Docker Compose 文件,它将启动 Redis 和速率限制器服务。

version: "3"
services:
  redis:
    image: redis:alpine
    expose:
      - 6379
    ports:
      - 6379:6379
    networks:
      - ratelimit-network

  # Rate limit service configuration
  ratelimit:
    image:  envoyproxy/ratelimit:bd46f11b
    command: /bin/ratelimit
    ports:
      - 10001:8081
      - 6070:6070
    depends_on:
      - redis
    networks:
      - ratelimit-network
    volumes:
      - $PWD/config:/data/config/config
    environment:
      - USE_STATSD=false
      - LOG_LEVEL=debug
      - REDIS_SOCKET_TYPE=tcp
      - REDIS_URL=redis:6379
      - RUNTIME_ROOT=/data
      - RUNTIME_SUBDIRECTORY=config

networks:
  ratelimit-network:

将上述文件保存为 rl-docker-compose.yaml,并使用下面的命令启动所有容器:

$ docker-compose -f rl-docker-compose.yaml up

为了确保速率限制器服务正确读取配置,我们可以检查容器的输出或使用速率限制器服务的调试端口。

$ curl localhost:6070/rlconfig
my_domain.generic_key_instance_1.header_match_get_request: unit=MINUTE requests_per_unit=5

随着速率限制器和 Redis 的启动和运行,我们可以启动 httpbin 容器。

docker run -d -p 3030:80 kennethreitz/httpbin

接下来,我们将创建 Envoy 配置,定义速率限制动作。我们将设置描述符 instance_1get_request,只要有 GET 请求被发送到 httpbin

http_filters 下,我们通过指定域名(my_domain)和指向 Envoy 可以用来到达速率限制服务的集群来配置 ratelimit 过滤器。

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 10000
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: namespace.local_service
              domains: ["*"]
              routes:
              - match:
                  prefix: /
                route:
                  cluster: instance_1
                  rate_limits:
                  - actions:
                    - generic_key:
                        descriptor_value: instance_1
                    - header_value_match:
                        descriptor_value: get_request
                        headers:
                        - name: ":method"
                          exact_match: GET
          http_filters:
          - name: envoy.filters.http.ratelimit
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
              domain: my_domain
              enable_x_ratelimit_headers: DRAFT_VERSION_03
              rate_limit_service:
                transport_api_version: V3
                grpc_service:
                    envoy_grpc:
                      cluster_name: rate-limit
          - name: envoy.filters.http.router
  clusters:
  - name: instance_1
    connect_timeout: 0.25s
    type: STATIC
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: instance_1
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 127.0.0.1
                port_value: 3030
  - name: rate-limit
    connect_timeout: 1s
    type: STATIC
    lb_policy: ROUND_ROBIN
    protocol_selection: USE_CONFIGURED_PROTOCOL
    http2_protocol_options: {}
    load_assignment:
      cluster_name: rate-limit
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 127.0.0.1
                port_value: 10001
admin:
  address:
    socket_address:
      address: 127.0.0.1
      port_value: 9901

将上述 YAML 保存为 2-lab-6-global-rate-limiter-1.yaml,并使用 func-e run -c 2-lab-6-global-rate-limiter-1.yaml 运行代理。

我们现在可以发送五个以上的请求,我们会得到速率限制。

$ curl -v localhost:10000
...
< HTTP/1.1 429 Too Many Requests
< x-envoy-ratelimited: true
< x-ratelimit-limit: 5, 5;w=60
< x-ratelimit-remaining: 0
< x-ratelimit-reset: 25
...

我们收到了 429 响应,以及表明我们受到速率限制的响应头;在受到速率限制之前我们可以发出多少个请求(x-ratelimit-remaining)以及速率限制何时重置(x-ratelimit-reset)。

results matching ""

    No results matching ""