[ISSUE #10490] Eliminate per-RPC allocation from Logback status, TopicMessageType toLowerCase, and RemotingHelper eager evaluation#10491
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR reduces per-call allocations in hot paths by introducing reusable OpenTelemetry AttributeKey singletons for metrics labels and by avoiding eager default-string creation in request/response code formatting.
Changes:
- Add typed
AttributeKeylabel constants for broker/remoting metrics and migrate selected call sites to use them. - Optimize request/response code description helpers to avoid unnecessary
String.valueOf(...)allocations when a mapping exists. - Precompute/canonicalize metric label values and adjust logging configuration behavior.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| remoting/src/main/java/org/apache/rocketmq/remoting/metrics/RemotingMetricsManager.java | Switches attribute building to use typed AttributeKey constant for protocol type. |
| remoting/src/main/java/org/apache/rocketmq/remoting/metrics/RemotingMetricsConstant.java | Introduces reusable typed AttributeKey singletons for remoting metric labels. |
| remoting/src/main/java/org/apache/rocketmq/remoting/common/RemotingHelper.java | Avoids eager default-string construction in code-to-description helpers. |
| common/src/main/java/org/apache/rocketmq/common/attribute/TopicMessageType.java | Caches lowercase metrics label value to avoid repeated toLowerCase() and enforce Locale.ROOT. |
| broker/src/main/resources/rmq.broker.logback.xml | Adds a NopStatusListener, changing visibility of Logback status output. |
| broker/src/main/java/org/apache/rocketmq/broker/metrics/PopMetricsManager.java | Migrates selected label puts to typed AttributeKey constants. |
| broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsManager.java | Migrates multiple metrics label puts to typed AttributeKey constants. |
| broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsConstant.java | Introduces reusable typed AttributeKey singletons for broker metric labels. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #10491 +/- ##
=============================================
- Coverage 48.18% 48.14% -0.05%
+ Complexity 13407 13397 -10
=============================================
Files 1377 1377
Lines 100838 100843 +5
Branches 13034 13037 +3
=============================================
- Hits 48590 48546 -44
- Misses 46314 46323 +9
- Partials 5934 5974 +40 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Review by github-manager-bot
Summary
This PR eliminates three per-RPC micro-allocations on the hot path: Logback status listener overhead, TopicMessageType.metricsValue repeated toLowerCase(), and RemotingHelper eager String.valueOf() evaluation. Additionally, it pre-builds OTel AttributeKey singletons to avoid per-call InternalAttributeKeyImpl allocation.
Findings
-
[Info]
TopicMessageType.java— CachingmetricsValuewithLocale.ROOTis correct and avoids per-call allocation. Good use ofLocale.ROOTfor deterministic casing. -
[Info]
RemotingHelper.java— Theget()+ null check pattern replacinggetOrDefault(code, String.valueOf(code))is a valid optimization to avoid eager evaluation. Consider adding a brief inline comment explaining why the null-check pattern is used instead ofgetOrDefault, since the intent is not immediately obvious to readers. -
[Info]
BrokerMetricsConstant.java/RemotingMetricsConstant.java— Pre-buildingAttributeKeysingletons is a sound optimization for OTel hot paths. The alignment style (extra spaces for=) is consistent within the block but may trigger checkstyle rules if the project enforces no-multi-spaces. Worth verifying CI passes. -
[Warning] The PR description mentions this is stacked on PR #10443. The diff currently includes 8 files (5 extra from #10443). Reviewers should focus on the 3 core delta files. Please rebase onto
developafter #10443 merges to keep the diff clean.
Suggestions
- Consider adding a microbenchmark (JMH) to quantify the per-RPC allocation reduction, especially for the
AttributeKeysingleton optimization. This would help justify the change and prevent regression. - The
NopStatusListeneraddition is fine, but consider documenting in a comment why it was added (suppress Logback internal status events to avoid per-RPC allocation).
Verdict
Clean performance optimization with no correctness concerns. The changes are well-targeted and low-risk.
Automated review by github-manager-bot
077be95 to
4294fae
Compare
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Review by github-manager-bot
Summary
Combined performance optimization covering four areas: (1) pre-built AttributeKey singletons in metrics constants, (2) NopStatusListener in Logback config to suppress internal status output, (3) TopicMessageType.metricsValue pre-computed in constructor to avoid repeated toLowerCase(), and (4) RemotingHelper request/response code description lookup using direct get() + null check instead of getOrDefault().
Findings
- [Info] The
NopStatusListeneraddition is a good defensive measure — Logback's internal status printer can cause unexpected allocations on the logging hot path. - [Info]
TopicMessageType.metricsValuepre-computation is clean — the enum constructor runs once at class-load, eliminating per-calltoLowerCase()on the send path. - [Warning]
RemotingHelper.getRequestCodeDesc/getResponseCodeDesc: replacinggetOrDefault(code, "")withget(code)+ null check avoids allocating the empty-string default on every call. This is correct since the returned value is used for metrics labels where empty vs null doesn't matter for OTel. However, verify that no downstream code calls.isEmpty()or.equals("")on the returned value — those would now get NPE instead of false. - [Info] The
AttributeKeysingletons here overlap with PR #10443. If both PRs target the same branch, ensure they don't conflict during merge.
Suggestions
- For
RemotingHelper, consider adding a brief comment explaining whyget() + null checkis preferred overgetOrDefault()(allocation avoidance on hot path), so future refactors don't "simplify" it back.
No blocking issues. Well-structured multi-part optimization.
Automated review by github-manager-bot
…, TopicMessageType toLowerCase, and RemotingHelper eager evaluation
4294fae to
8d7a462
Compare
RockteMQ-AI
left a comment
There was a problem hiding this comment.
- [Info] The
AttributeKeysingleton pre-building in metrics constants (from earlier commits) eliminates per-callInternalAttributeKeyImplallocation. This is a solid optimization for high-throughput scenarios.
Changes Since Last Review
The new commits (June 20) appear to maintain the same optimization strategy. All changes remain focused on reducing GC pressure on the hot path without altering functional behavior.
Verdict
✅ Clean, focused performance optimization. No blocking issues.
Automated re-review by github-manager-bot
Server Benchmark Results (2026-06-22)Environment: 8C30G broker, Dragonwell JDK 21, 1KB msg, 128 queues, sync mode, 256 threads, 20s warmup + 30s collect Producer-only (steady state, lines 3-5)
Minor optimizations (TopicMessageType cache, RemotingHelper get+null check, NopStatusListener, metricsValue cache). The -8.3% TPS is at the edge of the noise band (baseline variance is 5-10%). GC reduction (-40%) confirms reduced allocation. These micro-optimizations are not on the Send hot path, so TPS impact is expected to be minimal in production. |
Which Issue(s) This PR Fixes
Fixes #10490
Brief Description
Three independent per-RPC micro-allocations eliminated:
NopStatusListener— Add<statusListener class="ch.qos.logback.core.status.NopStatusListener"/>tormq.broker.logback.xmlto suppress Logback internal status event callbacks.TopicMessageType.metricsValuecache —getMetricsValue()was callingvalue.toLowerCase()per invocation. Now cachesmetricsValueas afinalfield withLocale.ROOT.RemotingHelpereager evaluation fix —Map.getOrDefault(code, String.valueOf(code))eagerly evaluatesString.valueOf(code)even on cache hit. Changed toget()+ null check.Stacked on PR #10443. Will rebase on
developafter #10443 merges to show only the 3 files.How Did You Test This Change?