Mastering Dubbo Tag Router: Isolate Parallel Tests with Dynamic Tag Routing
This article explains how Dubbo's tag router feature can isolate parallel test environments by assigning tags to providers and consumers, outlines configuration methods, compares it with version/group routing, discusses known attachment bugs, and presents a practical SPI‑filter solution for reliable tag propagation.
Introduction to Tag Routing
When multiple Dubbo applications (e.g., A, B, C, D, E) are developed and tested in parallel, changes in one requirement may unintentionally affect another, causing test chaos.
Common solutions include:
Deploy a full system per project with its own registry – simple but resource‑intensive.
Hard‑code or configure provider IP/port in the consumer – simple but hard to maintain in complex dependencies.
Use logical grouping to route requests correctly – resource‑efficient but harder to implement; this is the approach explored in this article.
Dubbo 2.6.6 introduced a tag router to solve this problem.
How Tag Routing Works
Tag routing groups one or more service providers together, restricting traffic to flow only within the specified group, enabling scenarios such as blue‑green or gray releases.
For providers, tags can be set statically via JVM arguments (e.g., -Ddubbo.provider.tag=env_tag) or dynamically by modifying the provider’s registration in the registry. The article uses static tagging.
For consumers, the tag is attached to each invocation using attachment. The attachment value persists throughout a remote call, allowing a single line of code to propagate the tag. Currently only hard‑coded dubbo.tag is supported, and it should be set via a servlet filter or a custom SPI filter because RpcContext is thread‑bound.
Implementation Simplicity
The core implementation consists of only a few lines of code (illustrated in the image below).
Unlike Dubbo’s static version and group routing, tag routing is dynamic: even if a tag does not match, the request remains in the invoker list and routing logic is executed at each call.
Tag Routing Degradation Rules
If dubbo.tag=tag1 is set on the consumer, providers with tag=tag1 are preferred. If none exist, the request falls back to providers with an empty tag. To change this behavior to throw an error instead, set request.tag.force=true.
If no tag is set on the consumer, only providers with an empty tag are matched; requests with non‑matching tags will not be routed.
The "Bug" in Tag Routing
Testing shows that the consumer’s dubbo.tag is passed to the provider via attachment, but the attachment is cleared after the request completes, so the tag is present only on the first call.
Building a Parallel Test Environment with Dubbo Tag Routing
Based on a GitHub PR, the author suggests using a servlet filter or a custom SPI filter to set dubbo.tag. The article proposes extending Dubbo’s SPI filter to fill the attachment, store the tag on the provider side, and re‑inject it for subsequent calls.
Scenario: two parallel test projects require two tags – green for requirement 1 and red for requirement 2.
Deploy a stable environment without tags (ABCD) and create new applications A & C with tag=green, and A & B & E with tag=red, all registering to the same registry.
At the request entry point (gateway or tool), inject the appropriate tag into the attachment.
On the provider side, store the incoming tag in a ThreadLocal (e.g., EnvContext).
The first call triggers tag routing; after the call and the ConsumerContextFilter, the tag is re‑added to the attachment for the next call.
When the call finishes, DubboTagProviderFilter clears the stored tag to avoid contaminating subsequent requests.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Xiao Lou's Tech Notes
Backend technology sharing, architecture design, performance optimization, source code reading, troubleshooting, and pitfall practices
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
