YvCeung opened a new pull request, #8102:
URL: https://github.com/apache/incubator-seata/pull/8102

   <!--
       Licensed to the Apache Software Foundation (ASF) under one or more
       contributor license agreements.  See the NOTICE file distributed with
       this work for additional information regarding copyright ownership.
       The ASF licenses this file to You under the Apache License, Version 2.0
       (the "License"); you may not use this file except in compliance with
       the License.  You may obtain a copy of the License at
   
       http://www.apache.org/licenses/LICENSE-2.0
       
       Unless required by applicable law or agreed to in writing, software
       distributed under the License is distributed on an "AS IS" BASIS,
       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       See the License for the specific language governing permissions and
       limitations under the License.
   -->
   <!-- Please make sure you have read and understood the contributing 
guidelines -->
   
   - [x] I have read the 
[CONTRIBUTING.md](https://github.com/apache/incubator-seata/blob/2.x/CONTRIBUTING.md)
 guidelines.
   - [ ] I have registered the PR 
[changes](https://github.com/apache/incubator-seata/tree/2.x/changes).
   
   ### Ⅰ. Describe what this PR did
   
   This PR introduces server-side load balancing for TC-to-RM reverse 
communication (branch commit/rollback), addressing the issue where 
`ChannelManager.getChannel()` always selects the first available channel with 
no distribution strategy, causing requests to concentrate on specific RM 
instances.
   
   **Core changes:**
   
   1. **New `ServerLoadBalance` SPI interface** 
   
   2. **Three LB strategy implementations:**
      - `ServerRandomLoadBalance` 
      - `ServerRoundRobinLoadBalance`
      - `ServerLeastActiveLoadBalance` 
   3. **Simplified configuration system** (`ServerLoadBalanceFactory`): Only 
two configuration keys:
      - `server.loadBalance.at.type` — LB algorithm for AT mode
      - `server.loadBalance.tcc.type` — LB algorithm for TCC mode
      
      If not configured or configured as blank, the original priority-based 
channel selection logic is used (fully backward compatible). If explicitly 
configured, the specified LB algorithm is loaded via SPI.
   
   4. **XA and SAGA explicitly excluded**: XA's second-phase operations are 
bound to the local database connection of the original RM; SAGA's state machine 
execution context is held in memory with no distributed lock protection. Both 
modes always use the original priority-based channel selection.
   
   5. **`ChannelManager` refactoring**: `getChannel()` collects all active 
candidate channels and applies the LB algorithm when configured; 
`getRmChannels()` applies LB per resourceId. The original 
`getChannelByPriority()` logic is preserved as the default fallback path.
   
   ### Ⅱ. Does this pull request fix one issue?
   <!-- If that, add "fixes #xxx" below in the next line, for example, fixes 
#97. -->
   
   fix #7758 
   ### Ⅲ. Why don't you add test cases (unit test/integration test)?
   
   Unit tests are included:
   
   - `ServerLoadBalanceFactoryTest` — verifies that XA/SAGA return null, 
unconfigured AT/TCC return null, SPI loading works for all three strategies, 
and invalid type names are handled gracefully
   - `ServerLoadBalanceBehaviorTest` — verifies randomness for 
`RandomLoadBalance`, even distribution for `RoundRobinLoadBalance`, 
least-active selection for `LeastActiveLoadBalance`, and single-candidate edge 
case
   
   ### Ⅳ. Describe how to verify it
   
   
   ### Ⅴ. Special notes for reviews
   
   - **Backward compatibility**: When no LB type is configured (the default), 
the behavior is identical to the original logic — `getChannelByPriority()` is 
used. Zero risk for existing deployments.
   - **Why not reuse `LoadBalance` interface from `discovery` module**: 
`LoadBalance` operates on `InetSocketAddress` and lives in the `discovery` 
module. `ChannelManager` is in `core`. Making `core` depend on `discovery` 
would create a circular dependency. The server-side context (`RpcContext` with 
channel, applicationId, activeCount) is fundamentally different from the 
client-side context.
   - **Why ConsistentHash is not included**: TC-to-RM requests are driven by 
the TC server. Server-side load balancing is opt-in via configuration 
(server.loadBalance.tcc.type). When enabled, it directly selects from all 
active RM candidates; when disabled, it falls back to the original 
exact-priority matching logic. Session affinity based on xid is unnecessary for 
AT mode (stateless second-phase) and does not fit TCC's current design where LB 
and priority-based selection are mutually exclusive strategies rather than 
layered fallbacks.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to