MySQL读写分离一主多从实现
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                MySQL读写分离一主多从实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                一主多從
實際項目中 
 一般都是采用一主多從的架構 
 修改數據源,動態切換數據源 
 
DynamicDataSource
定義動態數據源
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;/*** 定義動態數據源,實現通過集成Spring提供的AbstractRoutingDataSource,只需要實現determineCurrentLookupKey方法即可* * 由于DynamicDataSource是單例的,線程不安全的,所以采用ThreadLocal保證線程安全,由DynamicDataSourceHolder完成。**/ public class DynamicDataSource extends AbstractRoutingDataSource {private static final Logger LOGGER = LoggerFactory.getLogger(DynamicDataSource.class);private Integer slaveCount;// 輪詢計數,初始為-1,AtomicInteger是線程安全的private AtomicInteger counter = new AtomicInteger(-1);// 記錄讀庫的keyprivate List<Object> slaveDataSources = new ArrayList<Object>(0);@Overrideprotected Object determineCurrentLookupKey() {// 使用DynamicDataSourceHolder保證線程安全,并且得到當前線程中的數據源keyif (DynamicDataSourceHolder.isMaster()) {Object key = DynamicDataSourceHolder.getDataSourceKey(); if (LOGGER.isDebugEnabled()) {LOGGER.debug("當前DataSource的key為: " + key);}return key;}Object key = getSlaveKey();if (LOGGER.isDebugEnabled()) {LOGGER.debug("當前DataSource的key為: " + key);}return key;}@SuppressWarnings("unchecked")@Overridepublic void afterPropertiesSet() {super.afterPropertiesSet();// 由于父類的resolvedDataSources屬性是私有的子類獲取不到,需要使用反射獲取Field field = ReflectionUtils.findField(AbstractRoutingDataSource.class, "resolvedDataSources");field.setAccessible(true); // 設置可訪問try {Map<Object, DataSource> resolvedDataSources = (Map<Object, DataSource>) field.get(this);// 讀庫的數據量等于數據源總數減去寫庫的數量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);}}/*** 輪詢算法實現* * @return*/public Object getSlaveKey() {// 得到的下標為:0、1、2、3……Integer index = counter.incrementAndGet() % slaveCount;if (counter.get() > 9999) { // 以免超出Integer范圍counter.set(-1); // 還原}return slaveDataSources.get(index);} }總結
以上是生活随笔為你收集整理的MySQL读写分离一主多从实现的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: MySQL读写分离事务策略实现
- 下一篇: 微服务架构特点
