多线程操作spring多例使用redis报错

小牛毛 2017-08-24 03:42:36
最近有个很奇怪的问
1.使用流程:.多个线程(4个线程)操作一个spring 多例类A,A中有个方法function a(),方法里面有获取jedis,存取等操作,最后也有释放(finnally);

2问题描述:我们部署了很多服务器,都能正常使用,但是.....最近去一个地方部署的时候,居然报错了!!!
错误信息:[ERROR] 2017-08-18 19:14:01,257 - pool-3-thread-3 com.lachesis.flyover.service.impl.InfusionMultiThreadAnalysesServiceImpl.analyseInfusionData(InfusionMultiThreadAnalysesServiceImpl.java:557)
错误信息:redis.clients.jedis.exceptions.JedisConnectionException: Unknown reply: n
[ERROR] 2017-08-18 19:14:01,257 - pool-3-thread-3 com.lachesis.flyover.service.impl.InfusionMultiThreadAnalysesServiceImpl.analyseInfusionData(InfusionMultiThreadAnalysesServiceImpl.java:558)
错误信息:Unknown reply: n
[INFO] 2017-08-18 19:14:01,259 -
[ERROR] 2017-08-18 19:14:58,024 - pool-3-thread-4 com.lachesis.flyover.service.impl.InfusionMultiThreadAnalysesServiceImpl.analyseInfusionData(InfusionMultiThreadAnalysesServiceImpl.java:557)
错误信息:java.lang.ClassCastException: [B cannot be cast to java.lang.Long
[ERROR] 2017-08-18 19:14:58,024 - pool-3-thread-4 com.lachesis.flyover.service.impl.InfusionMultiThreadAnalysesServiceImpl.analyseInfusionData(InfusionMultiThreadAnalysesServiceImpl.java:558)
错误信息:[B cannot be cast to java.lang.Long


症结:网上查询各种资料,说是多线程使用了同一个jedis出的问题,但是关键是我使用的是多例呀!每个线程都有自己的一个类A,jedis也是每次都是在function a()中重新获取的呀(用的redispool)!
我就想不通了为什么还会出现线程使用jedis混乱的现象。。。。。

就相当于每个人都有自己的一个老婆,怎么用着用着还会用到别人的老婆!这也是奇怪了!!!
...全文
1044 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
小牛毛 2018-01-12
  • 打赏
  • 举报
回复
问题找到了,原因是有些已经失效或者损坏的连接被释放到连接池了!
ArcherCoder 2017-08-30
  • 打赏
  • 举报
回复
redis是单线程的吧 为啥非得搞多线程访问redis
小牛毛 2017-08-24
  • 打赏
  • 举报
回复
引用 10 楼 apoqi 的回复:
这个问题主要是由于生产环境的差异性引起的,可以排查下
李总来了啊!
小牛毛 2017-08-24
  • 打赏
  • 举报
回复
引用 8 楼 dsaddss 的回复:
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
感谢周董顶贴!
apoqi 2017-08-24
  • 打赏
  • 举报
回复
这个问题主要是由于生产环境的差异性引起的,可以排查下
小牛毛 2017-08-24
  • 打赏
  • 举报
回复
还有一点忘了说了,我把redis放到另外一台winserver服务器,然后再连接启动,没任何毛病。。。。。 现在就是搞不清问题出在哪了,redis之前也是用的好好的!
dsaddss 2017-08-24
  • 打赏
  • 举报
回复
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
小牛毛 2017-08-24
  • 打赏
  • 举报
回复
刚写了个测试类:
package com.test.jedis;

import redis.clients.jedis.Jedis;

/**
 * @Author: yinqianhui
 * @Date Created by ThinkPad on 2017/8/24.
 */
public class MutiTest implements Runnable {

    Jedis jedis;

    public MutiTest(Jedis jedis) {
        this.jedis = jedis;
    }

    public void run() {
        try {
            System.out.println(jedis);
            jedis.set("name", "123");
            Thread.sleep(3000);
            System.out.println(Thread.currentThread().getName() + " name======" + jedis.get("name"));
        } catch (Exception e) {
            System.out.println("错误:" + e);
        } finally {
            RedisUtil.returnResource(jedis);
        }
    }

    public static void main(String[] args) {
        //为每隔线程获取一个jedis,这是没问题的
   /*     for(int i=0;i<10;i++) {
            Jedis jedis1 = RedisUtil.getJedis();
            MutiTest mutiTest1 = new MutiTest(jedis1);
            Thread t1 = new Thread(mutiTest1);
            t1.start();
            Jedis jedis2 = RedisUtil.getJedis();
            MutiTest mutiTest2 = new MutiTest(jedis2);
            Thread t2 = new Thread(mutiTest2);
            t2.start();
        }*/
        System.out.println("----------------猥琐的分割线--------------------");
        //所有线程共用一个jedis,会出现错误
        Jedis jedis1 = RedisUtil.getJedis();
        for (int i = 0; i < 10; i++) {
            MutiTest mutiTest1 = new MutiTest(jedis1);
            Thread t1 = new Thread(mutiTest1);
            t1.start();
            MutiTest mutiTest2 = new MutiTest(jedis1);
            Thread t2 = new Thread(mutiTest2);
            t2.start();
            MutiTest mutiTest3 = new MutiTest(jedis1);
            Thread t3 = new Thread(mutiTest3);
            t3.start();
        }
    }
}
当所线程共用一个jedis时会报: 错误:redis.clients.jedis.exceptions.JedisConnectionException: Unknown reply: O 错误:redis.clients.jedis.exceptions.JedisConnectionException: Unknown reply: K 错误:redis.clients.jedis.exceptions.JedisConnectionException: It seems like server has closed the connection. 错误:redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Software caused connection abort: socket write error
引用 2 楼 yinqianhui1990 的回复:
这个是获取jedis

public synchronized static Jedis getJedis() {
		try {
			if (jedisPool != null) {
			} else {
				initJedisPool();
			}
			return jedisPool.getResource();
		} catch (Exception e) {
			LOGGER.error("获取jedis异常:"+e.getMessage());
			e.printStackTrace();
			return null;
		}
	}
//这个是我释放redis的代码

public synchronized static void returnResource(final Jedis jedis) {
		if (jedis != null) {
			jedisPool.returnResource(jedis);
		}
	}
有没有可能把那些损坏的jedis还回去了。。。。。但是这种说不过去!要是有问题应该所有的服务器都会出问题才对...
synchronized 这个东西是可以去掉的,因为jedis源码内部已经加了
小牛毛 2017-08-24
  • 打赏
  • 举报
回复
刚写了个测试类:
package com.test.jedis;

import redis.clients.jedis.Jedis;

/**
 * @Author: yinqianhui
 * @Date Created by ThinkPad on 2017/8/24.
 */
public class MutiTest implements Runnable {

    Jedis jedis;

    public MutiTest(Jedis jedis) {
        this.jedis = jedis;
    }

    public void run() {
        try {
            System.out.println(jedis);
            jedis.set("name", "123");
            Thread.sleep(3000);
            System.out.println(Thread.currentThread().getName() + " name======" + jedis.get("name"));
        } catch (Exception e) {
            System.out.println("错误:" + e);
        } finally {
            RedisUtil.returnResource(jedis);
        }
    }

    public static void main(String[] args) {
        //为每隔线程获取一个jedis,这是没问题的
   /*     for(int i=0;i<10;i++) {
            Jedis jedis1 = RedisUtil.getJedis();
            MutiTest mutiTest1 = new MutiTest(jedis1);
            Thread t1 = new Thread(mutiTest1);
            t1.start();
            Jedis jedis2 = RedisUtil.getJedis();
            MutiTest mutiTest2 = new MutiTest(jedis2);
            Thread t2 = new Thread(mutiTest2);
            t2.start();
        }*/
        System.out.println("----------------猥琐的分割线--------------------");
        //所有线程共用一个jedis,会出现错误
        Jedis jedis1 = RedisUtil.getJedis();
        for (int i = 0; i < 10; i++) {
            MutiTest mutiTest1 = new MutiTest(jedis1);
            Thread t1 = new Thread(mutiTest1);
            t1.start();
            MutiTest mutiTest2 = new MutiTest(jedis1);
            Thread t2 = new Thread(mutiTest2);
            t2.start();
            MutiTest mutiTest3 = new MutiTest(jedis1);
            Thread t3 = new Thread(mutiTest3);
            t3.start();
        }
    }
}
当所线程共用一个jedis时会报: 错误:redis.clients.jedis.exceptions.JedisConnectionException: Unknown reply: O 错误:redis.clients.jedis.exceptions.JedisConnectionException: Unknown reply: K 错误:redis.clients.jedis.exceptions.JedisConnectionException: It seems like server has closed the connection. 错误:redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Software caused connection abort: socket write error
小牛毛 2017-08-24
  • 打赏
  • 举报
回复
引用 4 楼 pany1209 的回复:
[quote=引用 3 楼 小牛毛的回复:][quote=引用 1 楼 pany1209 的回复:] 每个人都有自己的一个老婆,怎么用着用着还会用到别人的老婆!这也是奇怪了!!!。。。。。。不能换妻吗???
关键我没给他提供换妻的方法啊!!![/quote] InfusionMultiThreadAnalysesServiceImpl.java:558。。。。558行出现类转换错误???[/quote] 这个错误就是因为redis报错引起的
李德胜1995 2017-08-24
  • 打赏
  • 举报
回复
引用 3 楼 小牛毛的回复:
[quote=引用 1 楼 pany1209 的回复:] 每个人都有自己的一个老婆,怎么用着用着还会用到别人的老婆!这也是奇怪了!!!。。。。。。不能换妻吗???
关键我没给他提供换妻的方法啊!!![/quote] InfusionMultiThreadAnalysesServiceImpl.java:558。。。。558行出现类转换错误???
小牛毛 2017-08-24
  • 打赏
  • 举报
回复
引用 1 楼 pany1209 的回复:
每个人都有自己的一个老婆,怎么用着用着还会用到别人的老婆!这也是奇怪了!!!。。。。。。不能换妻吗???
关键我没给他提供换妻的方法啊!!!
小牛毛 2017-08-24
  • 打赏
  • 举报
回复
这个是获取jedis

public synchronized static Jedis getJedis() {
		try {
			if (jedisPool != null) {
			} else {
				initJedisPool();
			}
			return jedisPool.getResource();
		} catch (Exception e) {
			LOGGER.error("获取jedis异常:"+e.getMessage());
			e.printStackTrace();
			return null;
		}
	}
//这个是我释放redis的代码

public synchronized static void returnResource(final Jedis jedis) {
		if (jedis != null) {
			jedisPool.returnResource(jedis);
		}
	}
有没有可能把那些损坏的jedis还回去了。。。。。但是这种说不过去!要是有问题应该所有的服务器都会出问题才对...
李德胜1995 2017-08-24
  • 打赏
  • 举报
回复
每个人都有自己的一个老婆,怎么用着用着还会用到别人的老婆!这也是奇怪了!!!。。。。。。不能换妻吗???

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧