大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
转载来自:https://www.cnblogs.com/snowstar123/p/5696052.html
主要想说的是,源码中对于jedis连接redis clsuter没有设置密码,所以会一直报错说NOAUTH认证需要。
后来,在改篇文章的评论中有如下:
所以进行了jedis2.9.0的版本尝试:
jedis2.9jar包下载:(源码包是跟他放到一起的)
http://www.mvnjar.com/redis.clients/jedis/2.9.0/detail.html
commons-pool2下载(这个不知道具体跟jiedis的版本对应)
http://www.mvnjar.com/org.apache.commons/commons-pool2/jar.html
导入jar包后我就开始做如下操作:
jedisCluster.auth(”mima”);
直接失败,因为即使是jedis2.9,这个jedisCluster.auth()方法里面也是啥都没有,你可以重写这个方,这个方法内容如下:
/** * @deprecated No key operation doesn't make sense for Redis Cluster and Redis Cluster doesn't * support authorization scheduled to be removed on next major release */ @Deprecated @Override public String auth(String password) { throw new JedisClusterException("No way to dispatch this command to Redis Cluster."); }
因为连接的是redis集群,所有我就用eclipse看了一下JediCluster的构造方法:
找到了这个new JedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeout, int soTimeout,int maxAttempts, String password, final GenericObjectPoolConfig poolConfig);
然后我就修改代码增加上面参数配置项:
package readfile; import java.io.IOException; import java.util.HashSet; import java.util.Set; import redis.clients.jedis.HostAndPort; import redis.clients.jedis.JedisCluster; import redis.clients.jedis.JedisPoolConfig; public class GetData { public static void main(String[] args) throws IOException { int a = 0; JedisPoolConfig i2 = new JedisPoolConfig(); i2.setMaxTotal(-1); i2.setMinIdle(2); i2.setMaxIdle(-1); i2.setMaxWaitMillis(10000); i2.setTestOnBorrow(true); i2.setTestOnReturn(true); Set<HostAndPort> nodes = new HashSet<>(); nodes.add(new HostAndPort("######", 6379)); nodes.add(new HostAndPort("#####", 6379)); nodes.add(new HostAndPort("#####", 6379)); nodes.add(new HostAndPort("####", 6380)); nodes.add(new HostAndPort("##", 6380)); nodes.add(new HostAndPort("##", 6380)); JedisCluster jedis = new JedisCluster(nodes, 10000, 10000, 100, "wkz", i2); while (a < 10) { System.out.println(jedis.get("w")); a++; } jedis.close(); } }
这次顺利的出了结果,证明jedis2.9是好使的,其他验证就没做。
环境介绍:jedis:2.8.0
redis版本:3.2
首先说一下redis集群的方式,一种是cluster的 一种是sentinel的,cluster的是redis 3.0之后出来新的集群方式
本身redis3.2的cluster集群是支持密码的 ,具体怎么搭建,可以查找相关的文档,这里只介绍应用层面的操作
jedis2.8.0的版本没有实现对redis cluster集群的密码操作
在jedis中创建redis cluster的对象时,一般是采用
JedisCluster jedisCluster = new JedisCluster(clusterNodes,timeout,jedisPoolConfig);
我们在项目中直接写了一个类专门来负责操作redis的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
public class RedisClusterUtil {
private static final Logger LOGGER = Logger.getLogger(RedisClusterUtil. class );
private int timeout = 10000 ;
private JedisCluster jedisCluster;
private Set<HostAndPort> clusterNodes ;
public RedisClusterUtil(String redisUris, JedisPoolConfig jedisPoolConfig) throws Exception{
init(redisUris);
checkHostAndPost();
jedisCluster = new JedisCluster(clusterNodes,timeout,jedisPoolConfig);
}
/**
* reids 链接节点地址
*/
public void init(String redisUris) {
LOGGER.info( "redisUris:" + redisUris);
// ## 注册redis连接节点
clusterNodes = Sets.newHashSet();
if (StringUtils.isNotBlank(redisUris)){
// 以“;”分割成"ip:post"
String [] ipAndPostes = redisUris.split( ";" );
// 以“:”分割成 “ip”,“post”
if (ipAndPostes != null ){
for (String ipAndPost : ipAndPostes){
//ipAndPost 值:(ip:端口)
String [] ipAndPostArray = ipAndPost.split( ":" );
clusterNodes.add( new HostAndPort(ipAndPostArray[ 0 ], Integer.parseInt(ipAndPostArray[ 1 ])));
}
}
}
LOGGER.info( "redis链接节点个数(clusterNodes):" + clusterNodes.size());
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<? xml version="1.0" encoding="UTF-8"?>
< beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
">
< bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
< property name="maxTotal" value="${redis.maxTotal}"/>
< property name="maxIdle" value="${redis.maxIdle}"/>
< property name="minIdle" value="${redis.minIdle}"/>
< property name="maxWaitMillis" value="${redis.maxWaitMillis}"/>
< property name="testOnBorrow" value="${redis.testOnBorrow}"/>
</ bean >
< bean id="redisClusterUtil" class="*.*.utils.RedisClusterUtil">
< constructor-arg index="0" value="${redisUris}"></ constructor-arg >
< constructor-arg index="1" ref="jedisPoolConfig"></ constructor-arg >
</ bean >
</ beans >
|
我们创建好jedisCluster之后,看了一下jedisCluster里面有一个jedisCluster.auth(“密码”)方法,可惜,这个方法里面什么都没有实现,仅仅抛一个异常
@Deprecated
@Override
public String auth(String password) {
throw new JedisClusterException(“No way to dispatch this command to Redis Cluster.”);
}
所以想通过这个来设置密码是没戏啦,只能去修改jedis的源码啦,我们先直接启动一下看下报错信息,会发现整个jedis在操作cluster集群涉及到的主要的类
这里我们会发现cluster集群最终会调用redis.clients.jedis.JedisClusterConnectionHandler.initializeSlotsCache(Set<HostAndPort>, GenericObjectPoolConfig)方法,而这个方法里面的代码是
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
private void initializeSlotsCache(Set<HostAndPort> startNodes, GenericObjectPoolConfig poolConfig) {
for (HostAndPort hostAndPort : startNodes) {
Jedis jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort());
try {
cache.discoverClusterNodesAndSlots(jedis);
break ;
} catch (JedisConnectionException e) {
// try next nodes
} finally {
if (jedis != null ) {
jedis.close();
}
}
}
for (HostAndPort node : startNodes) {
cache.setNodeIfNotExist(node);
}
}
|
这里我们可以看到代码中有jedis的创建,而jedis本身是可以支持password配置的,这样我们就可以直接写一个方法去给这个类中塞一个密码进去啦
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
以下是我自己添加的一个方法,主要是添加了密码 <br> private void initializeSlotsCache(Set<HostAndPort> startNodes, GenericObjectPoolConfig poolConfig,String password) {
for (HostAndPort hostAndPort : startNodes) {
Jedis jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort());
jedis.auth(password);
try {
cache.discoverClusterNodesAndSlots(jedis);
break ;
} catch (JedisConnectionException e) {
// try next nodes
} finally {
if (jedis != null ) {
jedis.close();
}
}
}
for (HostAndPort node : startNodes) {
cache.setNodeIfNotExist(node);
}
}
|
这样我们就让JedisClusterConnectionHandler支持了密码,再根据上面的异常信息中的信息,分别去新增方法去传递password到JedisClusterConnectionHandler;这里就部再详细介绍每段代码啦,从异常信息中就知道要修改哪些方法啦
重写的jedis的代码如上(太长我省略了),重写了jedis的4个类,4个类中分别新增了一个方法,最新项目中调用时,就可以
直接
public RedisClusterUtil(String redisUris, JedisPoolConfig jedisPoolConfig) throws Exception{
init(redisUris);
checkHostAndPost();
jedisCluster = new JedisCluster(clusterNodes,timeout,jedisPoolConfig,”密码”);
}
这样就结束啦
public class RedisClusterUtil { private static final Logger LOGGER = Logger.getLogger(RedisClusterUtil.class); private int timeout = 10000; private JedisCluster jedisCluster; private Set<HostAndPort> clusterNodes ;
public RedisClusterUtil(String redisUris, JedisPoolConfig jedisPoolConfig) throws Exception{ init(redisUris); checkHostAndPost(); jedisCluster = new JedisCluster(clusterNodes,timeout,jedisPoolConfig,”!QAZ2wsx”); } /** * reids 链接节点地址 */ public void init(String redisUris) { LOGGER.info(“redisUris:” + redisUris); // ## 注册redis连接节点 clusterNodes = Sets.newHashSet(); if(StringUtils.isNotBlank(redisUris)){ // 以“;”分割成”ip:post” String [] ipAndPostes = redisUris.split(“;”); // 以“:”分割成 “ip”,“post” if(ipAndPostes != null){ for (String ipAndPost : ipAndPostes){ //ipAndPost 值:(ip:端口) String [] ipAndPostArray = ipAndPost.split(“:”); clusterNodes.add(new HostAndPort(ipAndPostArray[0], Integer.parseInt(ipAndPostArray[1]))); } } } LOGGER.info(“redis链接节点个数(clusterNodes):” + clusterNodes.size()); }
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/196978.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...