Skip to content

kidminks/rate-limiter-java

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

69 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Rate Limiter Java Library

A Java library for rate limiting, assembled using extensible storage and application framework adaptors. The library's interfaces support thread-safe sync, async, and reactive usage patterns.

Modules

RateLimiterJava provides the following stable pluggable modules

  • Fixed Window rate limiter
  • Sliding Window rate limiter

Features

Configuration can be made to store the user data in redis using these modules. Lua scripts is used in following cases to reduce redis calls

  • Sliding Window rate limiter
  • In case user data is handled using this library

Installation

Add the dependency to your pom.xml file

<dependency>
    <groupId>io.github.kidminks</groupId>
    <artifactId>rate-limiter-java</artifactId>
    <version>0.0.1</version>
</dependency>

Then run from the root dir of the project:

mvn install

Prerequisite

  • jedis
  • javax.validation
  • guava
  • lombok

Examples

Example Rate Limiter Service

Create a service RateLimiterService which will handle the library linking

package com.example.demo;

import io.github.kidminks.rate.limiter.core.abst.AbstractRateLimiter;
import io.github.kidminks.rate.limiter.core.factory.RateLimiterFactory;
import io.github.kidminks.rate.limiter.model.dto.Configuration;
import io.github.kidminks.rate.limiter.model.dto.LimitDetails;
import io.github.kidminks.rate.limiter.model.enums.RateLimiterType;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Component
@Service
public class RateLimiterService {

    private AbstractRateLimiter slidingWindowRateLimiter;
    private AbstractRateLimiter fixedWindowRateLimiter;

    private void initSlidingWindowRateLimiter() {
        Configuration configuration = Configuration.builder()
                .redisHost("localhost")
                .redisPort(6379)
                .redisDb(1)
                .maxTotal(10)
                .maxIdle(1)
                .useLuaScript(true)
                .build();
        this.slidingWindowRateLimiter = RateLimiterFactory.getRateLimiter(configuration, RateLimiterType.SLIDING_WINDOW);
    }

    private void initFixedWindowRateLimiter() {
        Configuration configuration = Configuration.builder()
                .redisHost("localhost")
                .redisPort(6379)
                .redisDb(1)
                .maxTotal(10)
                .maxIdle(1)
                .useLuaScript(false)
                .build();
        this.fixedWindowRateLimiter = RateLimiterFactory.getRateLimiter(configuration, RateLimiterType.FIXED_WINDOW);
    }

    public RateLimiterService() {
        initSlidingWindowRateLimiter();
        initFixedWindowRateLimiter();
    }

    public Boolean checkSlidingWindowLimit(String key) {
        return slidingWindowRateLimiter.check(new LimitDetails(key, 100L, 3600000L));
    }

    public Boolean checkFixedWindowLimit(String key) {
        return fixedWindowRateLimiter.check(new LimitDetails(key, 100L, 3600000L));
    }
}

Sliding Window

Checking limits left using sliding rate limiter api. These checks using lua scripts. Old request data are deleted with every request

@RestController
@RequestMapping("/")
@Slf4j
public class RateLimiterTestController {

    @Autowired
    private RateLimiterService rateLimiterService;

    @GetMapping("/sliding-window")
    public void slidingWindowTest(@RequestHeader("X-AUTH-TOKEN") String token) {
        if(rateLimiterService.checkSlidingWindowLimit(token)) {
            log.info("limit available");
            return;
        }
        log.info("limit not available");
    }
}

Fixed Window

increment function of redis is used to increase the key count. Every time a new key is created expiry is set and that key is deleted after the end.

@RestController
@RequestMapping("/")
@Slf4j
public class RateLimiterTestController {

    @Autowired
    private RateLimiterService rateLimiterService;

    @GetMapping("/fixed-window")
    public void fixedWindowTest(@RequestHeader("X-AUTH-TOKEN") String token) {
        if(rateLimiterService.checkFixedWindowLimit(token)) {
            log.info("limit available");
            return;
        }
        log.info("limit not available");
    }
}

Roadmap

Feature Status
Sliding Window rate limiter Released
Fixed Window rate limiter Released
Store user data Ongoing

About

Java api rate limiter library

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages