jedis连接redis3.2.9集群密码问题[通俗易懂]

jedis连接redis3.2.9集群密码问题[通俗易懂]转载来自:https://www.cnblogs.com/snowstar123/p/5696052.html主要想说的是,源码中对于jedis连接redisclsuter没有设置密码,所以会一直报错说NOAUTH认证需要。后来,在改篇文章的评论中有如下:#1楼 2016-12-2814:21 破壁人  您好按照您的方式进行了修改,但是问题依然出现报错,NOAUTHAuthenticatio…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

转载来自:https://www.cnblogs.com/snowstar123/p/5696052.html

主要想说的是,源码中对于jedis连接redis clsuter没有设置密码,所以会一直报错说NOAUTH认证需要

jedis连接redis3.2.9集群密码问题[通俗易懂]

后来,在改篇文章的评论中有如下:

#1楼
 
2016-12-28 14:21 
破壁人 
 
您好按照您的方式进行了修改,但是问题依然出现报错,NOAUTH Authentication required.,但是如果将密码故意输入错误会报出密码有误的提示,不知大神是否遇到过这种情况。

  

#2楼
[
楼主
2017-01-05 18:06 
星空雪苑 
 

@ 破壁人

现在已经不需要使用这种方式啦 jedis2.9.0的版本已经发布啦 该版本已经实现了redis cluster集群的密码功能

所以进行了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集群涉及到的主要的类

jedis连接redis3.2.9集群密码问题[通俗易懂]

这里我们会发现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账号...

(0)


相关推荐

  • 在html中加下划线

    在html中加下划线方法一:用&lt;u&gt;&lt;/u&gt;标签方法二:用text-decoration:underline;方法三:用border:1pxsolid;     padding:5px;如下范例:范例对应的结果:

  • 568A线序是什么_水晶头a类线序

    568A线序是什么_水晶头a类线序什么情况下会用上568A线序1985年初,计算机工业协会(CCIA)提出对大楼布线系统标准化的倡仪,美国电子工业协会(EIA)和美国电信工业协会(TIA)开始标准化制定工作。1991年7月,ANSI/EIA/TIA568即《商业大楼电信布线标准》问世。1995年底,EIA/TIA568标准正式更新为EIA/TIA/568AEIA/TIA的布线标准中规定了两种双绞线的线序568A与568B。标准568A:绿白-1,绿-2,橙白-3,蓝-4,蓝白-5,橙-6,褐白-7

    2022年10月30日
  • centos7开机界面出现多个选项

    centos7开机界面出现多个选项

  • linuxiostat命令详解_ifstat命令

    linuxiostat命令详解_ifstat命令Linuxiostat命令详解iostat主要用于监控系统设备的IO负载情况,根据这个可以看出当前系统的写入量和读取量,CPU负载和磁盘负载。1.命令格式:iostat参数时间次数2.命令参数:-C显示CPU使用情况-d显示磁盘使用情况-k以KB为单位显示-m以M为单位显示-N显示磁盘阵列(LVM)信息-n显示NFS使用情况-p[磁盘]显示磁盘和分区的情况-t显示终端和CPU的信息-x显示详细信息-V显示版本信息3.常用

  • 虚拟局域网vlan的最大个数_虚拟局域网的标准是

    虚拟局域网vlan的最大个数_虚拟局域网的标准是VLAN实例1.VLAN划分实例[Huawei]interfaceEthernet0/0/1[Huawei-Ethernet0/0/1]portlink-typeaccess[Huawei-Ethernet0/0/1]portdefaultvlan10[Huawei]interfaceEthernet0/0/2[Huawei-Ethernet0/0/2]portlink-typeaccess[Huawei-Ethernet0/0/2]portdefau

  • 十进制小数转换为二进制小数采用方法为乘2取整法?_小数点二进制转10进制

    十进制小数转换为二进制小数采用方法为乘2取整法?_小数点二进制转10进制十进制小数转换成二进制小数采用"乘2取整,顺序排列"法。具体做法是:用2乘十进制小数,可以得到积,将积的整数部分取出,再用2乘余下的小数部分,又得到一个积,再将积的整数部分取出,如此进行,直到积中的整数部分为零,或者整数部分为1,此时0或1为二进制的最后一位。或者达到所要求的精度为止。  然后把取出的整数部分按顺序排列起来,先取的整数作为二进制小数的高位有效位,后取的整数作为低位有…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号