MySQL读写分离一主多从实现
生活随笔
收集整理的這篇文章主要介紹了
MySQL读写分离一主多从实现
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一主多從
實(shí)際項(xiàng)目中
一般都是采用一主多從的架構(gòu)
修改數(shù)據(jù)源,動態(tài)切換數(shù)據(jù)源
DynamicDataSource
定義動態(tài)數(shù)據(jù)源
import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger;import javax.sql.DataSource;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import org.springframework.util.ReflectionUtils;/*** 定義動態(tài)數(shù)據(jù)源,實(shí)現(xiàn)通過集成Spring提供的AbstractRoutingDataSource,只需要實(shí)現(xiàn)determineCurrentLookupKey方法即可* * 由于DynamicDataSource是單例的,線程不安全的,所以采用ThreadLocal保證線程安全,由DynamicDataSourceHolder完成。**/ public class DynamicDataSource extends AbstractRoutingDataSource {private static final Logger LOGGER = LoggerFactory.getLogger(DynamicDataSource.class);private Integer slaveCount;// 輪詢計數(shù),初始為-1,AtomicInteger是線程安全的private AtomicInteger counter = new AtomicInteger(-1);// 記錄讀庫的keyprivate List<Object> slaveDataSources = new ArrayList<Object>(0);@Overrideprotected Object determineCurrentLookupKey() {// 使用DynamicDataSourceHolder保證線程安全,并且得到當(dāng)前線程中的數(shù)據(jù)源keyif (DynamicDataSourceHolder.isMaster()) {Object key = DynamicDataSourceHolder.getDataSourceKey(); if (LOGGER.isDebugEnabled()) {LOGGER.debug("當(dāng)前DataSource的key為: " + key);}return key;}Object key = getSlaveKey();if (LOGGER.isDebugEnabled()) {LOGGER.debug("當(dāng)前DataSource的key為: " + key);}return key;}@SuppressWarnings("unchecked")@Overridepublic void afterPropertiesSet() {super.afterPropertiesSet();// 由于父類的resolvedDataSources屬性是私有的子類獲取不到,需要使用反射獲取Field field = ReflectionUtils.findField(AbstractRoutingDataSource.class, "resolvedDataSources");field.setAccessible(true); // 設(shè)置可訪問try {Map<Object, DataSource> resolvedDataSources = (Map<Object, DataSource>) field.get(this);// 讀庫的數(shù)據(jù)量等于數(shù)據(jù)源總數(shù)減去寫庫的數(shù)量this.slaveCount = resolvedDataSources.size() - 1;for (Map.Entry<Object, DataSource> entry : resolvedDataSources.entrySet()) {if (DynamicDataSourceHolder.MASTER.equals(entry.getKey())) {continue;}slaveDataSources.add(entry.getKey());}} catch (Exception e) {LOGGER.error("afterPropertiesSet error! ", e);}}/*** 輪詢算法實(shí)現(xiàn)* * @return*/public Object getSlaveKey() {// 得到的下標(biāo)為:0、1、2、3……Integer index = counter.incrementAndGet() % slaveCount;if (counter.get() > 9999) { // 以免超出Integer范圍counter.set(-1); // 還原}return slaveDataSources.get(index);} }總結(jié)
以上是生活随笔為你收集整理的MySQL读写分离一主多从实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL读写分离事务策略实现
- 下一篇: MyCat数据库分片