使用spring的动态路由实现数据库负载均衡
2017-09-08 15:08
981 查看
使用spring的动态路由实现数据库负载均衡
系统中存在的多台服务器是“地位相当”的,不过,同一时间他们都处于活动(Active)状态,处于负载均衡等因素考虑,数据访问请求需要在这几台数据库服务器之间进行合理分配, 这个时候,通过统一的一个DataSource来屏蔽这种请求分配的需求,从而屏蔽数据访问类与具体DataSource的耦合;
系统中存在的多台数据库服务器现在地位可能相当也可能不相当,但数据访问类在系统启动时间无法明确到底应该使用哪一个数据源进行数据访问,而必须在系统运行期间通过某种条件来判定到底应该使用哪一个数据源,这个时候,我们也得使用这种“合纵连横”的方式向数据访问类暴露一个统一的DataSource,由该DataSource来解除数据访问类与具体数据源之间的过紧耦合;
更多场景需要读者根据具体的应用来判定,不过,并非所有的应用要做这样的处理,如果能够保持简单,那尽量保持简单.要实现这种“合纵连横”的多数据源管理方式,总的指导原则就是实现一个自定义的DataSource,让该DataSource来管理系统中存在的多个与具体数据库挂钩的数据源,
数据访问类只跟这个自定义的DataSource打交道即可。在spring2.0.1发布之前,各个项目中可能存在多种针对这种情况下的多数据源管理方式, 不过,spring2.0.1发布之后,引入了AbstractRoutingDataSource,使用该类可以实现普遍意义上的多数据源管理功能。
假设我们有三台数据库用来实现负载均衡,所有的数据访问请求最终需要平均的分配到这三台数据库服务器之上,那么,我们可以通过继承AbstractRoutingDataSource来快速实现一个满足这样场景的原型(Prototype):
[java] view
plaincopy
public class PrototypeLoadBalanceDataSource extends AbstractRoutingDataSource {
private Lock lock = new ReentrantLock();
private int counter = 0;
private int dataSourceNumber = 3;
@Override
protected Object determineCurrentLookupKey() {
lock.lock();
try{
counter++;
int lookupKey = counter % getDataSourceNumber();
return new Integer(lookupKey);
}finally{
lock.unlock();
}
}
// ...
}
我们在介绍AbstractRoutingDataSource的时候说过,要继承该类,通常只需要给出determineCurrentLookupKey()方法的逻辑即可。 下面是针对PrototypeLoadBalanceDataSource的配置:
[html] view
plaincopy
<bean id="dataSourc1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="url" value=".."/>
<property name="driverClassName" value=".."/>
<property name="username" value=".."/>
<property name="password" value=".."/>
<!-- other property settings -->
</bean>
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="url" value=".."/>
<property name="driverClassName" value=".."/>
<property name="username" value=".."/>
<property name="password" value=".."/>
<!-- other property settings -->
</bean>
<bean id="dataSource3" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="url" value=".."/>
<property name="driverClassName" value=".."/>
<property name="username" value=".."/>
<property name="password" value=".."/>
<!-- other property settings -->
</bean>
<util:map id="dataSources">
<entry key="0" value-ref="dataSource1"/>
<entry key="1" value-ref="dataSource2"/>
<entry key="2" value-ref="dataSource3"/>
</util:map>
<bean id="dataSourceLookup" class="org.springframework.jdbc.datasource.lookup.MapDataSourceLookup">
<constructor-arg>
<ref bean="dataSources"/>
</constructor-arg>
</bean>
<bean id="dataSource" class="..PrototypeLoadBalanceDataSource">
<property name="defaultTargetDataSource" ref="dataSourc1"/>
<property name="targetDataSources" ref="dataSources"/>
<property name="dataSourceLookup" ref=""/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="someDao" class="...">
<property name=""jdbcTemplate"" ref=""jdbcTemplate""/>
<!-- other property settings -->
</bean>
系统中存在的多台服务器是“地位相当”的,不过,同一时间他们都处于活动(Active)状态,处于负载均衡等因素考虑,数据访问请求需要在这几台数据库服务器之间进行合理分配, 这个时候,通过统一的一个DataSource来屏蔽这种请求分配的需求,从而屏蔽数据访问类与具体DataSource的耦合;
系统中存在的多台数据库服务器现在地位可能相当也可能不相当,但数据访问类在系统启动时间无法明确到底应该使用哪一个数据源进行数据访问,而必须在系统运行期间通过某种条件来判定到底应该使用哪一个数据源,这个时候,我们也得使用这种“合纵连横”的方式向数据访问类暴露一个统一的DataSource,由该DataSource来解除数据访问类与具体数据源之间的过紧耦合;
更多场景需要读者根据具体的应用来判定,不过,并非所有的应用要做这样的处理,如果能够保持简单,那尽量保持简单.要实现这种“合纵连横”的多数据源管理方式,总的指导原则就是实现一个自定义的DataSource,让该DataSource来管理系统中存在的多个与具体数据库挂钩的数据源,
数据访问类只跟这个自定义的DataSource打交道即可。在spring2.0.1发布之前,各个项目中可能存在多种针对这种情况下的多数据源管理方式, 不过,spring2.0.1发布之后,引入了AbstractRoutingDataSource,使用该类可以实现普遍意义上的多数据源管理功能。
假设我们有三台数据库用来实现负载均衡,所有的数据访问请求最终需要平均的分配到这三台数据库服务器之上,那么,我们可以通过继承AbstractRoutingDataSource来快速实现一个满足这样场景的原型(Prototype):
[java] view
plaincopy
public class PrototypeLoadBalanceDataSource extends AbstractRoutingDataSource {
private Lock lock = new ReentrantLock();
private int counter = 0;
private int dataSourceNumber = 3;
@Override
protected Object determineCurrentLookupKey() {
lock.lock();
try{
counter++;
int lookupKey = counter % getDataSourceNumber();
return new Integer(lookupKey);
}finally{
lock.unlock();
}
}
// ...
}
我们在介绍AbstractRoutingDataSource的时候说过,要继承该类,通常只需要给出determineCurrentLookupKey()方法的逻辑即可。 下面是针对PrototypeLoadBalanceDataSource的配置:
[html] view
plaincopy
<bean id="dataSourc1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="url" value=".."/>
<property name="driverClassName" value=".."/>
<property name="username" value=".."/>
<property name="password" value=".."/>
<!-- other property settings -->
</bean>
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="url" value=".."/>
<property name="driverClassName" value=".."/>
<property name="username" value=".."/>
<property name="password" value=".."/>
<!-- other property settings -->
</bean>
<bean id="dataSource3" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="url" value=".."/>
<property name="driverClassName" value=".."/>
<property name="username" value=".."/>
<property name="password" value=".."/>
<!-- other property settings -->
</bean>
<util:map id="dataSources">
<entry key="0" value-ref="dataSource1"/>
<entry key="1" value-ref="dataSource2"/>
<entry key="2" value-ref="dataSource3"/>
</util:map>
<bean id="dataSourceLookup" class="org.springframework.jdbc.datasource.lookup.MapDataSourceLookup">
<constructor-arg>
<ref bean="dataSources"/>
</constructor-arg>
</bean>
<bean id="dataSource" class="..PrototypeLoadBalanceDataSource">
<property name="defaultTargetDataSource" ref="dataSourc1"/>
<property name="targetDataSources" ref="dataSources"/>
<property name="dataSourceLookup" ref=""/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="someDao" class="...">
<property name=""jdbcTemplate"" ref=""jdbcTemplate""/>
<!-- other property settings -->
</bean>
相关文章推荐
- 【转】使用spring的动态路由实现数据库负载均衡
- 使用spring的动态路由实现数据库负载均衡
- 使用spring的动态路由实现数据库负载均衡
- 使用spring的动态路由实现数据库负载均衡
- 使用spring的动态路由实现数据库读写分离【数据库读写分离(二) 】
- 使用spring的动态路由实现数据库读写分离【数据库读写分离(二) 】 .
- 使用spring的动态路由实现数据库负载均衡
- 路由应用-使用路由实现负载流量均衡
- 负载均衡时使用Spring Session和SpringData来实现多台tomcat服务器的session同步
- 本文主要介绍使用SpringBoot与shiro实现基于数据库的细粒度动态权限管理系统实例。
- 客户端实现负载均衡:springCloud Ribbon的使用
- 详解spring cloud中使用Ribbon实现客户端的软负载均衡
- 路由应用-使用路由实现负载流量均衡
- 使用Spring Cloud Zuul实现动态路由
- SpringCloud 微服务简介及搭建(本文使用Spring封装后的API,实现负载均衡的功能)
- RouterOS实现负载均衡和策略路由的方法
- 路由交换笔记(十七)---EIGRP等价负载均衡的实现方法
- [转]使用DNS服务器实现负载均衡
- 多台主机使用DNS服务器实现网络负载均衡详细教程
- 全面介绍网站性能优化之数据库及服务器架构实现负载均衡等实用知识