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());    }

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196978.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • map key为null_mybatis json

    map key为null_mybatis jsonmybatis返回Map结果集value为Null的情况下丢失key的解决办法本博主之前一直是网络资源的索取者,本着开源精神愿意把自己在开发过程中遇到过的问题以及解决方案分享给大家,这是我的第一篇博客,希望以后能坚持写博客,让大家少走弯路、少踩坑。废话少说,直入主题!springcloud微服务集成mybatis动态多数据源在网上有很多文章可以搜到,这里就不重复造轮子了。如题,网上…

    2022年9月28日
    2
  • iozone使用简介

    iozone使用简介iozone 使用简介 iozone www iozone org 是一个文件系统的 benchmark 工具 可以测试不同的操作系统中文件系统的读写性能 可以测试 Read write re read re write readbackward readstrided fread fwrite randomread pread mmap aio read aio write 等等不同的模式下的硬盘的性能 命令详情 aAutomode AAuto2mode b

    2025年9月1日
    2
  • pycharm安装Translation翻译插件(中文翻译)「建议收藏」

    pycharm安装Translation翻译插件(中文翻译)「建议收藏」打开pytcharm选择文件——设置找到plugins——在输入框搜索translation进行安装即可设置翻译工具的唤醒快捷键位置:快捷键——在输入框输入名称,右击选择啊大大keyboardshortcut自定义就可以了选择翻译的工具如图所示:进入pycharm,按快捷键呼出翻译界面,输入内容,按回车按钮…

    2025年7月11日
    5
  • inputstreamreader类是用于将_readstring

    inputstreamreader类是用于将_readstring一、InputStreamReader类InputStreamReader将字节流转换为字符流。是字节流通向字符流的桥梁。如果不指定字符集编码,该解码过程将使用平台默认的字符编码,如:GBK。构造方法:InputStreamReaderisr=newInputStreamReader(InputStreamin);//构造一个默认编码集的InputStr

    2022年9月26日
    2
  • 基于pytorch卷积人脸表情识别–毕业设计「建议收藏」

    基于卷积神经网络的人脸表情识别前言毕业设计内容介绍卷积神经网络的设计卷积网络的模型卷积池化过程详细说明第一层卷积池化过程第二层卷积池化过程第三层卷积池化过程全连接层过程模型的训练过程卷积与池化原理模型如何训练模型的评估指标训练结果分析通过训练曲线分析通过混淆矩阵分析效果通过摄像头识别表情设计流程效果演示部分代码展示总结前言这篇文章记录一下我本科毕业设计的内容。我的课题是人脸表情识别,本来最开始按照历届学长的传统是采用MATLAB用传统的机器学习方法来实现分类的。但是鉴于我以前接触过一点点深度学习的内容,

    2022年4月11日
    161
  • 《JavaScript 模式》读书笔记(6)— 代码复用模式3

    我们之前聊了聊基本的继承的概念,也聊了很多在JavaScript中模拟类的方法。这篇文章,我们主要来学习一下现代继承的一些方法。九、原型继承下面我们开始讨论一种称之为原型继承(prototype

    2022年3月25日
    46

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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