Spring Cloud Gateway: Building a Microservice Gateway with CORS, Filters, and 100k QPS Rate Limiting
This tutorial explains how to build a Spring Cloud Gateway microservice gateway, covering CORS configuration, custom filters, token‑bucket rate limiting up to 100 000 QPS using Redis, and provides complete Maven, Java, and YAML code examples for deployment.
1.1 Introduction
The article covers microservice gateway features such as handling up to 100 000 QPS rate limiting, CORS, custom filters, and the token‑bucket algorithm.
In microservice architectures, a gateway is essential; from the early Zuul to the modern Spring Cloud Gateway, it is indispensable.
This post consolidates knowledge about gateway configuration, CORS handling, filter implementation, and rate limiting.
1.2 What is a Microservice Gateway?
This project provides a library for building an API Gateway on top of Spring WebFlux.
Official site: https://spring.io/projects/spring-cloud-gateway
Common implementations include Nginx, Netflix Zuul, and Spring Cloud Gateway, which integrates circuit breaking, path rewriting, and offers better performance than Zuul.
1.3 Why Use a Gateway?
Clients would otherwise need to call multiple services directly, increasing complexity.
Cross‑origin requests become harder to manage.
Authentication must be duplicated across services.
Service refactoring is difficult when clients talk to many services directly.
Some services use firewall‑protected or non‑browser‑friendly protocols.
The gateway acts as a middle layer, handling security, performance, and monitoring, allowing services to focus on business logic.
1.4 Advantages of a Microservice Gateway
Security: only the gateway is exposed to the outside world.
Easy monitoring: collect metrics at the gateway.
Centralized authentication.
Reduces client‑service interaction count.
Unified authorization.
1.5 Summary
The gateway provides authentication, security control, unified logging, and monitoring capabilities for microservices.
2. Microservice Gateway Setup and Configuration
2.1 Building the Gateway Service
Dependencies (pom.xml):
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>Main class (GatewayApplication):
@SpringBootApplication
@EnableEurekaClient
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}application.yml (resources):
spring:
application:
name: apigateway
cloud:
gateway:
routes:
- id: open
uri: lb://open
predicates:
- Path=/open/**
filters:
- StripPrefix=1
- id: system
uri: lb://system
predicates:
- Path=/system/**
filters:
- StripPrefix=1
server:
port: 9999
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true2.2 CORS Configuration
Add the following bean to the gateway application:
@Bean
public CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedMethod("*");
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}3. Gateway Filters
Two global filters are demonstrated: an IP filter and a URL filter.
IpFilter:
@Component
public class IpFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
InetSocketAddress remoteAddress = request.getRemoteAddress();
// TODO: implement IP whitelist
System.out.println("ip:" + remoteAddress.getHostName());
return chain.filter(exchange);
}
@Override
public int getOrder() { return 1; }
}UrlFilter:
@Component
public class UrlFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String url = request.getURI().getPath();
// TODO: intercept specific URLs
System.out.println("url:" + url);
return chain.filter(exchange);
}
@Override
public int getOrder() { return 2; }
}4. Rate Limiting – 100 000 Requests per Second
The gateway can perform rate limiting using the token‑bucket algorithm. Spring Cloud Gateway uses Redis‑based RateLimiter by default.
4.1 Token‑Bucket Algorithm Overview
Requests must acquire a token before being processed. Tokens are added to the bucket at a fixed rate (replenishRate) up to a maximum capacity (burstCapacity). If the bucket is empty, requests are rejected with HTTP 429.
4.2 Implementation Steps
Add Redis starter dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>Define a KeyResolver bean to use the client IP as the limiting key:
@Bean
public KeyResolver ipKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}Configure rate limiting in application.yml:
spring:
cloud:
gateway:
routes:
- id: open
uri: lb://open
predicates:
- Path=/open/**
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
key-resolver: "#{@ipKeyResolver}"
redis-rate-limiter.replenishRate: 1
redis-rate-limiter.burstCapacity: 1
- id: system
uri: lb://system
predicates:
- Path=/system/**
filters:
- StripPrefix=1
redis:
host: 101.57.2.128
port: 6379
server:
port: 9999Explanation: burstCapacity – total token bucket size. replenishRate – tokens added per second. key-resolver – bean that provides the key for limiting (here the client IP).
Start Redis, Eureka, the business microservice, and finally the gateway. Access http://localhost:9999/open and refresh quickly; exceeding 100 000 requests in one second returns HTTP 429.
Thus, the gateway can protect downstream services by performing centralized CORS handling, authentication, monitoring, and high‑throughput rate limiting.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
