Spring Cloud Gateway Guide: Routing Predicates, Filters, Rate Limiting, and Custom Gateway Patterns

Spring Cloud Gateway serves as the unified entry point in a microservices architecture. It addresses fragmented service exposure, duplicated authentication logic, and complex route maintenance. This article focuses on route configuration, predicate factories, filter chains, and rate limiting to help you quickly build a governable gateway layer. Keywords: Spring Cloud Gateway, microservices gateway, rate limiting.

Technical Specification Snapshot

Parameter Description
Core Language Java
Application Framework Spring Boot, Spring Cloud
Communication Protocol HTTP/HTTPS
Programming Model Reactor, WebFlux
Service Discovery Nacos
Load Balancing Spring Cloud LoadBalancer
Monitoring Capabilities Actuator, Gateway Metrics
GitHub Stars Not provided in the source
Core Dependencies gateway, nacos-discovery, loadbalancer, actuator

The gateway acts as the unified governance entry point for microservices.

In a monolithic architecture, permission checks, logging, and API exposure are usually handled in one place. After splitting the system into microservices, however, requests can directly reach multiple services, which leads to duplicated authentication logic, fragmented entry points, and more complex operations.

The value of Gateway is that it shifts unified access to the front. All requests enter the gateway first, and the gateway then handles validation, routing, rate limiting, and forwarding. Backend services can stay focused on business logic.

Spring Cloud Gateway primarily solves four categories of problems.

  1. Access control: Move authentication and authorization to a unified entry point.
  2. Dynamic routing: Forward requests based on rules such as path, header, and HTTP method.
  3. Load balancing: Route by service name to specific instances.
  4. Traffic governance: Support rate limiting, retries, monitoring, and request rewriting.

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<dependency>

<groupId>com.alibaba.cloud</groupId>

<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

These dependencies provide gateway capabilities, service discovery, and service-name-based load balancing.

Basic route configuration determines how requests enter downstream services.

A Gateway project is itself an independent service. A common practice is to register it with Nacos and forward requests to downstream instances through lb://service-name.

server:
  port: 10030 # Gateway port
spring:
  application:
    name: gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      routes:
        - id: product-service # Unique route identifier
          uri: lb://product-service # Load balancing based on service name
          predicates:
            - Path=/product/** # Forward after the path matches
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order/**

This configuration defines two basic routes: /product/** and /order/** go to different microservices.

Route predicates are fundamentally request-matching rules.

A Predicate receives the request context and returns a boolean value to determine whether the current request matches a route. When multiple predicates appear together, the default relationship is and.

Common predicates include Path, Method, Header, Cookie, Host, Query, and time-based predicates such as After, Before, and Between.

ZonedDateTime now = ZonedDateTime.now(); // Generate a time value with time zone information for time-based predicate configuration
System.out.println(now);

This code generates a time value that matches the format required by Gateway time predicates.

The filter chain handles pre-processing and post-processing logic.

Predicates decide whether to route. Filters decide what to do before and after routing. They are well suited for cross-cutting concerns such as parameter injection, response header enrichment, logging, retries, and traffic control.

Gateway filters fall into two categories: GatewayFilter applies only to specific routes, while GlobalFilter applies to all requests. In addition, default-filters can be applied uniformly to all routes.

spring:
  cloud:
    gateway:
      routes:
        - id: product-service
          uri: lb://product-service
          predicates:
            - Path=/product/**
            - After=2026-04-26T22:45:33.181755800+08:00[Asia/Shanghai]
          filters:
            - AddRequestParameter=userName,zhku # Add a request parameter
      default-filters:
        - AddResponseHeader=X-Response-Default-Red, Default-Blue # Add a unified response header

This configuration demonstrates how to combine route-specific filters with global default filters.

Common filters directly determine the granularity of gateway governance.

Retry handles retry-on-failure scenarios and works well for transient errors. RequestSize limits request body size to protect downstream services. PrefixPath appends a common path prefix. AddRequestParameter is often used to pass through shared parameters.

filters:
  - name: Retry
    args:
      retries: 3 # Retry up to 3 times
      statuses: BAD_REQUEST # Trigger retries for the specified status code
  - name: RequestSize
    args:
      maxSize: 5000000 # Limit the maximum request body size to 5 MB

This configuration shows two high-frequency filters: retries and request body size limiting.

The rate limiting mechanism is essential for protecting the gateway and downstream services.

Common rate limiting algorithms include fixed window, sliding window, leaky bucket, and token bucket. Gateway’s RequestRateLimiter is typically implemented with a Redis-backed token bucket, balancing smooth traffic handling with burst tolerance.

The token bucket model offers two key advantages: the system places tokens into the bucket at a fixed rate, and a request can pass only after obtaining a token. This makes it possible to limit the average request rate while still allowing a controlled level of short-lived bursts.

filters:
  - name: RequestRateLimiter
    args:
      redis-rate-limiter.replenishRate: 10 # Add 10 tokens per second
      redis-rate-limiter.burstCapacity: 20 # Bucket capacity is 20
      redis-rate-limiter.requestedTokens: 1 # Each request consumes 1 token

This configuration means the gateway allows about 10 sustained requests per second while tolerating some traffic spikes.

Global filters are commonly used for monitoring and unified governance.

When uri uses the lb:// prefix, LoadBalancer-related global filters automatically participate in request distribution. To enable monitoring, you can add Actuator and turn on Gateway Metrics.


<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

This dependency exposes gateway monitoring endpoints so you can integrate them with visualization systems such as Grafana.

spring:
  cloud:
    gateway:
      metrics:
        enabled: true # Enable gateway metrics
management:
  endpoints:
    web:
      exposure:
        include: "*" # Expose all endpoints

After enabling it, you can inspect health status and gateway metrics through /actuator.

Custom filters are well suited for enterprise-wide shared logic.

A custom GatewayFilterFactory is a good fit for route-level extensions, while a custom GlobalFilter is better for unified logic such as global authentication, auditing, and distributed tracing. Filter execution order is controlled by Ordered: the smaller the order, the earlier the filter runs.

@Data
public class CustomConfig {
    private String name; // Bind a custom parameter from the configuration file
}

This configuration class receives the args parameters for a custom filter.

spring:
  cloud:
    gateway:
      routes:
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order/**,/feign/**
          filters:
            - name: Custom
              args:
                name: test_custom # Pass a custom filter parameter

This configuration shows that the custom filter name comes from the Custom prefix of CustomGatewayFilterFactory.

The service deployment process should validate configuration before opening access.

When deploying a gateway, a practical approach is to follow five steps: verify the registry center and route configuration, package and upload the application, start the service, open the required port, and run integration tests. Because the gateway serves as the unified entry point, you must verify ports, firewall rules, and service registration information together.

If you use rate limiting, monitoring, and global authentication in production, perform load testing in a test environment first and then gradually increase traffic to avoid accidentally affecting critical business flows.

FAQ

1. What is the core difference between Spring Cloud Gateway and Zuul?

Gateway is built on Spring WebFlux and Reactor, so it natively supports reactive programming. Its performance and extensibility make it better suited to modern microservices scenarios. Zuul 1.x is based more on a blocking model.

2. Why does routing fail when multiple predicates exist at the same time?

Because the default relationship is and. If even one predicate is not satisfied, the entire route will not match. When troubleshooting, pay special attention to time, path, and request header conditions.

3. Should a custom filter use GatewayFilter or GlobalFilter?

If the logic serves only a specific route or a certain type of API, use GatewayFilter. If the logic must cover all requests, such as unified authentication, log auditing, or distributed tracing, use GlobalFilter.

AI Readability Summary

This article systematically explains the core capabilities of Spring Cloud Gateway, including unified entry, dynamic routing, predicate matching, route-level and global filters, token-bucket rate limiting, custom filters, and deployment considerations. It works well as a quick-start guide and configuration reference for microservices gateways.