Skip to content

Instantly share code, notes, and snippets.

@omidp
Created September 24, 2023 18:10
Show Gist options
  • Save omidp/b0d36b9da04a01b1513b1c9a36ca4fe4 to your computer and use it in GitHub Desktop.
Save omidp/b0d36b9da04a01b1513b1c9a36ca4fe4 to your computer and use it in GitHub Desktop.
RateLimiterServlet
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-all</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-vavr</artifactId>
<version>2.1.0</version>
</dependency>
import io.github.resilience4j.ratelimiter.RateLimiter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
@Configuration
public class RateLimiterConfig {
@Bean
public RateLimiter rateLimiter(){
//2 request per second
io.github.resilience4j.ratelimiter.RateLimiterConfig config = io.github.resilience4j.ratelimiter.RateLimiterConfig.custom()
.timeoutDuration(Duration.ofSeconds(0))
.limitRefreshPeriod(Duration.ofSeconds(1))
.limitForPeriod(2)
.build();
RateLimiter rateLimiter = RateLimiter.of("backendName", config);
return rateLimiter;
}
}
import io.github.resilience4j.ratelimiter.RateLimiter;
import io.github.resilience4j.ratelimiter.RequestNotPermitted;
import io.vavr.control.Try;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.IOException;
@RequiredArgsConstructor
@Component
@Slf4j
public class RateLimiterServlet implements Filter {
private final RateLimiter rateLimiter;
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
try {
Try.runRunnable(() -> RateLimiter.decorateConsumer(rateLimiter, 1, unused -> chain(servletRequest, servletResponse, filterChain)).accept(null)).get();
} catch (RequestNotPermitted rnp) {
log.info("2 requests per second is allowed");
((HttpServletResponse) servletResponse).setStatus(429);
}
}
@SneakyThrows
private void chain(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
filterChain.doFilter(servletRequest, servletResponse);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment