消息减少器/聚合器基于超时或超过的数量

时间:2014-04-05 20:35:40

标签: java aggregate

我正在研究基于java SE(+ netty)的系统,该系统从客户端接收不同类型的消息,聚合它们并将聚合结果推送到存储中。

我需要在汇总之前预先累积消息,直到满足以下两个条件之一 - 超出超时或超出数量。超时和数量是针对每种类型预先配置的,可能会有很大差异。之后,我聚合/减少相同类型和发送者的消息,并将结果推送到存储中。聚合可能看起来像计算消息中的平均值。或者它可能要复杂得多。在我的情况下,存储中的后聚合是不可接受的。

这项任务似乎很简单,但我坚持执行。显然,我需要在某些数据结构中收集消息,并检查每个元素的超时和数量规则。我想过DelayedQueue<Delayed<List<MyMessages>>>List<MyMessages> - 是一个可聚合的消息列表。)

DelayedQueue以很好的方式实现超时。但目前尚不清楚,如何检查最大数量并有效地在列表中添加新消息。我不想在每条新消息上检查所有列表,搜索正确的消息。将数据添加到Delayed<List>元素看起来并不安全。

哪些数据结构/架构适合我正在尝试创建的系统?我想这个问题有一个合适的学术名称和解决方案,我该怎么去谷歌?

1 个答案:

答案 0 :(得分:0)

忽略可能对此有帮助的现有数据结构,问题可以从根本上以两种方式解决:接受消息的线程执行检查并通知聚合线程,或者聚合线程需要轮询。第一种方法使限制检查变得容易,第二种方法使超时变得容易。

我建议将两者结合使用:接收线程记录已累积的项目数,并在达到阈值时通知聚合线程,聚合线程会跟踪时间。

你可以这样简单地做到这一点:

final long maxWait = 1000;
final int maxMessages = 10;
final ArrayBlockingQueue<Message> queue;

final Thread aggregator = new Thread()
{
  @Override
  public void run() {
    try {
      ArrayList<Message> messages = new ArrayList<>();
      while ( true ) {
        messages.clear();
        queue.drainTo( messages );

        // Store messages

        this.wait( maxWait );
      }
    }
    catch ( InterruptedException e ) {
      // Handle this..
    }
  }
};

final Thread reciever = new Thread()
{
  @Override
  public void run() {
    Message message; // Get this from network
    queue.put( message );
    if(queue.size() > maxMessages) {
      aggregator.notify();
    }
  }
}

这不处理您的邮件分组,但我相信您可以看到如何推断这可以处理不同邮件类型的多个队列。要使聚合器在通知时仅考虑某些特定的消息类型,您可以使用一些更复杂的消息传递机制而不是wait / notify,例如让它等待队列,而接收线程又可以将队列作为“消息” “关于需要聚合和存储的队列。