1、前言java
分佈式環境下數據庫的讀寫分離策略是解決數據庫讀寫性能瓶頸的一個關鍵解決方案,更是最大限度了提升了應用中讀取 (Read)數據的速度和併發量。mysql
在進行數據庫讀寫分離的時候,咱們首先要進行數據庫的主從配置,最簡單的是一臺Master和一臺Slave(大型網站系統的話,固然會很複雜,這裏只是分析了最簡單的狀況)。經過主從配置主從數據庫保持了相同的數據,咱們在進行讀操做的時候訪問從數據庫Slave,在進行寫操做的時候訪問主數據庫Master。這樣的話就減輕了一臺服務器的壓力。git
在進行讀寫分離案例分析的時候。首先,配置數據庫的主從複製,下邊是兩種方法(任選其一便可):spring
一、MySQL5.6 數據庫主從(Master/Slave)同步安裝與配置詳解:sql
http://blog.csdn.net/xlgen157387/article/details/51331244數據庫
二、使用mysqlreplicate命令快速搭建 Mysql 主從複製:服務器
http://blog.csdn.net/xlgen157387/article/details/52452394併發
固然,只是簡單的爲了看一下如何用代碼的方式實現數據庫的讀寫分離,徹底沒必要要去配置主從數據庫,只須要兩臺安裝了 相同數據庫的機器就能夠了。框架
2、實現讀寫分離的兩種方法分佈式
具體到開發中,實現讀寫分離經常使用的有兩種方式:
一、第一種方式是咱們最經常使用的方式,就是定義2個數據庫鏈接,一個是MasterDataSource,另外一個是SlaveDataSource。更新數據時咱們讀取MasterDataSource,查詢數據時咱們讀取SlaveDataSource。這種方式很簡單,我就不贅述了。
二、第二種方式動態數據源切換,就是在程序運行時,把數據源動態織入到程序中,從而選擇讀取主庫仍是從庫。主要使用的技術是:Annotation,Spring AOP ,反射。
下面會詳細的介紹實現方式。
3、Aop實現主從數據庫的讀寫分離案例
一、項目代碼地址
目前該Demo的項目地址在開源中國 碼雲 上邊:http://git.oschina.net/xuliugen/aop-choose-db-demo
或者CSDN免費下載:
http://download.csdn.net/detail/u010870518/9724872
二、項目結構
上圖中,除了標記的代碼,其餘的主要是配置代碼和業務代碼。
三、具體分析
該項目是SSM框架的一個demo,Spring、Spring MVC和MyBatis,具體的配置文件不在過多介紹。
(1)UserContoller模擬讀寫數據
模擬讀寫數據,調用IUserService 。
(2)spring-db.xml讀寫數據源配置
<bean id="statFilter" class="com.alibaba.druid.filter.stat.StatFilter" lazy-init="true">
<property name="logSlowSql" value="true"/>
<property name="mergeSql" value="true"/>
</bean>
<!-- 數據庫鏈接 -->
<bean id="readDataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close" init-method="init" lazy-init="true">
<property name="driverClassName" value="${driver}"/>
<property name="url" value="${url1}"/>
<property name="username" value="root"/>
<property name="password" value="${password}"/>
<!-- 省略部份內容 -->
</bean>
<bean id="writeDataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close" init-method="init" lazy-init="true">
<property name="driverClassName" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="root"/>
<property name="password" value="${password}"/>
<!-- 省略部份內容 -->
</bean>
<!-- 配置動態分配的讀寫 數據源 -->
<bean id="dataSource" class="com.xuliugen.choosedb.demo.aspect.ChooseDataSource" lazy-init="true">
<property name="targetDataSources">
<map key-type="java.lang.String" value-type="javax.sql.DataSource">
<!-- write -->
<entry key="write" value-ref="writeDataSource"/>
<!-- read -->
<entry key="read" value-ref="readDataSource"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="writeDataSource"/>
<property name="methodType">
<map key-type="java.lang.String">
<!-- read -->
<entry key="read" value=",get,select,count,list,query"/>
<!-- write -->
<entry key="write" value=",add,create,update,delete,remove,"/>
</map>
</property>
</bean>
</beans>
上述配置中,配置了readDataSource和writeDataSource兩個數據源,可是交給SqlSessionFactoryBean進行管理的只有dataSource,其中使用到了:com.xuliugen.choosedb.demo.aspect.ChooseDataSource
這個是進行數據庫選擇的。
(3)ChooseDataSource
(4)DataSourceAspect進行具體方法的AOP攔截
(5)DataSourceHandler,數據源的Handler類
主要代碼,如上所述。具體細節能夠下載代碼查看。