ServiceStack.Redis对多线程的支持


原文地址: http://blog.csdn.net/zhang98722/article/details/8279548

  上周四上线了一个东西

要在多线程的情况下访问Redis

以前也用过ServiceStack.Redis去访问Redis

加上这玩意在Redis官方网站推荐指数排第一

果断就选择用它了


考虑到我是在多线程的环境下使用的

所以特意还去关注了它对多线程的支持

看着他们api图上大大的一排鸟语:ThreadSafe Access

我笑了


结果今天早上一到公司

一看数据

所有的东西全挂

回顾了一下上周上线的内容

一下就确定是ServiceStack.Redis在作怪

立马停掉

然后拿下日志分析

发现报了很多很诡异的异常...

例如:

[csharp]  view plain copy
  1. System.Runtime.Serialization.SerializationException: Type definitions should start with a '{', expecting serialized type 'SubscriptionModel', got string starting with: 1  

[csharp]  view plain copy
  1. ServiceStack.Redis.RedisResponseException: Unknown reply on integer response: 43OK, sPort: 8223, LastCommand:   

[csharp]  view plain copy
  1. ServiceStack.Redis.RedisResponseException: Unexpected reply: +OK, sPort: 8223, LastCommand:  

然后东西就不明不白的假死了

看了下我的代码

所有可能的异常都处理了啊

这些小小的异常根本不可能搞死我的程序啊

于是猜想难道是ServiceStack.Redis内部的机制导致内存溢出了?

找运维查了下日志

一切正常

一点风吹草动都没有

于是拿着代码在本地各种疯跑各种乱七八糟调试

基本上出现的异常都被还原了

但是我的代码还是没死啊...

心里面一万头草泥马在奔腾啊...

然后再去运维那要了更详细的日志

回过头来看测试环境的程序

竟然完美的还原了线上的场景

跟进去一看

所有的线程都卡在Redis的Get方法里

这是什么情况?!

确定了下Redis没有挂

那就只能把问题锁定在ServiceStack.Redis里咯

不由怀疑

这玩意到底支持多线程不哦...

然后详细看了下ServiceStack.Redis的文档

然后发现一个惊天的秘密:

这坑爹的ServiceStack.Redis不支持我们传统认为的线程安全啊


ServiceStack.Redis对多线程采用的是连接池

也就是说:

每一个线程可以从连接池里获取一个连接供本线程使用

在使用完毕过后还回给连接池

这样来保证每一个线程使用的Redis连接都是独立的而不会互相干扰

这就是ServiceStack.Redis所谓的ThreadSafe Access

ServiceStack.Redis就是这样来保证线程安全的...


坑爹呢这是...

我们传统意义的线程安全可是多个线程并发访问一个对象啊

而不是多个线程访问不同的对象啊...

都怪我学艺不精啊...

竟然不知道还有这种ThreadSafe Access啊...


这个东西本身有自己的线程安全
不过它的线程安全是类似于java的ThreadLocal那种
就是每一个线程你可以自己去获取自己单独用的redis客户端
但是不能几个线程公用一个
所以基本就只有两种了:
每个线程自己去获取自己的redis客户端
如果公用一个客户端
自己手动加锁 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值