Envoy實現.NET架構的閘道器(五)整合Redis實現限流

chester·chen發表於2021-11-02

什麼是限流

限流即限制併發量,限制某一段時間只有指定數量的請求進入後臺伺服器,遇到流量高峰期或者流量突增時,把流量速率限制在系統所能接受的合理範圍之內,不至於讓系統被高流量擊垮。而Envoy可以通過envoy.filters.http.ratelimit外掛實現限流。

限流服務

Envoy實現限流需要依賴限速服務,Envoy官方為我們提供了基於Redis和Memcached的限速服務

https://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

測試限速

呼叫介面http://192.168.43.94:10000/Name,第三次的時候就會觸發429超限請求

 我們看看example/ratelimit/config/example.yaml,可以看到每分鐘只允許2次請求,至此限速驗證完成!!

相關文章