【Java】对redis指定db进行操作

时间:2019-08-20
本文章向大家介绍【Java】对redis指定db进行操作,主要包括【Java】对redis指定db进行操作使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

问题

自动化测试大量报错,原因是验证码错误,从redis中查询验证码,返回结果均为null。

原因

因为在UAT环境,各项目共用1个redis,db0中的数据较多,达到了600W+,导致查询速度较慢,故验证码发送服务将验证码的存储从db0切到了db4。

导致自定义的Jmeter函数无法正常查询到验证码,因为原本该函数是默认充db0中进行查询的。

解决方案

自定义函数中是使用jedis对redis使用操作,版本为3.0.1,maven详细依赖如下:

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.0.1</version>
</dependency>

在网上查询的方法有在config中添加配置与在redis对象上使用select()两种方案,可能是因为jedis版本不同,以上2中方案均不适用。

因为JedisPoolConfig中没有方法用于设置db,并且ShardedJedis中没有select()方法,只能寻找其他技术方案进行解决。

函数中原使用以下方法创建redis分片:

public static ShardedJedis getJedis (String host, String password) {
    JedisShardInfo jedisShardInfo = new JedisShardInfo(host,6379);
    jedisShardInfo.setPassword(password);
    List<JedisShardInfo> list = new LinkedList<JedisShardInfo>();
    list.add(jedisShardInfo);
    ShardedJedisPool pool = new ShardedJedisPool(config, list);
    ShardedJedis jedis = pool.getResource();
    return jedis;
}

查看JedisShardInfo中的JedisShardInfo(String host, int port)构造方法,

public JedisShardInfo(String host, int port) {
    this(host, port, 2000);
}

继续查看调用链,

public JedisShardInfo(String host, int port, int timeout) {
    this(host, port, timeout, timeout, 1);
}
public JedisShardInfo(String host, int port, int connectionTimeout, int soTimeout, int weight) {
    super(weight);
    this.password = null;
    this.name = null;
    this.db = 0;
    this.host = host;
    this.port = port;
    this.connectionTimeout = connectionTimeout;
    this.soTimeout = soTimeout;
}

发现db默认写死为0,且没有set方法。

查询JedisShardInfo中的其他构造方法,发现JedisShardInfo(String host)方法:

public JedisShardInfo(String host) {
    super(1);
    this.password = null;
    this.name = null;
    this.db = 0;
    URI uri = URI.create(host);
    if (JedisURIHelper.isValid(uri)) {
        this.host = uri.getHost();
        this.port = uri.getPort();
        this.password = JedisURIHelper.getPassword(uri);
        this.db = JedisURIHelper.getDBIndex(uri);
        this.ssl = JedisURIHelper.isRedisSSLScheme(uri);
    } else {
        this.host = host;
        this.port = 6379;
    }
}

此处的db设置并未写死,看起来是根据url来获取设置,进入JedisURIHelper.getPassword()查看详情:

public static int getDBIndex(URI uri) {
    String[] pathSplit = uri.getPath().split("/", 2);
    if (pathSplit.length > 1) {
        String dbIndexStr = pathSplit[1];
        return dbIndexStr.isEmpty() ? 0 : Integer.parseInt(dbIndexStr);
    } else {
        return 0;
    }
}

从方法中得知,db可根据url中"/"后的值进行设置,而url是通过URI.create()方法获得,查询URI.create()方法详情:

public static URI create(String str) {
    try {
        return new URI(str);
    } catch (URISyntaxException x) {
        throw new IllegalArgumentException(x.getMessage(), x);
    }
}

查询if判断条件中的JedisURIHelper.isValid()方法:

public static boolean isValid(URI uri) {
    return !isEmpty(uri.getScheme()) && !isEmpty(uri.getHost()) && uri.getPort() != -1;

故得知,使用JedisShardInfo(String host)进行实例化时,入参为URL的形式,需要有协议头、host地址、端口号,并在host添加"/",再其后设置dbIndex,如下所示形式:

http://xxxxxxx.redis.rds.aliyuncs.com:6379/4

结论

在自定义函数中的getJedis()方法里使用JedisShardInfo(String host)对JedisShardInfo进行实例化,并以http://redisHost:port/dbIndex的形式设置redis地址,则可对redis的指定db进行操作。

修改后的getJedis()方法如下:

public static ShardedJedis getJedis (String host, String password) {
    JedisShardInfo jedisShardInfo = new JedisShardInfo(host);
    jedisShardInfo.setPassword(password);
    List<JedisShardInfo> list = new LinkedList<JedisShardInfo>();
    list.add(jedisShardInfo);
    ShardedJedisPool pool = new ShardedJedisPool(config, list);
    ShardedJedis jedis = pool.getResource();
    return jedis;
}

原文地址:https://www.cnblogs.com/6970-9192/p/11383312.html