zoukankan      html  css  js  c++  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;
    }
  • 相关阅读:
    公司财务(书籍学习过程总结)
    职场心理学-心理学第一天(非原创)
    (原创干货)自身管理-日常思考实战框架学习第八天
    (原创干货)融资、路演-日常思考实战框架学习第七天
    (原创干货)理财、投资-日常思考实战框架学习第七天
    (原创干货)理财、投资-日常思考实战框架学习第六天
    (原创干货)公司金融-日常思考实战框架学习第五天
    (原创干货)沟通、演讲-日常思考实战框架学习第四天
    虚拟机中给linux 系统添加硬盘以后,进行分区挂载
    基于Xshell使用密钥方式连接远程主机
  • 原文地址:https://www.cnblogs.com/6970-9192/p/11383312.html
Copyright © 2011-2022 走看看