2012-03-27 45 views
-1

网络协议解析器代码,解析单线程中的图层。解析一些网络协议后,得到唯一的对话框。 对于网络协议解析器项目;有一个消息解析器,解析具有多个层的消息(例如,以太网,IP,TCP等)。解析字段之一是层中间的对话ID;这意味着在获得它之前需要进行一些解析操作。得到dialog id解析后应该(因为性能)多线程。 约束是指具有相同对话ID的消息应以相同的顺序处理。我有一些想法,但不确定是否优雅。按参数排列的Java Multithread

  1. 创建10个队列作为对话框ID的最后一位,每个队列解析单独的线程。
  2. 多个执行程序的模块操作相对于对话框id类似的第一个选项。

如何将消息处理为多线程?

更多解释; 有多于一个的消息相同的对话ID和它应处理相同order.These被对话ID之间没有相关性,我的意思是对话ID = 100能够对话ID之前处理= 99

消息

例传入订单

  1. 对话ID = 100
  2. 对话ID = 99
  3. 对话ID = 98
  4. 对话ID = 100
  5. 对话ID = 100
  6. 消息2或消息4 - - 消息1.后消息5之前没有消息4之间的任何顺序
  7. 对话ID = 98
  8. 对话ID = 99

消息4应处理消息3等。

+1

找不到问号。 – bezmax 2012-03-27 09:53:59

+0

我猜只是最后一点是真正的问题,而且你问:“配置我的有效载荷的最佳方法是按顺序处理具有相同对话ID的所有项目?”根据定义,“不具有相同对话ID的项目可以按任何顺序处理” - 即可以与具有dialogId = 1002的项目同时处理项目dialogId = 1001? – wmorrison365 2012-03-27 09:56:39

+0

如果上述条件为真,那么:(1)我假定“按顺序”的意思是说,一旦有效载荷项被解析器识别出来,它必须在由具有相同对话的解析器识别的下一个项之前被处理ID。即对于dialogId = 1001,解析器找到了项目1001_1,然后是1001_2,然后是1001_3,因此应按照该顺序处理这些项目。如果是这样,(2)处理每个项目的结果是否按照该顺序保持是重要的,还是按照该顺序完成实际的“处理”是足够的? – wmorrison365 2012-03-27 09:59:22

回答

0

好吧,给你的编辑和我在评论这个问题的假设,我可能会做以下的(我认为这是接近你是无论如何提示)。请注意,我假设处理的顺序很重要,但不是所产生的任何结果的顺序(因为您需要在每个有效负载项上使用顺序ID)。

我建议如下:

  1. 使用基于队列的机制,确保 项目具有相同对话ID的执行顺序。这可能是并发的 队列实施或JMS队列,具体取决于系统的分布 。
  2. 决定你需要队列的数量,给您的总有效载荷。
  3. 所有具有相同dialogId的项目都必须进入同一队列。多个 不同的dialogIds可以进入同一队列。
  4. 确定哪个队列一个dialogId应该被分配到使用id的散列 或模。通过这种方式,您的队列将始终包含 有效负载项目,以实现dialogId。
  5. 或者:

    (一)杭多个工作线程关闭每个队列来同时处理的物品,在 序列从队列。这提供了最高并发(硬件的 范围内),但你运行的两个项目具有相同 对话ID的风险正在开始订单,但出完的顺序(即1001_1开始 第一,但睡觉和1001_2启动,在那段时间内完成)。

    (b)中仅杭一个worker线程每个队列来处理在一个时间 严格的顺序一个从该队列项目。您现在削减线程的数量每个队列下降到 只有一个,但是,这样做,你能保证处理该队列 (并在其上处理所有dialogIds)的顺序。 (c)作为(b)但每个对话ID有一个线程(对于在该队列上处理的所有ID,该队列可以向前看并且只处理具有该ID的线程,这保证了 命令并且提高了吞吐量(d)由于(a)有多个线程可以跨所有ID操作,但会锁定对话框ID ,以确保按顺序完成处理。管理要做什么的大量开销 对话ID被锁定 - 开始新队列?requeue?

在任何情况下,您总是可以每个队列至少有一个线程,并且对于您的设置而言,最多可以有多个队列。这样你可以实现一些并发性。此外,越是可以将队列中的对话ID传播越好。其他考虑因素是负载平衡队列。

0

您将需要跟踪您当前处理的任何消息的对话ID,因为您无法开始处理具有相同对话ID的其他消息,直到前一个消息完成。

所以我会推荐以下内容:将数据包存储在列表中。主列表包含每个对话ID至少有一个未处理消息的条目。内部列表包含当前对该对话ID未处理(或未完整处理)的所有消息。

当您收到新消息时:检查当前处理消息的表。如果有一个具有相同的对话ID,请将该消息链接在它后面。如果没有,则使用该对话框ID在表格中创建一个新条目。将其标记为可以处理并唤醒任何睡眠线程。

处理消息:检查当前处理消息的表格。如果没有标记就绪,请等到一个标记就绪。如果您发现一个标记就绪,请从该内部列表中获取头部消息,并将该列表标记为正在处理中。完成处理后,如果没有消息链接到它(使用相同的对话ID0,请将其从主列表中删除,否则,请删除我们已处理的消息并将其标记为可以处理。