我正在研究基于java SE(+ netty)的系统,该系统从客户端接收不同类型的消息,聚合它们并将聚合结果推送到存储中。
我需要在汇总之前预先累积消息,直到满足以下两个条件之一 - 超出超时或超出数量。超时和数量是针对每种类型预先配置的,可能会有很大差异。之后,我聚合/减少相同类型和发送者的消息,并将结果推送到存储中。聚合可能看起来像计算消息中的平均值。或者它可能要复杂得多。在我的情况下,存储中的后聚合是不可接受的。
这项任务似乎很简单,但我坚持执行。显然,我需要在某些数据结构中收集消息,并检查每个元素的超时和数量规则。我想过DelayedQueue<Delayed<List<MyMessages>>>
(List<MyMessages>
- 是一个可聚合的消息列表。)
DelayedQueue
以很好的方式实现超时。但目前尚不清楚,如何检查最大数量并有效地在列表中添加新消息。我不想在每条新消息上检查所有列表,搜索正确的消息。将数据添加到Delayed<List>
元素看起来并不安全。
哪些数据结构/架构适合我正在尝试创建的系统?我想这个问题有一个合适的学术名称和解决方案,我该怎么去谷歌?
答案 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,例如让它等待队列,而接收线程又可以将队列作为“消息” “关于需要聚合和存储的队列。