Below you will find pages that utilize the taxonomy term “开源 Xmemcached Java”
Posts
Xmemcached 死锁分析和 Aviator 可变参数方法实现
首先是 xmemcached 发了 2.2.0 版本,最重要解决的问题就是请求超时。详细的情况可以参考这个 issue 。推荐所有还在用 xmc 的朋友升级到这个版本,性能和稳定性都有所改进。
这个 bug 的原因可能更值得说道说道。
xmemcached 本身会对发出去的请求维护一个队列,在 onMessageSent 也就是消息写到 socket 后将请求放入队列,然后在收到 memcached 返回应答的时候,找出当前的请求来 decode 应答内容。伪代码是这样:
//Handler 里加入队列。 public void onMessageSent(Command msg, Session session){ session.getQueue().offer(msg); } //Decoder 里做解码 public Command decode(ByteBuffer buf, Session session){ Command cmd = session.getQueue().take().decode(buf); if(cmd!=null) return cmd; else return null; } 这个 Bug 的关键就在于加入队列的时候和 take 的使用。 take 会阻塞当前操作,直到队列中有可用的元素或者被中断。而我们放入队列的时候是在命令被完全写入 socket 之后(有没有发出去,你无法确认的,因为有 socket 缓冲区、网卡缓冲区的存在)。其次是这两段逻辑是发生在同一个处理线程上。
那么当用户写入一个超过 1M 的数据的时候,假设是 2M。因为 memcached 最多只允许保存 1M 大小的数据,当 xmemcached 将超过 1M 但是还没有达到 2M 的数据发送到 memcached 后, memcached 立即应答返回错误。但是此时,数据还没有完全写出去,导致命令没有被加入队列,同时 take 也取不到数据,我们遇到了死锁: take 在等待命令加入,而写入命令数据的线程被 take 阻塞了没有机会继续写。