针对Java基于JNDI 实现读写分离,我可以为您提供以下攻略。
什么是JNDI?
JNDI(Java Naming and Directory Interface) 是一套用来访问各种命名和目录服务的API,来实现在Java平台上的“访问命名和目录服务”功能。
JNDI的读写分离
JNDI 可以通过配置多个数据源,实现读写分离的场景。对于读请求使用到的数据源进行负载均衡的操作,达到读写分离的效果。
JNDI读写分离的实现步骤
步骤一:配置数据源
<Resource name="jdbc/master" auth="Container"
type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/db_master"
username="root" password="root" maxActive="20" maxIdle="10"
maxWait="-1"/>
<!-- 从库1 -->
<Resource name="jdbc/slave1" auth="Container"
type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/db_slave1"
username="root" password="root" maxActive="20" maxIdle="10"
maxWait="-1"/>
<!-- 从库2 -->
<Resource name="jdbc/slave2" auth="Container"
type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/db_slave2"
username="root" password="root" maxActive="20" maxIdle="10"
maxWait="-1"/>
在上述配置文件中,我们初始化了3个数据源,其中第一个是主库数据源,后面两个是从库数据源。
步骤二:使用JNDI技术,查找并使用数据源
通过JNDI查找数据源,可以使用如下代码:
InitialContext context=new InitialContext();
DataSource dataSource= (DataSource) context.lookup("java:comp/env/jdbc/master");
其中,context.lookup
查找数据源,"java:comp/env/"
是固定写法。
步骤三:在连接处做读写分离操作
在连接数据库的时候,我们可以通过判断当前执行的语句类型,进行负载均衡的操作,例子如下:
/**
* 负载均衡写/读库:INSERT、UPDATE、DELETE都写入master库,SELECT从slave1和slave2均衡获取
*
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
Connection conn = null;
try {
if (null == context) {
context = new InitialContext();
}
DataSource dataSource;
// 根据具体情况做读写分离的实现
String sql = SQLThreadLocal.get();
if (StringUtils.containsIgnoreCase(sql, "select")) {
int index = RandomUtils.nextInt() % 2;
dataSource = (DataSource) context.lookup(String.format("java:comp/env/jdbc/slave%d", index + 1));
} else {
dataSource = (DataSource) context.lookup("java:comp/env/jdbc/master");
}
conn = dataSource.getConnection();
} catch (NamingException e) {
e.printStackTrace();
}
return conn;
}
这里,我们通过 SQLThreadLocal.get()
获取当前执行的SQL语句,如果是SELECT语句,则随机选取最终的数据源;否则使用主库。
注意,JNDI在使用上述方法时,需要保证在 Servlet 容器上下文中才会起作用。如果是普通JAR 包,是没有办法使用JNDI实现读写分离的。
示例代码
你可以在这里看到使用JNDI实现读写分离的 示例代码。
此代码包含两个样例,分别是根据不同情况切换数据源和使用AOP动态数据源。你可以自己下载并使用。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java基于JNDI 实现读写分离的示例代码 - Python技术站