问题
In the versions of Netty prior to 4 (3.x), there was a way to make channel handling through an executor memory-aware and ordered using the OrderedMemoryAwareThreadPoolExecutor
executor to execute the actions for a given Channel
. This OrderedMemoryAwareThreadPoolExecutor
in 3.x would take care of ordering the event-handling for a channel even though they could be executed by different threads, as well as provide for restricting the total memory used by the Channel
. If the channel memory (due to the queued events) is over a certain threshold, the execution of events is blocked until memory is freed up.
In 4.x, however, there is no such mechanism. The new thread model does provide for ordering of the executed events (as events for a particular channel are executed by a single thread), but there seems to be no way to restrict the memory consumed by a single Channel
in any of the EventExecutorGroup
s. What this means is that, if this is not possible, a lot of events sent to one particular Channel
could exhaust the memory on the server. While I have not yet tested this for a fact, I thought it might be worthwhile to ask here if that's the case with Netty 4.x indeed.
So my question essentially is:
Is there a way to restrict the memory consumed by a single Channel
when using an EventExecutorGroup
with a ChannelHandler
in Netty 4.x?
回答1:
You are right. This kind of the situation is possible.
However, Netty has ChannelOption.WRITE_BUFFER_WATER_MARK
option for your channel. So when you writing too fast into some channel and queue of pending messages exceeds ChannelOption.WRITE_BUFFER_WATER_MARK
limit the channel you are writing to will become not writable. So you can guard your code with:
if (channel.isWritable()) {
}
or
if (ctx.channel().isWritable()) {
}
And thus prevent exhausting of memory when the channel is busy or consumes events slowly.
You also can change ChannelOption.AUTO_READ
for channel that generates events and handles this manually with:
ctx.channel().config().setAutoRead(false);
So your server will stop read events from the channel that generates them too much. Here is pull request that demonstrates this way.
来源:https://stackoverflow.com/questions/44562265/memory-aware-channel-handling-with-netty-4-1