【问题标题】:Producer-consumer architecture with Java RealTime使用 Java RealTime 的生产者-消费者架构
【发布时间】:2012-01-08 04:59:08
【问题描述】:

我正在使用 Java Realtime (Sun JRTS 2.2) 设计交易系统,想问几个关于最佳实践的问题,因为我害怕发明轮子,而且我很确定我的任务已经解决了。

所以我有线程持续读取套接字、解析字节和提取消息(二进制协议)。之后,我应该向算法发送消息,它实际上会进行一些计算并决定是否交易。

所以我认为我应该设计这个系统的方式是将它分成两部分。生产者(周期性(?)实时线程,从套接字中提取字节,解析它)和消费者(实时线程(周期性/零星?),从生产者那里提取消息,使用它们进行操作等)。

那么第一个问题是如何设计这两个线程(生产者/消费者)之间的高性能通信?我也很想听听 cmets 关于设计此类系统的现有经验、建议等。

感谢您的帮助!

【问题讨论】:

  • 您知道实时并不一定意味着更快吗?
  • 是的,我愿意。但我也应该注意垃圾收集器,高频率和低延迟。

标签: java multithreading real-time producer-consumer


【解决方案1】:

我正在处理类似的问题,但在不同的域中:

我是这样处理的:

public class Producer extends Thread{
   private BlockingQueue<E> consumerQueue = null;
   public setConsumerQueue(BlockingQueue<E> val){
      consumerQueue = val;
   }
   // main method where data is received from socket...
   public void run(){
      while(!interrupted()){
           data = socket.receive();// Receive data
           if(consumerQueue!=null) consumerQueue.offer(data);
      }
   }
}

public class Consumer extends Thread{
   private BlockingQueue<E> consumerQueue = new BlockingQueue<E>();
   public Consumer (Producer val){
      val.setConsumerQueue(consumerQueue);
   }
   public void run(){
      while(!interrupted()){
           data = consumerQueue.take();// block until there is data from producer
           if(data !=null) processData(data);
      }
   }
}

【讨论】:

  • 感谢您的评论。我认为我们需要研究中断库并降低线程通信延迟。
  • 取决于您的应用程序可以承受的延迟幅度,但如果您想让事情变得更快(实时),那么恐怕您必须使用更快的本地语言,例如 C++
【解决方案2】:

在决定如何分解您的应用程序时,最好了解每个阶段需要多长时间以及可以并行完成哪些处理。您希望以微秒为单位对每个阶段进行计时并测量分布。最有趣的点通常是 99%(最差的 1%)、99.9% 或 99.99% 的瓦片延迟。


我想看看disruptor 库。这是一个相当通用的库,专为高吞吐量和低延迟而设计。


如果您想要更简单的东西,有许多模式可以在亚微秒时间内在线程之间交换数据,但是这些都是点解决方案,取决于您的具体用例。

您可能会发现此演示文稿很有趣,尽管它主要涉及测试低延迟、高吞吐量组件和通过套接字进行的通信。 http://vanillajava.blogspot.com/2011/11/low-latency-slides.html

【讨论】:

  • 彼得,感谢您对破坏库的推荐。这绝对是我应该考虑的事情之一。也许您可以推荐一些技术/模式来处理从套接字读取的高性能/低延迟(我使用 Java NIO 开发了简单的原型,但我很确定有一些方面需要调整)。
  • 我建议您像我在演示文稿中所做的那样调整您的系统。 (使用亲和力将线程分配给内核)使用忙等待来进一步降低延迟。如果可以,请使用内核旁路网络适配器。例如Solarflare 或 Myricom。尝试直接使用rdtsc,以降低使用时间戳的成本。
  • 顺便说一句:如果您正在使用忙等待一个简单的队列使用是 AtomicReference ;)
  • BTW2:你可能会觉得这个谜题很有趣vanillajava.blogspot.com/2011/11/…
  • 谢谢你的链接,彼得,订阅你的博客 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-09
  • 1970-01-01
  • 1970-01-01
  • 2019-05-24
  • 2012-04-30
  • 1970-01-01
相关资源
最近更新 更多