r8limiter

module
v0.0.0-...-f12b9c8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 6, 2020 License: MIT

README

r8limiter

r8limiter is an Envoy pluggable RateLimit gRPC service. It can serve multiple purposes, e.g - API Gateways, Database accesses, Service-to-Service communications etc. It offers a totally configurable API, in which you can define the rules by which a request can be limited. This service uses the sliding window rate limiting algorithm, with asynchronous or synchronous data replication, or even an in-mem rate limiter.

CI Status

CircleCI

Installation

go get github.com/samueltorres/r8limiter

Usage

Usage of r8limiter:
  -debug-addr string
    	debug address for metrics and healthcheck (default ":8083")
  -grpc-addr string
    	grpc address (default ":8081")
  -http-addr string
    	http address (default ":8082")
  -log-level string
    	log level (panic, fatal, error, warn, info, debug, trace) (default "info")
  -redis-address string
    	redis address
  -redis-database int
    	redis database
  -redis-password string
    	redis password
  -rules-file string
    	rules file (default "/env/rules.yaml")
  -shutdown-grace-period duration
    	shutdown grace period for grpc and http servers (default 30s)
  -sync-batch-size int
    	number of counters to sync in each batch (default 1000)

Rules Configuration

Rate limiting rules are being described in yaml format.

Please look at the following example, in which we are limiting any authenticated user to make 500 requests per hour, all the other users can do 1000 per hour.

domains:
  - domain: envoy
    rules:
      - name: authenticated users
        labels:
          - key: authenticated
            value: "true"
          - key: user_id
        limit:
          unit: hour
          requests: 500
        syncRate: 1

      - name: any user
        labels:
          - key: user_id
        limit:
          unit: hour
          requests: 1000
        syncRate: -1
Synchronization

This implementation offers you the possibility of configuring the synchronization rate for a given rule.

sync rate
-1 no synchronization
0 (default) all rate limit requests go through the remote storage
[1-n] number of seconds between synchronizations

Sometimes the rate limiter needs to be strict e.g number of requests per client tier on an enterprise offering.

domains:
  - domain: api-gateway
    rules:
      - name: starter users
        labels:
          - key: user_type
            value: starter
        limit:
          unit: minute
          requests: 500
        syncRate: 0
      - name: premium users
        labels:
          - key: user_type
            value: premium
        limit:
          unit: minute
          requests: 20000
        syncRate: 0

In other use cases we can be very lenient in the number of requests, like protecting a server from DDOS attacks, and the in-mem rate limiter will be sufficient.

domains:
  - domain: api-gateway
    rules:
      - name: ddos protection
        labels:
          - key: ip_address
        limit:
          unit: second
          requests: 5000
        syncRate: -1
      - name: tenant
        labels:
          - key: tenant
        limit:
          unit: minute
          requests: 50000
        syncRate: 3

If we want to be a little bit strict, we can have an in-mem rate limiter that synchronizes the counters with the remote storage after n seconds, thereforew we are sure that all instances of the rate limiter have.

domains:
  - domain: api-gateway
    rules:
      - name: tenant
        labels:
          - key: tenant
        limit:
          unit: minute
          requests: 50000
        syncRate: 3
Other examples

This configuration schema allows you to configure different rate limits configurations for each kind use case you'll need, e.g - limiting mongodb accesses to 10000 reqs/hour, limiting Portuguese users to 20 reqs/min etc.

domains:
  - domain: api-gateway
    rules:
      - name: any user
        labels:
          - key: country
            value: PT
          - key: user_id
        limit:
          unit: minute
          requests: 20
  - domain: mongodb
    rules:
      - name: any request
        labels:
          - key: generic
        limit:
          unit: hour
          requests: 10000

Remote Storages

When synchronization is needed, a remote storage must be provided, currently it only supports Redis.

Run locally

Spin up environment using docker-compose

docker-compose up

Spin up the r8limiter server

go run cmd/server/server.go --rules-file ./env/rules.yaml

Spin up a test client

go run cmd/client/client.go

License

This project is licensed under the MIT open source license.

Directories

Path Synopsis
cmd
pkg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL