繁体   English   中英

Java性能池与阻塞

[英]Java performance pooling vs blocking

我正在考虑通过网络发送某种消息的两种方法。

1)有一个带有内部缓存的LoadBalancer,它引用了Channels。 每个通道都有一个内部线程(可调用),该线程具有用于发送消息的实现以及它接受sendMessage请求的公共接口。

Channel为LoadBalancer提供了一种方法,可以在该方法上执行非阻塞查询,并可以发送其他消息。

总结一下:LoadBalancer有一个线程,该线程连续地沿通道列表isChannelReady()合并通道列表,并在通道就绪时发送另一条消息。

public class SomeLoadBalancingStrategy implements LoadBalancer {
private List<Channel> channels = ChannelFactory.getChannels(//parameters here)

// read from some queue
while(there are messages) {

foreach (channel) {

// non blocking query
if(channel.isReady()) {

       channel.sendMessage(message)
    }
  }
}

2)每个通道对象由可运行线程组成,该线程包装负责发送消息的内部可调用对象。 通道在某些并发队列中等待新消息被阻塞。 将消息添加到队列中后,通道可运行通道将其拾取并传递给可调用通道。 该可运行对象被阻止,等待结果。 一旦有callable的结果可用,线程包装它可能会通过LoadBalancer接口从队列中提取下一条消息。

因此,总结一下:每个通道有两个线程,一个线程可以调用并发送消息,第二个线程等待该结果,以便可以接收下一个请求。 在这种情况下,没有单独的LoadBalancer线程将消息分发到通道。

一些注意事项:

  • 通道使用与端点的同步通信

  • 请考虑我对解决方案的解释,就像我要讨论的基本思想的模板一样

  • 频道数量很少,最多5个

第二种方法在性能上总是更好吗? 是否有条件下优先选择会更好? 硬件,操作系统,什么? 如果通道是异步的,会有所不同吗?

第二种方法在性能上总是更好吗?

不可能说。 最好的选择是测试两种方法。 通常,最简单的解决方案是最好的,并且在队列前面添加队列并不总是有用的(TCP流是字节队列)

是否有条件下优先选择会更好?

专用线程通常更容易推理,并且性能更好。 当线程数量较少时,这将更好地工作。

如果通道是异步的,会有所不同吗?

是的,但无法说是否更好,但会更加复杂。

我建议您看看netty ,如果不使用它,而是从它的使用方法中学习。

解决方案第一似乎在负载均衡器中进行了持续轮询,询问每个通道是否准备就绪。

这将增加不必要的CPU消耗。 我将更改1),以通过保留“就绪”通道的阻塞队列来避免这种情况。 负载平衡器将从队列中拉出一个就绪通道,并且这些通道在准备好另一个请求时会将其自身添加到队列中。

在2)中,除非操作分配器的实现(可调用API?)以某种方式强加了,否则不明白为什么每个通道需要两个线程。

IMO的两个选项在性能上似乎相当,我不明白为什么一个选项会比另一个选项做得更好。 也就是说,1)可以保证循环使用所有通道,而2)如果消息流量较低,则取决于VM如何管理集合,同一通道可能总是在工作等待请求消息队列中新项目的Java线程数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM