首页 > 数据库技术 > 详细

spring下高可用数据库架构(读写分离+主主复制)

时间:2015-03-11 02:26:35      阅读:420      评论:0      收藏:0      [点我收藏+]

spring读写分离已经有很多博文了,在此不再赘述。这里是使用的AbstractRoutingDataSource进行干预的。

?

问题:

一主一从无法满足高可用,如果主挂了,从是无写入的,写入也无法同步到主上,后面问题很多。

?

思路:

1.数据库层实现主主复制,为了保证数据不冲突,在应用层读写分离,保证一个主是写入的,另外一个是读的。

2.灾难恢复,任何一个主挂掉,起来以后可用从另外一台同步数据。

3.应用层监听数据库是否正常,如果有一个挂机,读写都转移到另外一台主机上。对业务层透明,继续使用读写分离,但数据源转到一个源上。反之也一样。

4.如果主机挂机恢复,应用层重新设置数据源,读写数据源再次分离,对业务层透明。两台机器重新都得到使用。

?

实验成功。

挂机,数据源切换到另外一个主机上;

恢复主机,数据源重新读写分离。

?

核心代码

private void ping() throws Exception{
		
		Map<Object,Object> map = new HashMap<Object,Object>();
		
		boolean b1 = ping(masterConnection,"master");
		boolean b2 = ping(slaveConnection,"slave");
		//same with last time return ;
		if ( ((b1 && lastStatus1)||(!b1 && !lastStatus1)) && ((b2 && lastStatus2)||(!b2 && !lastStatus2))){
			return ;
		}
		
		if ((b1 && b2)||(!b1&&!b2)) {
			map.put("master", SpringContextUtil.getBean("masterdataSource"));
			map.put("slave", SpringContextUtil.getBean("slavedataSource"));
			dynamicDataSource.setTargetDataSources(map);
			dynamicDataSource.setDefaultTargetDataSource(SpringContextUtil.getBean("masterdataSource"));
			dynamicDataSource.afterPropertiesSet();
		}else if (!b1 && b2){
			map.put("master", SpringContextUtil.getBean("slavedataSource"));
			map.put("slave", SpringContextUtil.getBean("slavedataSource"));
			dynamicDataSource.setTargetDataSources(map);
			dynamicDataSource.setDefaultTargetDataSource(SpringContextUtil.getBean("slavedataSource"));
			dynamicDataSource.afterPropertiesSet();
		}else if (b1 && !b2){
			map.put("master", SpringContextUtil.getBean("masterdataSource"));
			map.put("slave", SpringContextUtil.getBean("masterdataSource"));
			dynamicDataSource.setTargetDataSources(map);
			dynamicDataSource.setDefaultTargetDataSource(SpringContextUtil.getBean("masterdataSource"));
			dynamicDataSource.afterPropertiesSet();
		}
		
		if (!b1 && masterConnection != null && !masterConnection.isClosed()){
			try {
				DataSourceUtils.doReleaseConnection(masterConnection, (javax.sql.DataSource)SpringContextUtil.getBean("masterdataSource"));
				masterConnection = null;
			} catch (BeansException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (!b2 && slaveConnection != null && !slaveConnection.isClosed()){
			try {
				DataSourceUtils.doReleaseConnection(slaveConnection, (javax.sql.DataSource)SpringContextUtil.getBean("slavedataSource"));
				slaveConnection = null;
			} catch (BeansException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		lastStatus1 = b1;
		lastStatus2 = b2;
	}

?

后记

起一个线程定期连接数据库,如果数据库变化就进行数据源重新设置。?

两台主数据库基本满足一般使用,灾难自动切换数据源。当然还可以再一拖N个从,那是后话。两台主同时挂了,那就悲催了。

?

参考:http://blog.csdn.net/huoyunshen88/article/details/36674861

spring下高可用数据库架构(读写分离+主主复制)

原文:http://rain010101.iteye.com/blog/2191154

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!