Why Does Dubbo 2.7.3 Throw Duplicate Unregister Errors and How to Fix It
This article investigates the duplicate unregister bug in Dubbo 2.7.3, explains how the shutdown hook interaction causes the error, and shows how the issue was fixed in later versions and can be mitigated without upgrading the whole framework.
Background
I am responsible for the in‑house Dubbo registry center, and we frequently receive reports that Dubbo interface unregistration throws errors. Investigation revealed that the same interface was being unregistered twice, and because our registry does not allow repeated unregistration, the second call fails with an "instance not found" error.
Although the error only logs a single line and does not affect business, I decided to investigate further because repeated unregistration also prolongs application shutdown and slows rollback.
Problem Reproduction
Using the business side's customized Dubbo 2.7.3 (based on the open‑source 2.7.3 with security fixes and business adaptations), I ran a demo and killed the process, which reproduced the error.
Testing with the pure open‑source 2.7.3 produced the same error, confirming it is not caused by our internal modifications.
Switching to Dubbo 2.7.7 eliminated the error, indicating that the duplicate unregistration is a bug in 2.7.3 that was fixed in later versions.
Therefore, simply upgrading Dubbo would solve the problem, but internal modifications and business constraints make a direct upgrade non‑trivial.
Our internal Dubbo has custom changes that need to be merged into the new version, which is cumbersome.
Even if we upgraded, pushing the new version to the business side cannot be done quickly.
Thus we need to locate the root cause of the bug and see whether the registry extension can be patched; otherwise we must fix it in our customized Dubbo version.
Investigation
Suspecting ShutdownHook
Because I had recently studied ShutdownHook, I first suspected it might be involved.
In Dubbo 2.7.3 the shutdown hook implementation resides in the DubboShutdownHook class, and the relationship is shown below.
Both Dubbo and Spring register a ShutdownHook, so I debugged to see if the hook was registered twice. Using IntelliJ IDEA, the process must be killed manually to trigger the debug; clicking the IDE’s close button does not fire the hook.
Setting a breakpoint in DubboShutdownHook.doDestroy showed it executes only once, meaning Spring and Dubbo each register the hook only once. The following diagram illustrates the registration order.
In Dubbo, the register and unregister methods manage the ShutdownHook. When Spring’s ConfigurableApplicationContext is initialized, it registers its own hook and then calls DubboShutdownHook.getDubboShutdownHook().unregister(), effectively replacing Dubbo’s hook with Spring’s.
public static void addApplicationContext(ApplicationContext context) {
CONTEXTS.add(context);
if (context instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) context).registerShutdownHook();
DubboShutdownHook.getDubboShutdownHook().unregister();
}
BeanFactoryUtils.addApplicationListener(context, SHUTDOWN_HOOK_LISTENER);
}This proved the ShutdownHook suspicion was not the cause of the duplicate unregistration.
Continuing Investigation from the Unregister Stack
Because the issue could be reproduced reliably, I examined the call stacks of the two unregister invocations. Adding breakpoints in the registry extension’s unregister method revealed two distinct stack traces.
The code shows that AbstractRegistryFactory.destroyAll() destroys all registries, which in turn calls destroyProtocols(). Each protocol obtains the registry and invokes its unregister method, leading to two separate unregister calls.
Thus a single ShutdownHook execution triggers two unregisters.
In Dubbo 2.7.7, the registry protocol adds a small piece of code during destruction: after the registry is destroyed, a destroyed flag is set to true. When the protocol later attempts to obtain the registry again, it receives a null registry, so the subsequent unregister call has no effect.
The fix was introduced in a pull request that landed in version 2.7.5.
https://github.com/apache/dubbo/pull/5450
Therefore the duplicate unregister bug exists in Dubbo 2.7.0 ~ 2.7.4, was fixed in 2.7.5, and while Zookeeper registries may not surface an error, the extra unregistration slows down application shutdown.
Summary
Dubbo duplicate unregister issue exists in 2.7.0‑2.7.4 and is fixed in 2.7.5; ZK registry does not error but the slowdown is real.
The problem can be resolved by adjusting the registry extension so that destroy is invoked only once.
Investigating even small issues can reveal clever designs, such as Dubbo’s elegant handling of ShutdownHook registration.
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.
