渠道池中的Netty负载均衡器

时间:2013-06-26 10:16:28

标签: netty

我正在为我的应用程序使用protobuf-rpc-pro(两个系统集成)。 protobuf-rpc-pro基于Netty并使用Netty的这种依赖性:
<依赖性>
<&的groupId GT; io.netty< /&的groupId GT;
< artifactId的>网状-所有< / artifactId的>
<版本> 4.0.0.CR1< /版本>
< /依赖性>

我需要为两个系统之间的通信实现通道池以获得高性能。即在我的实现中,我希望获得多个并行发送消息的连接(非阻塞通信)。这里的问题是如何检查发送缓冲区是否已满并切换到另一个连接(如负载平衡)。在Netty或某些外部实现中是否有任何机制? 网上没有找到任何东西......

1 个答案:

答案 0 :(得分:2)

您是否看过Channel#isWritable()方法?据我所知,如果写缓冲区太满,那将返回false。

编辑:添加了一个使用Channel#isWritebale()和highWaterMark / lowWaterMark的简单演示。

static InetSocketAddress ADDRESS = new InetSocketAddress("localhost", 4711);

static ChannelPipeline createPipeline() {

    ChannelPipeline pipeline = Channels.pipeline();
    pipeline.addLast("frameDecoder", new DelimiterBasedFrameDecoder(100,
            Delimiters.lineDelimiter()));
    pipeline.addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8));

    pipeline.addLast("stringEncoder", new StringEncoder(CharsetUtil.UTF_8));
    return pipeline;

}

public static void main(String[] args) throws Throwable {
    int suspendedWrites = 0;
    int N = 1000;
    final CountDownLatch ready = new CountDownLatch(N);

    ConnectionlessBootstrap server = new ConnectionlessBootstrap(
            new NioDatagramChannelFactory());
    server.setPipeline(createPipeline());
    server.getPipeline().addLast("printer",
            new SimpleChannelUpstreamHandler() {
                @Override
                public void messageReceived(ChannelHandlerContext ctx,
                        MessageEvent e) throws Exception {
                    System.out.println((String) e.getMessage());
                    ready.countDown();
                }
            });
    server.bind(ADDRESS);

    ClientBootstrap client = new ClientBootstrap(
            new NioDatagramChannelFactory());
    client.setPipeline(createPipeline());
    Channel clientChannel = client.connect(ADDRESS).sync().getChannel();

    NioDatagramChannelConfig config = (NioDatagramChannelConfig) clientChannel
            .getConfig();

    config.setWriteBufferLowWaterMark(500);
    config.setWriteBufferHighWaterMark(1000);

    for (int i = 0; i < N; ++i) {
        String message = "Hello number " + (i + 1) + " from client\n";
        if (clientChannel.isWritable())
            clientChannel.write(message);
        else {
            clientChannel.write(message).await();
            ++suspendedWrites;
        }
    }

    ready.await(1, TimeUnit.SECONDS);
    client.releaseExternalResources();
    client.shutdown();
    server.releaseExternalResources();
    server.shutdown();
    System.out.println("Suspended writes: " + suspendedWrites);
    System.out.println("Missed reads: " + ready.getCount());
}

运行此操作将显示Channel#isWriteable()取决于当前写入缓冲区大小以及高水位线和低水位线的值。

更详细的实施可以监控利益操作的变化,并在此基础上提供可写信道。