Scala Netty有任何方式可以共享ReplayingDecoder

时间:2015-11-03 16:09:26

标签: scala netty

我希望使用netty客户端引导程序打开多个连接,以便解析来自多个源的消息。消息都具有相同的格式,但是,由于需要处理的数据量,我必须在不同的线程上运行每个连接(假设netty为每个客户端通道创建一个线程,我无法找到参考 - 如果不是这样,那将如何实现?)。

这是我用来连接数据服务器的代码:

var b = new Bootstrap()
        .group(group)
        .channel(classOf[NioSocketChannel])
        .handler(RawFeedChannelInitializer)


var ch1 = b.clone().connect(host, port).sync().channel();
var ch2 = b.clone().connect(host, port).sync().channel();

初始化程序调用{​​{1}},它扩展了ReplayingDecoder,并定义为here。 打开单个连接时,代码在没有RawPacketDecoder的情况下运行良好,但出于我的应用程序的目的,我必须多次连接到同一服务器。

这导致运行时错误@Sharable指向我的@Sharable annotation is not allowed类。

我不完全确定如何解决这个问题,而不是重新实现scala一个可实例化的RawPacketDecoder类,因为我的解码器直接基于ReplayingDecoder

非常感谢任何帮助。

注意:我使用的是netty 4.0.32 Final

1 个答案:

答案 0 :(得分:1)

我在this StockExchange answer找到了解决方案。

我的问题是我使用的是基于对象的ChannelInitializer(单例),ReplayingDecoder以及ByteToMessageDecoder不可共享。

我的初始化程序是作为scala对象创建的,因此允许使用单个实例。将初始化程序更改为scala类并为每个引导程序克隆实例化解决了该问题。我修改了上面的bootstrap代码如下:

var b = new Bootstrap()
    .group(group)
    .channel(classOf[NioSocketChannel])
    //.handler(RawFeedChannelInitializer)

var ch1 = b.clone().handler(new RawFeedChannelInitializer()).connect(host, port).sync().channel();
var ch2 = b.clone().handler(new RawFeedChannelInitializer()).connect(host, port).sync().channel();

我不确定这是否可以确保所需的多线程,但它确实允许将数据访问分成多个连接到源服务器。

编辑更新:在对该主题进行额外研究后,我确定netty实际上确实为每个频道创建了一个帖子;这是通过在创建每个频道后打印到控制台来验证的:

println("No. of active threads: " + Thread.activeCount());

当创建通道并将其与各自的线程关联时,输出显示增量编号。

默认情况下,NioEventLoopGroup使用here定义的2*Num_CPU_cores个线程:

DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt(
              "io.netty.eventLoopThreads",
               Runtime.getRuntime().availableProcessors() * 2));

通过设置

,可以将此值覆盖为其他值
val group = new NioEventLoopGroup(16)

然后使用该组创建/设置引导程序。