Envoy实现.NET架构的网关(五)集成Redis实现限流

什么是限流

限流即限制并发量,限制某一段时间只有指定数量的请求进入后台服务器,遇到流量高峰期或者流量突增时,把流量速率限制在系统所能接受的合理范围之内,不至于让系统被高流量击垮。而Envoy可以通过envoy.filters.http.ratelimit插件实现限流。

限流服务

Envoy实现限流需要依赖限速服务,Envoy官方为我们提供了基于Redis和Memcached的限速服务

//github.com/envoyproxy/ratelimit

 

 我们将其从github下载到本地,来看看其中的docker-compose.yaml的工作模式,我们注意到其中的example文件挂载目录

 

 并且其中还制定了配置目录是example/ratelimit

 

 我们来看看config.yaml和example.yaml的内容,发现其中定义了domain和描述符

 

 所以根据文档的提示,我们在envoy配置中应该命中这些描述符才有效,下面我们通过docker-compose up启动ratelimit服务,启动之前我们需要调整docker-compose.yaml,需要将go mod代理指向国内的代理

 

 启动ratelimit服务

 

 配置Envoy

配置envoy之前我们需要注意一下几点

  • 需要用到envoy.filters.http.ratelimit过滤器
  • 指定其domain为example.yaml中对应的rl
  • 需要为其指定ratelimit服务的cluste
  • 需要为route配置限速规则

具体配置如下

admin:
  address:
    socket_address:
      protocol: TCP
      address: 0.0.0.0
      port_value: 9902
static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        protocol: TCP
        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
          codec_type: AUTO
          stat_prefix: ingress
          http_filters:
          - name: envoy.filters.http.ratelimit
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
              domain: rl
              request_type: both
              stage: 0
              rate_limited_as_resource_exhausted: true
              failure_mode_deny: false
              enable_x_ratelimit_headers: DRAFT_VERSION_03
              rate_limit_service:
                grpc_service:
                  envoy_grpc:
                    cluster_name: ratelimit
                transport_api_version: V3
          - name: envoy.filters.http.router
            typed_config: {}
          route_config:
            name: route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: service_envoyproxy_io
                  rate_limits:
                  - actions:
                      - request_headers:
                          header_name: "foo"
                          descriptor_key: "foo"
  clusters:
  - name: ratelimit
    type: STRICT_DNS
    connect_timeout: 1s
    lb_policy: ROUND_ROBIN
    protocol_selection: USE_CONFIGURED_PROTOCOL
    http2_protocol_options: {}
    load_assignment:
      cluster_name: ratelimit
      endpoints:
        - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: 192.168.43.94
                    port_value: 8081
  - name: service_envoyproxy_io
    connect_timeout: 30s
    type: strict_dns
    # Comment out the following line to test on v6 networks
    # dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: service_envoyproxy_io
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 192.168.43.94
                port_value: 5000

启动Envoy

docker run --rm -it -p 9902:9902 -p 10000:10000 -v D:/gateway/envoy/config/static/:/etc/envoy/ -v D:/gateway/envoy/logs:/logs envoyproxy/envoy-dev  -c /etc/envoy/envoy-ratelimit.yaml

测试限速

调用接口//192.168.43.94:10000/Name,第三次的时候就会触发429超限请求

 我们看看example/ratelimit/config/example.yaml,可以看到每分钟只允许2次请求,至此限速验证完成!!

Tags: