# Configuring Spring Cloud Gateway Filters for High-Availability Routing in Apache Linkis

> Learn to configure Spring Cloud Gateway filters for high-availability routing in Apache Linkis. Implement token validation, IP priority load balancing, and Eureka health checks for robust routing.

- Repository: [The Apache Software Foundation/linkis](https://github.com/apache/linkis)
- Tags: best-practices
- Published: 2026-02-25

---

**Configure the `GatewayAuthorizationFilter` for token validation, enable the `IpPriorityLoadBalancer` to honor `FIXED_INSTANCE` headers with automatic fallback to healthy instances, and integrate Eureka health checks to ensure dead nodes are excluded from the routing pool.**

Apache Linkis leverages Spring Cloud Gateway as the unified entry point for its microservices architecture. Configuring the Spring Cloud Gateway filters for high-availability routing in Linkis requires understanding how the custom `IpPriorityLoadBalancer` interacts with global filters to provide instance affinity, automatic failover, and secure token-based access.

## Core Components of the Linkis Gateway Architecture

### GatewayAuthorizationFilter

The `GatewayAuthorizationFilter` class serves as the primary security checkpoint. Located at [`linkis-spring-cloud-services/linkis-service-gateway/linkis-spring-cloud-gateway/src/main/java/org/apache/linkis/gateway/springcloud/http/GatewayAuthorizationFilter.java`](https://github.com/apache/linkis/blob/main/linkis-spring-cloud-services/linkis-service-gateway/linkis-spring-cloud-gateway/src/main/java/org/apache/linkis/gateway/springcloud/http/GatewayAuthorizationFilter.java), this global filter validates authentication tokens, enforces request body size limits, and constructs the `BaseGatewayContext` used throughout the request lifecycle.

### IpPriorityLoadBalancer

The `IpPriorityLoadBalancer` implements `ReactorServiceInstanceLoadBalancer` to provide intelligent routing logic. Found in [`linkis-spring-cloud-services/linkis-service-gateway/linkis-spring-cloud-gateway/src/main/java/org/apache/linkis/gateway/springcloud/http/IpPriorityLoadBalancer.java`](https://github.com/apache/linkis/blob/main/linkis-spring-cloud-services/linkis-service-gateway/linkis-spring-cloud-gateway/src/main/java/org/apache/linkis/gateway/springcloud/http/IpPriorityLoadBalancer.java), this component checks for the `FIXED_INSTANCE` header (defined in `SpringCloudGatewayConstant.FIXED_INSTANCE`). When present, it routes to the exact host:port pair; if that instance is unhealthy, it falls back to random selection from available healthy instances.

### SpringCloudGatewayWebsocketFilter

WebSocket connections require special handling to prevent duplicate connection errors. The `SpringCloudGatewayWebsocketFilter` in [`linkis-spring-cloud-services/linkis-service-gateway/linkis-spring-cloud-gateway/src/main/java/org/apache/linkis/gateway/springcloud/websocket/SpringCloudGatewayWebsocketFilter.java`](https://github.com/apache/linkis/blob/main/linkis-spring-cloud-services/linkis-service-gateway/linkis-spring-cloud-gateway/src/main/java/org/apache/linkis/gateway/springcloud/websocket/SpringCloudGatewayWebsocketFilter.java) manages the `ROUTE_URI_FOR_WEB_SOCKET_HEADER` constant and prevents the `WEBSOCKET_CONNECT_ERROR` (code 13001) by ensuring upgrade requests are properly forwarded without recreation.

### Configuration Constants and Properties

Key configuration values are centralized in [`SpringCloudGatewayConstant.java`](https://github.com/apache/linkis/blob/main/SpringCloudGatewayConstant.java) and `linkis-mg-gateway.properties`. The `FIXED_INSTANCE` header name and WebSocket routing headers are defined as constants, while the properties file controls authentication and proxy behaviors through flags like `wds.linkis.gateway.conf.enable.token.auth`.

## Step-by-Step Configuration for High-Availability Routing

### Enable Authentication and Proxy Settings

Configure the gateway security layer by modifying `linkis-dist/package/conf/linkis-mg-gateway.properties` or the equivalent Spring profile:

```properties
wds.linkis.gateway.conf.enable.proxy.user=false
wds.linkis.gateway.conf.enable.token.auth=true
wds.linkis.is.gateway=true

```

These properties are consumed by `GatewayAuthorizationFilter` during initialization. Changes require a restart of the gateway service to take effect.

### Configure Instance Affinity with FIXED_INSTANCE Headers

For stateful operations requiring session persistence, clients must include the `FIXED_INSTANCE` header:

```http
GET /api/v1/engine/exec HTTP/1.1
Host: gateway.example.com
FIXED_INSTANCE: 10.0.2.15:9003
Authorization: Bearer <token>

```

The `IpPriorityLoadBalancer` extracts this header value and attempts to route to the specified instance. If `10.0.2.15:9003` is unavailable, the load balancer automatically falls back to a random healthy instance from the service registry, ensuring high availability while preserving affinity when possible.

### Implement Custom Load Balancer Strategies

To override the default random selection behavior for specific services, provide a custom bean configuration:

```java
@Configuration
public class CustomLoadBalancerConfig {

    @Bean
    public ReactorServiceInstanceLoadBalancer myServiceLoadBalancer(
            ObjectProvider<ServiceInstanceListSupplier> supplierProvider) {
        return new IpPriorityLoadBalancer("my-service", supplierProvider);
    }
}

```

This configuration ensures that the `IpPriorityLoadBalancer` logic—including `FIXED_INSTANCE` header support—is applied to your custom service definitions.

### Ensure WebSocket Connection Stability

WebSocket connections require careful handling to prevent the `WEBSOCKET_CONNECT_ERROR` (code 13001). Ensure your routing configuration respects the `ROUTE_URI_FOR_WEB_SOCKET_HEADER` constant defined in `SpringCloudGatewayWebsocketFilter`. The filter automatically manages upgrade headers, but clients should avoid retrying upgrade requests rapidly, as this triggers the duplicate connection protection logic.

### Integrate Health Checks with Service Registry

High availability depends on accurate health status in the service registry. Configure Eureka client settings in the gateway's [`application.yml`](https://github.com/apache/linkis/blob/main/application.yml):

```yaml
eureka:
  client:
    serviceUrl:
      defaultZone: http://eureka:8761/eureka/
    fetchRegistry: true
    registerWithEureka: false

```

The `IpPriorityLoadBalancer` relies on `ServiceInstanceListSupplier` to provide candidate instances. Since the supplier filters out instances not marked **UP** in Eureka, the load balancer never routes to unhealthy nodes, providing automatic failover capabilities.

## Code Implementation Examples

### Java Client with FIXED_INSTANCE Header

When building clients that require instance affinity, use `WebClient` with the custom header:

```java
WebClient client = WebClient.builder()
    .baseUrl("http://gateway.example.com")
    .defaultHeader("FIXED_INSTANCE", "10.0.2.15:9003")
    .defaultHeader(HttpHeaders.AUTHORIZATION, "Bearer " + token)
    .build();

Mono<String> response = client.get()
    .uri("/api/v1/engine/exec")
    .retrieve()
    .bodyToMono(String.class);

```

### Custom Load Balancer Bean Configuration

To apply the Linkis load balancing logic to additional services:

```java
@Configuration
public class LoadBalancerConfig {
    @Bean
    public ReactorServiceInstanceLoadBalancer linkisLoadBalancer(
            ObjectProvider<ServiceInstanceListSupplier> provider) {
        return new IpPriorityLoadBalancer("linkis-service", provider);
    }
}

```

### YAML Configuration for Token Authentication

Externalize gateway security settings in [`application.yml`](https://github.com/apache/linkis/blob/main/application.yml):

```yaml
wds:
  linkis:
    gateway:
      conf:
        enable:
          token:
            auth: true
          proxy:
            user: false
    is:
      gateway: true
spring:
  server:
    port: 9001

```

## Key Source Files for Reference

| File | Path | Purpose |
|------|------|---------|
| [`GatewayAuthorizationFilter.java`](https://github.com/apache/linkis/blob/main/GatewayAuthorizationFilter.java) | [`linkis-spring-cloud-services/linkis-service-gateway/linkis-spring-cloud-gateway/src/main/java/org/apache/linkis/gateway/springcloud/http/GatewayAuthorizationFilter.java`](https://github.com/apache/linkis/blob/main/linkis-spring-cloud-services/linkis-service-gateway/linkis-spring-cloud-gateway/src/main/java/org/apache/linkis/gateway/springcloud/http/GatewayAuthorizationFilter.java) | Token validation and request context building |
| [`IpPriorityLoadBalancer.java`](https://github.com/apache/linkis/blob/main/IpPriorityLoadBalancer.java) | [`linkis-spring-cloud-services/linkis-service-gateway/linkis-spring-cloud-gateway/src/main/java/org/apache/linkis/gateway/springcloud/http/IpPriorityLoadBalancer.java`](https://github.com/apache/linkis/blob/main/linkis-spring-cloud-services/linkis-service-gateway/linkis-spring-cloud-gateway/src/main/java/org/apache/linkis/gateway/springcloud/http/IpPriorityLoadBalancer.java) | Instance affinity and fallback logic |
| [`SpringCloudGatewayWebsocketFilter.java`](https://github.com/apache/linkis/blob/main/SpringCloudGatewayWebsocketFilter.java) | [`linkis-spring-cloud-services/linkis-service-gateway/linkis-spring-cloud-gateway/src/main/java/org/apache/linkis/gateway/springcloud/websocket/SpringCloudGatewayWebsocketFilter.java`](https://github.com/apache/linkis/blob/main/linkis-spring-cloud-services/linkis-service-gateway/linkis-spring-cloud-gateway/src/main/java/org/apache/linkis/gateway/springcloud/websocket/SpringCloudGatewayWebsocketFilter.java) | WebSocket upgrade handling |
| [`SpringCloudGatewayConstant.java`](https://github.com/apache/linkis/blob/main/SpringCloudGatewayConstant.java) | [`linkis-spring-cloud-services/linkis-service-gateway/linkis-spring-cloud-gateway/src/main/java/org/apache/linkis/gateway/springcloud/http/SpringCloudGatewayConstant.java`](https://github.com/apache/linkis/blob/main/linkis-spring-cloud-services/linkis-service-gateway/linkis-spring-cloud-gateway/src/main/java/org/apache/linkis/gateway/springcloud/http/SpringCloudGatewayConstant.java) | Header constants like `FIXED_INSTANCE` |
| `linkis-mg-gateway.properties` | `linkis-dist/package/conf/linkis-mg-gateway.properties` | Default gateway configuration flags |
| [`LinkisGatewayApplication.java`](https://github.com/apache/linkis/blob/main/LinkisGatewayApplication.java) | [`linkis-spring-cloud-services/linkis-service-gateway/linkis-spring-cloud-gateway/src/main/java/org/apache/linkis/gateway/springcloud/LinkisGatewayApplication.java`](https://github.com/apache/linkis/blob/main/linkis-spring-cloud-services/linkis-service-gateway/linkis-spring-cloud-gateway/src/main/java/org/apache/linkis/gateway/springcloud/LinkisGatewayApplication.java) | Spring Boot entry point registering filters |

## Summary

- **Enable token authentication** via `wds.linkis.gateway.conf.enable.token.auth=true` in `linkis-mg-gateway.properties` to secure all routed requests.
- **Use instance affinity** by sending the `FIXED_INSTANCE` header; the `IpPriorityLoadBalancer` will route to the specified host:port or fall back to healthy instances automatically.
- **Configure Eureka integration** with `fetchRegistry: true` to ensure the load balancer only receives healthy service instances, preventing routing to dead nodes.
- **Handle WebSocket stability** by ensuring clients do not retry upgrade requests rapidly, avoiding the `WEBSOCKET_CONNECT_ERROR` (code 13001) triggered by `SpringCloudGatewayWebsocketFilter`.
- **Customize load balancing** by providing a custom `ReactorServiceInstanceLoadBalancer` bean if you need service-specific routing strategies beyond the default random selection.

## Frequently Asked Questions

### How does the Linkis gateway handle failover when a fixed instance becomes unavailable?

When the `FIXED_INSTANCE` header specifies a target host:port that is unhealthy or offline, the `IpPriorityLoadBalancer` automatically falls back to a random selection from the available healthy instances registered in Eureka. This ensures high availability while preserving affinity when the preferred instance is healthy.

### What is the purpose of the FIXED_INSTANCE header in Linkis routing?

The `FIXED_INSTANCE` header, defined in `SpringCloudGatewayConstant.FIXED_INSTANCE`, enables client-driven instance affinity. When present, the `IpPriorityLoadBalancer` attempts to route the request to the exact IP and port specified, which is essential for stateful operations like engine execution sessions that must maintain connection to a specific backend instance.

### How can I prevent WebSocket connection errors in the Linkis gateway?

To avoid the `WEBSOCKET_CONNECT_ERROR` (error code 13001), ensure that clients do not rapidly retry WebSocket upgrade requests. The `SpringCloudGatewayWebsocketFilter` manages connection state and prevents duplicate WebSocket creation. Configure your client to respect the connection lifecycle and ensure the `ROUTE_URI_FOR_WEB_SOCKET_HEADER` constant matches your routing rules.

### Where are the gateway authentication settings configured in Linkis?

Authentication settings are controlled through properties in `linkis-mg-gateway.properties` or equivalent Spring profiles. The key properties are `wds.linkis.gateway.conf.enable.token.auth` to enable token validation and `wds.linkis.gateway.conf.enable.proxy.user` to control user-level proxy behavior. These are consumed by the `GatewayAuthorizationFilter` during request processing.