netty做Pipe一端快一端慢时防止内存溢出进行的操作

前段时间用netty3.x做了一个pipe的功能,读的速度很快,写的速度很慢,结果读总是把内存耗光(来不及写写到pipe的另一端),后面解决了这个问题。

原来的pipe的代码:

	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {
		inboundChannel.write(e.getMessage());
	}

 inboundChannel是一个很慢的连接,而当前连接很快(messageReceived调用很频繁),inboundChannel的写缓冲区很快满了(inboundChannel.isWritable() =false),继续写很容易就OOM了,

 

修改后的代码是:

 

private Object trafficLock = new Object();
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {
		synchronized (trafficLock) {
            inboundChannel.write(e.getMessage());
            if (!inboundChannel.isWritable()) {
                e.getChannel().setReadable(false);
            }
        }
	}

	@Override
	public void channelInterestChanged(ChannelHandlerContext ctx,
			ChannelStateEvent e) throws Exception {
		synchronized (trafficLock) {
			if (e.getChannel().isWritable()) {
				inboundChannel.setReadable(true);
			}
		}
	}

 

 必须给双方的channel都添加包含上述代码的handler,才能生效;

上面的代码可以理解成:

1,如果对方channel不可写时,把当前channel的读操作禁用;

2,如果当前的channel可写了,把对方channel的读操作启用;

 

两个handler是对等的,恰好可以解决这个问题。

 

注意:两个handler必须共享锁trafficLock,具体原因,参见讨论:

http://markmail.org/message/x7jc6mqx6ripynqf

以及另外一个实例:

http://searchco.de/codesearch/view/16958454

 

posted on 2013-05-23 17:12  子非鱼焉  阅读(305)  评论(0编辑  收藏  举报

导航