Cloud Native 13 min read

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.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
Spring Cloud Gateway: Building a Microservice Gateway with CORS, Filters, and 100k QPS Rate Limiting

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: true

2.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: 9999

Explanation: 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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javaCORSSpring Cloud Gateway
Code Ape Tech Column
Written by

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

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.