jedis read time out问题

jedis read time out问题

空城仅有旧梦在 发布于 2021-11-25 字数 2859 浏览 509 回复 3

windows版本2.6.12.1的jedis,一般一天会有一两次read time out的异常,感觉不是特别稳定。有没有人遇到过类似的情况。异常截图如下:

jedis的类文件:

package com.klgz.ms.util;

import java.util.Random;

import org.apache.log4j.Logger;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class RedisLock {
    ///protected final Log logger = LogFactory.getLog(getClass());
    protected final Logger logger = Logger.getLogger(getClass());//"debug"

	// 加锁标志
	public static final String LOCKED = "TRUE";
	public static final long ONE_MILLI_NANOS = 1000000L;
	// 默认超时时间(毫秒)
	public static final long DEFAULT_TIME_OUT = 10;
	//public static final long DEFAULT_TIME_OUT = 300;
	//public static final long DEFAULT_TIME_OUT = 5000;
	public static JedisPool pool;
	public static final Random r = new Random();
	// 锁的超时时间(秒),过期删除
//	public static final int EXPIRE = 5 * 60;
	//设置过期时间为15秒
	public static final int EXPIRE = 250 * 60;
	static {
		pool = new JedisPool("localhost", 6379);
	}
	private Jedis jedis;
	private String key;
	// 锁状态标志
	private boolean locked = false;

	public RedisLock(String key) {
		this.key = key;
		this.jedis = pool.getResource();
	}

	public boolean lock(long timeout) {
		long nano = System.nanoTime();
		timeout *= ONE_MILLI_NANOS;
		try {
			while ((System.nanoTime() - nano) < timeout) {
				if (jedis.setnx(key, LOCKED) == 1) {
					jedis.expire(key, EXPIRE);
					locked = true;
					logger.info(">>>locked="+key+ Thread.currentThread().getName());
					return locked;
				}
				// 短暂休眠,nano避免出现活锁
				Thread.sleep(3, r.nextInt(500));
			}
		} catch (Exception e) {
			logger.error("===exception"+key+e.getMessage() +e.getLocalizedMessage() + Thread.currentThread().getName());
			e.printStackTrace();
		}
		return false;
	}

	public boolean lock() {
		return lock(DEFAULT_TIME_OUT);
	}

	// 无论是否加锁成功,必须调用
	public void unlock() {
		try {
			if (locked){
				jedis.del(key);
				
				logger.info("<<<unlocked="+key+ Thread.currentThread().getName());
			}
		} finally {
			pool.returnResource(jedis);
		}
	}

	public static void test() throws InterruptedException {
		String key = "key123";
		RedisLock redisLock = new RedisLock(key);
		try {
			if (redisLock.lock(30000)) {
				for(int i=0;i<100;i++){
					System.out.println(i);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			redisLock.unlock();
		}
	}

	public static void main(String[] args) throws InterruptedException {
//		RedisLock lock = new RedisLock(null);
		test();

	}

}

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

无人问我粥可暖 2021-12-01 3 楼

你直接把源码导入到项目中了?timeout是哪个类啊?

梅窗月明清似水 2021-12-01 2 楼

我也测试出过这个 问题 ,是用的redisclient图形界面。 后来把源码中timeout加长了,就Ok了。 你可以参考一下redisclient客户端的源代码。 https://github.com/caoxinyu/RedisClient.git 。 可以用源码起来的

柠檬 2021-11-30 1 楼

有遇到过,连本机的 redis 都会出现 time out不过我遇到的好像是因为代码的原因,后来解决了,具体的忘了,楼主再 check 一下吧.....或者换一个解决方案....