我希望使用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
答案 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)
然后使用该组创建/设置引导程序。