Cloud Native 12 min read

Extending Spring Cloud Ribbon for Weight‑Based and Label‑Based Routing

This guide explains how to enhance Spring Cloud's Ribbon with custom rules that enable weight‑based traffic distribution and label‑driven routing, covering project setup, core microservice components, implementation approaches, testing procedures, and practical examples for real‑world microservice deployments.

Programmer DD
Programmer DD
Programmer DD
Extending Spring Cloud Ribbon for Weight‑Based and Label‑Based Routing

Project Overview

The article demonstrates how to extend Spring Cloud to provide advanced routing capabilities such as weight‑based load balancing and label‑driven traffic control, which are not available out‑of‑the‑box. It walks through a complete microservice demo consisting of a configuration center, Eureka registry, Zuul gateway, provider and consumer services, and a shared core library.

Core Microservice Components

Config Center : Runs on port 8888, reads application-dev.properties (global config) and supplies configuration to all services, including the Eureka address.

Consumer Service : Runs on port 18090, calls the provider to demonstrate header propagation.

Core Library : A shared JAR that all services import; uses @AutoConfiguration to provide zero‑configuration Spring Cloud setup.

Eureka Registry : Runs on port 8761, exposes a /metadata endpoint for per‑instance metadata.

Provider Service : Runs on port 18090 (multiple instances), contains no special business logic.

Zuul Gateway : Runs on port 8080, extracts a label from the incoming request token and forwards it via HTTP headers.

Extending Ribbon for Weight‑Based Routing

The key extension point is Ribbon's load‑balancing rule. By implementing a custom rule ( LabelAndWeightMetadataRule) that reads a weight value from each instance's metadata stored in Eureka, traffic can be distributed proportionally to the configured weights.

Three integration methods are presented:

AutoConfig Bean : Declare the custom rule as a @Bean to replace the default ZoneAvoidanceRule. Quick for prototyping but forces a global setting.

PropertiesFactory Extension : Modify org.springframework.cloud.netflix.ribbon.PropertiesFactory to support the Netflix‑style global property ribbon.NFLoadBalancerRuleClassName. This allows a global rule defined in application-dev.properties while still permitting per‑service overrides. Note that the factory fields are private, making this approach fragile.

@RibbonClient Configuration : Use Spring Cloud’s official @RibbonClient annotation (currently only available in unit‑test modules) to bind a custom rule to a specific service.

Testing Weight‑Based Routing

Start the services in order: config, eureka, two provider instances (different ports via --server.port), consumer, and zuul. Use the metadata UI at http://localhost:8761/metadata.html to set each provider’s weight (changes take ~2 minutes to propagate). Then repeatedly call http://localhost:8080/provider/user or http://localhost:8080/consumer/test to observe traffic distribution according to the configured weights.

Label‑Based Routing Extension

After weight routing, the article adds label‑driven routing. Requests entering through Zuul are tagged (e.g., by user, IP, or custom criteria) and the label is stored in a thread‑local variable. Because Hystrix runs commands in separate threads, the label is transferred using HystrixRequestVariableDefault rather than plain ThreadLocal. The label is then injected into outgoing HTTP headers via a Spring MVC interceptor ( CoreHeaderInterceptor) and a RestTemplate interceptor ( CoreHttpRequestInterceptor), allowing downstream services to access the label.

In Ribbon’s custom rule, the label is read from the thread‑local variable to select the appropriate instance based on metadata such as orLabel or andLabel. This enables scenarios like gray releases, region‑based routing, or read/write separation.

Full Test Flow for Labels

Configure two provider instances with different label metadata ( orLabel=CN,Test for the first, andLabel=EN,Male for the second). Send requests with an Authorization header that the PreFilter interprets as a simulated token containing the desired label. Verify that Zuul routes all traffic to the matching provider and that the consumer also follows the same routing logic.

Conclusion

By customizing Ribbon’s rule and propagating labels through Zuul and Hystrix, Spring Cloud can achieve fine‑grained traffic control comparable to Dubbo’s built‑in capabilities. The article provides a complete, reproducible example and multiple integration options, enabling developers to tailor routing strategies to any business requirement.

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.

MicroservicesroutingSpring CloudRibbonZuulLabelWeight
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

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.