Skip to main content
Version: 4.6

Custom Load Balancing Strategy

Overview​

As shown below, the slave group holds three datasources. When a user switches to slave, a load balancing algorithm is applied.

The framework ships with two load balancing algorithms:

  • LoadBalanceDynamicDataSourceStrategy — round-robin, the default.
  • RandomDynamicDataSourceStrategy — random.
spring:
datasource:
dynamic:
datasource:
master:
username: sa
password: ""
url: jdbc:h2:mem:test
driver-class-name: org.h2.Driver
schema: db/schema.sql
slave_1:
username: sa
password: ""
url: jdbc:h2:mem:test
driver-class-name: org.h2.Driver
slave_2:
username: sa
password: ""
url: jdbc:h2:mem:test
driver-class-name: org.h2.Driver
slave_3:
username: sa
password: ""
url: jdbc:h2:mem:test
driver-class-name: org.h2.Driver
strategy: com.baomidou.dynamic.datasource.strategy.LoadBalanceDynamicDataSourceStrategy

How to customize​

If neither built-in strategy fits your needs, you can write your own by referring to the source code. For now it can only be changed globally.

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import javax.sql.DataSource;

public class RandomDynamicDataSourceStrategy implements DynamicDataSourceStrategy {
public RandomDynamicDataSourceStrategy() {
}

public DataSource determineDataSource(List<DataSource> dataSources) {
return (DataSource)dataSources.get(ThreadLocalRandom.current().nextInt(dataSources.size()));
}
}

Group name rules​

The part before the first _ of a datasource name is the group name: both slave_1 and slave_2 belong to the slave group. @DS("slave") routes to a group and the strategy decides which member is used; @DS("slave_1") targets one concrete datasource and skips the strategy.

Naming is topology — see @DS semantics and precedence.

FAQ​

Q1: When a replica goes down, does traffic fail over to another replica or to the primary automatically?​

No. The framework has no built-in failover (see the related proposals #84, #108 and #790).

A possible do-it-yourself path: implement your own DynamicDataSourceStrategy that probes availability while picking a member and skips the unavailable ones.

Q2: Reading right after a write — how do I deal with primary/replica lag?​

The framework makes no lag judgement (#361). Common practices on the application side: run reads that need strong consistency after a write inside the same transaction, or specify @DS("master") explicitly; you can also bring in an external component (such as ShardingSphere's HintManager) to force routing to the primary.

Q3: How do I configure multiple primaries and multiple replicas?​

master_1 and master_2 themselves form the master group — it is only naming (#128). If the write side also needs load balancing, @DS("master") plus a strategy is enough; write conflicts across multiple primaries, however, are yours to evaluate.

Q4: A write fails after an explicit @DS("slave")?​

That means INSERT/UPDATE/DELETE really were routed to a read-only replica (#190). This is exactly the advantage of the automatic read/write splitting plugin mode: write statements always go to the primary.

Q5: When used together with ShardingSphere, who owns read/write splitting?​

Do not configure it twice: either let ShardingSphere handle read/write splitting (dynamic only manages multiple datasources), or use this framework's plugin (#314, #690).

Q6: Why is my @DS("slave") not taking effect / why is read/write splitting not working?​

First go through the @DS not working checklist. For plugin mode, check two more things: whether the plugin bean is registered, and whether the traffic really goes through MyBatis (JdbcTemplate is not controlled by the plugin).

Further reading​