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

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

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:

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:

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

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:

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:

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

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

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →