当前位置: 首页 > 知识库问答 >
问题:

Netty 3.95通道编写和使用setTrafficClass

麹正业
2023-03-14

我有一个Netty 3.95客户端和服务器。客户端向服务器发送任务计划。可以发送的计划数量基本上没有限制,有些计划比其他计划更重要。我有三个优先级(高、中、低),我给每个任务计划分配了一个优先级(当我把数据读入客户端时的DSCP值)。)我希望这允许更重要的任务计划首先到达服务器。

我已经将路由器的出站数据速率调至最低,并向路由器发送了大约1000个计划。我可以看到任务计划到达服务器,它们到达得非常慢。这告诉我,我已经有效地锁定了路由器的出站数据速率。

在我为每个任务计划写通道之前,我得到通道的配置并设置流量等级。

private void setTrafficClass(int code) {
    comLink = connection.getChannel();
    cfg = (NioSocketChannelConfig) comLink.getConfig();
    cfg.setTrafficClass(code);
}

然后,我用一个

comLink.write();

任务计划总是按照我发送的顺序到达。DSCP代码似乎被忽略了。DSCP在路由器中启用。我使用Wireshark检查客户端和服务器之间的流量,我注意到并非所有的DSCP代码都是正确的。看起来好像是一组任务计划是同时编写的,最后一个任务的DSCP代码就是该组的代码。然而,有些是不正确的。

问题

    < li >使用channel.write()有没有更有效的方法?我想在每次写入后刷新通道,但我没有看到这个方法。有没有我没发现的? < li >在每次写入之前写入trafficClass无法正常工作有什么原因吗? < li >我尝试使用相同的DSCP对任务计划进行分组,并将其作为一个单元来编写。我会写低,然后中,然后高,以为路由器会调整交付,但这也不起作用。

我已经解决了这个问题,更好的是,一位同事查看了我的代码,我们发现了这个问题。我的代码中有一个竞争条件,它不允许设置正确的DSCP代码。如果你看一下我的setTrafficClass方法,你可以看到我传入了我想要设置的代码,但是重要的是要意识到这段代码是设置连接而不是实际的数据包DSCP。因为我实际上是尽可能快地发送了100个任务计划,所以代码不断地改变连接的流量等级。如果有足够的时间,它就无法跟上,因此我会看到这种行为。

由于采用了 Netty API,因此解决方案非常简单。在我的情况下,我只使用2个DSCP代码,所以我声明了两个连接。一个连接将处理 DSCP 代码 0 数据包,另一个连接将处理 DSCP 代码 46 数据包。一旦我应用了这段代码,我就能够看到两个DSCP代码都按预期到达发送方。

共有2个答案

韩喜
2023-03-14

就我个人而言,我会在代码中执行优先级排序,而不是依靠网络来完成。这样,您就可以将自己与数据可能需要经过的任何特殊网络配置隔离开来。

有几种方法可以实现这一点,因此以下只是一个例子。

    < li >在单独的线程中读取计划,并放在优先级队列中 < li >从第二个线程的优先级队列中读取项目,并写入通道 < li >如果channel.isWritable返回它不再可写,您可以阻塞返回的future,从而保证Netty已将所有数据刷新到套接字缓冲区,或者在Netty将足够的数据刷新到低水位线以下时,立即侦听channelInterestOpsChanged事件以恢复写入。这可能更具性能,因为它允许您在Netty刷新最后一个以前的数据时继续准备数据。

Java至少从Java6开始就提供了PriorityQueue实现。它甚至提供了一个示例,说明如何使用序列号在不同的优先级级别内维护优先级。如果您的网络速度很慢,您可能需要限制队列中未完成计划的数量。

您可能还需要考虑饥饿是否是一个问题 - 即是否产生了如此多的高优先级计划,以至于低优先级计划永远不会被发送。

诸葛雨泽
2023-03-14

我想我没有答案。

>

  • 在Netty 3.9中,您可以等待channel.write()返回未来,或者更好地在您自己的ChannelFutureListener上开始下一次写入,如下所示:

    channel.write().addListener(yourChannelFutureListener);
    

    您不应阻止 IO 工作线程,因此使用侦听器的原因。但是,如果它太复杂,您只需在管道中添加一个有序内存软件线程池计算器,就在应用程序处理程序之前,以便在 IO 工作线程外部执行它,然后使用 await()。

    在内蒂

    还要注意,IPV4中的值是有限的(请参阅Javadoc)。

    但是,我不是这方面的专家,但我认为无论代码如何,顺序都是保持的,因为据我所知,从TCP的角度来看,它是强制性的。我相信在UDP中,它应该按照您的要求工作(因为无法确保订购)。

  •  类似资料:
    • 在进一步介绍之前,让我们花点时间来讨论编写"通用"代码时的约束条件 - 即运行在服务器和客户端的代码。由于用例和平台 API 的差异,当运行在不同环境中时,我们的代码将不会完全相同。所以这里我们将会阐述你需要理解的关键事项。 服务器上的数据响应 在纯客户端应用程序 (client-only app) 中,每个用户会在他们各自的浏览器中使用新的应用程序实例。对于服务器端渲染,我们也希望如此:每个请求

    • 在进一步介绍之前,让我们花点时间来讨论编写"通用"代码时的约束条件 - 即运行在服务器和客户端的代码。由于用例和平台 API 的差异,当运行在不同环境中时,我们的代码将不会完全相同。所以这里我们将会阐述你需要理解的关键事项。 服务器上的数据响应 在纯客户端应用程序(client-only app)中,每个用户会在他们各自的浏览器中使用新的应用程序实例。对于服务器端渲染,我们也希望如此:每个请求应该

    • 首先感谢大家的关注,我将spring batch和spring integration结合起来,定义了一个作业流,从ftp适配器中检索文件发送到jobChannel,并用spring batch对其进行处理,我要写到输出通道,处理后使用通道,我的代码是:

    • 问题内容: 我正在练习中用Java写一个skiplist类。我编写了一个名为的类,其中包含实际的跳过列表。我还制作了一个包装类,该包装类实现了接口并包含的实例。 其中,包含一个方法,该方法返回等于存在的元素,否则返回null。 在编写(继承自via )方法时,我注意到其参数是一个Object而不是一个E。我打算这样做,但由于类型擦除而无法实现: 由于无法通过这种方式完成操作,该怎么办? 问题答案:

    • 我是Selenium的新手,需要能够使用属性和文本对以下元素进行xpath。 我正在使用 但我还需要它带有属性,以便将其缩小到单个元素。

    • 问题内容: 在昨天发布的另一个问题中,我对如何在Windows中将Python脚本作为服务运行提供了很好的建议。我唯一想知道的是:Windows如何了解可以在本机工具(“管理工具”中的“服务”窗口)中管理的服务。即 在Windows下,等效于在Linux下将启动/停止脚本放在/etc/init.d中的Windows是什么? 问题答案: 与Windows中大多数“可感知”的东西一样,答案是“注册表”