排队消息的并发处理的制作方法

文档序号:7992086阅读:235来源:国知局
排队消息的并发处理的制作方法
【专利摘要】在流内执行排序的同时,提供对来自消息队列消息的可缩放、并发(即,并发)处理。因此能够遵守消息之间的依赖性。不要求用于确定哪些消息形成流的准则为消息分派器所知,消息分派器接收流名称并确定该指定流中的另一消息正在被处理。如果是这样,则分派器确定调取者是应暂时等待,还是应被给定先前被阻止且已变得可用于处理的不同消息,还是应被命令从消息队列取回不同的消息。
【专利说明】排队消息的并发处理
【技术领域】
[0001]本发明涉及计算系统,并且更特别地涉及在队列中临时地存储消息的消息处理系统,并且更具体地涉及并发地处理消息队列中的排队消息流。
【背景技术】
[0002]消息排队在计算机编程中是众所周知的概念,并且是指消息发送模型,在消息发送模型中来自多个发送者的消息被放置在消息发送服务提供者处的队列处,并且然后从队列分派到各个目标接收者。消息发送服务提供者还可称为消息派对系统。消息队列提供消息发送者与接收者之间的异步通信,由此,发送者能够在不考虑接收者当前是否能够接收到消息的情况下发送消息:消息保持被存储在队列中直至诸如其被分派到接收者的时间为止。发送者和接收者可以是单个计算机上的进程或者不同计算机上的进程。可使用事务处理语义来确保消息不会被永久地从队列去除直至接收者已成功地将其接收为止。

【发明内容】

[0003]本发明涉及并发地处理来自消息队列的排队消息流。在一方面,这包括:接收用以分配来自所述消息队列的排队消息以由线程处理的请求,所述排队消息属于已标识的消息流;以及响应于确定属于已标识的所述消息流的另一消息当前不在被处理,分配所述排队消息以用于由所述线程处理。所述消息流可以通过评估指定如何标识所述消息流的至少一个准则而被标识。所述请求可以包括所述排队消息的标识符和已标识的所述消息流的名称。响应于确定属于已标识的所述消息流的另一消息当前正在被处理,可以分配所述排队消息中的不同的一个排队消息以由所述线程处理,所述不同的排队消息属于不同的消息流。
[0004]可将本发明的这些及其他方面的实施方式提供为方法、系统和/或计算机程序产品。应注意的是前述内容是概要,并且因此必要地包含细节的简单化、一般化和省略;因此,本领域的技术人员将认识到该概要仅仅是说明性的,并且并不意图以任何方式是限制性的。由所附权利要求限定的本发明的其他方面、发明特征和优点在下面阐述的非限制性详细描述中将变得显而易见。
【专利附图】

【附图说明】
[0005]现在将仅以示例的方式并参考附图来描述本发明的实施方式,在附图中:
[0006]图1和4通过图示出本发明的实施方式的操作而图示出样本消息队列;
[0007]图2提供了描述调取线程、队列接口以及分派器接口之间的代表性交互的流程图;
[0008]图3描述了可存储在队列上的消息的简单示例;
[0009]图5-7提供了描述当实现本发明的实施方式时可使用的逻辑的流程图;以及
[0010]图8描述了适合于存储和/或执行程序代码的数据处理系统。【具体实施方式】
[0011]在队列中存储消息的消息处理系统一般地称为消息排队系统。消息排队系统通常使用先进先出、或“FIFO”排队方法以用于消息递送。如众所周知的,其包括按照消息最初被置于队列上的相同顺序从队列去除消息。然而,可认识到队列内的消息的子集常常相互有关。例如子集中的消息可源自于同一发送者和/或其可以以同一接收机为目标。或者,队列上的多个消息可能是较大事务的一部分,诸如表示银行事务的借贷的消息。相应地,本发明的实施方式将队列视为流的集合,其中,流是借助于某些准则匹配而相关的消息的某个(可能无界)子集。本发明的实施方式使得能够并发地处理流中的多个流,同时确保每个流内的消息继续被按照FIFO顺序处理。
[0012]根据本发明的实施方式,流是正交的,亦即每个消息属于一个且仅一个流。不要求用来标识流的准则为排队系统所知。替代地,由读取排队消息的线程针对准则来评估每个排队消息。使用浏览式读取操作,由此,消息未被该读取实际上从队列去除。如果浏览显示此消息属于期望流,则可使用后续操作来从队列去除该消息,如下面将更详细地讨论。
[0013]本发明的实施方式依赖于消息排队系统的多个属性和用来访问该系统中的消息的接口,包括:
[0014]?消息队列存在于多线程计算环境中,其中多个线程处理从队列取回(retrieve)的消息。本发明的实施方式不对此多线程环境中的线程的数目N设置上限。
[0015]?使用事务型语义从队列取回消息。也就是说,一旦已从队列取回消息,则其不可用于任何其他线程或进程,除非其被回滚(并因此恢复到队列)。
[0016]?能够以严格的FIFO方式来取回消息。
[0017]?能够浏览而不是`取回消息。当浏览消息时,能够在不将消息从队列去除的情况下检查消息的内容,并且因此在执行浏览时不需要考虑的事务型语义。
[0018].能够连续地浏览消息。可使用消息光标或消息序列号来跟踪在队列内的位置,使得能够容易地确定下一连续排队消息。
[0019]?消息能够具有唯一键或标识符(在下文中称为消息标识符或消息ID),并且因此能够将单独排队消息与队列中的其他消息区别开。
[0020]?能够在浏览之后不按顺序地取回消息,使用在浏览期间发现的唯一消息标识符来请求消息取回。
[0021]本发明的实施方式遵守一组原理,其包括:
[0022]?可以并发地处理来自不同流的消息。
[0023]?保持特定流内的消息排序。相应地,当来自流的一个消息被从队列去除时,在开始处理该流中的另一消息之前完成处理该消息。
[0024]?消息分派部件的调取者(invoker)确定排队消息属于哪个流。这优选地包括检查被浏览消息的内容并将该内容与一个或多个准则相比较。可使用XPath表达式或类似表示法来指定准则或其某个子集。(XPath表示法对于本领域的技术人员而言是众所周知的,并且因此在本文中不做更详细的描述。)
[0025]?优选地使用事务型语义来处理消息。也就是说,一旦已从队列去除了消息,则该消息被处理至完成并提交,否则消息被回滚(回滚包括将消息恢复至队列)。[0026]?一旦已在队列上浏览了特定消息并针对准则进行评估以确定消息所属的流,则优选地在该线程上处理该消息至完成。然而,可将特定消息的处理从最初浏览并评估消息的线程切换至将完成消息处理的另一线程,如果替换将阻止处于等待状态的所有空闲线程,尽管此切换可招致相对显著的开销(包括由接管线程来重新解析该消息以对消息的各种字段进行定位)。
[0027]?当选择要分配给线程的消息时,排队消息之间的消息优先级化优选地包括首先对当前未被任何线程处理的流给予优先权,并且然后在队列内按顺序给予优先权。换言之,如果存在用于两个(或更多)不同流的排队消息,其两者中没有一个具有当前被处理的消息,则这些流中的具有最接近于队列头部的消息的那个被给定较高优先级,并且因此将取回用于此流的第一排队消息并将其分配给线程。
[0028]?控制消息的分派,使得包含许多消息的流并不完全使得其他流的处理处于饥饿状态(starve)。也就是说,在具有可用于处理来自队列的消息的N个线程的系统中,本发明的实施方式确保被允许服务于来自同一流的消息的线程的数目(包括在特定排队消息上等待以变得可用的线程)在X < N时将不超过(N-X),并且当X > = N时将不超过I,其中X是一时间点处的在队列上具有消息(包括已被暂时地去除而尚未提交的消息)的流的数目。
[0029]本发明的实施方式提供了分派器(dispatcher)对象或部件(在下文中称为分派器对象或简单地称为分派器),其控制哪些消息被每个线程处理和该处理何时能够开始。此分派器在多线程计算环境中被多个线程中的每一个调取。使用本文公开的技术,在仍然确保保持流内的排序的同时实现跨各流的并发性。(应注意的是,虽然本文中的讨论假设在消息流中使用事务型语义,但本发明的实施方式可替换地由并不要求提交和回滚处理的消息流来使用。鉴于本文提供的教示,如何能够适应此替换将是显而易见的。作为示例,上文所讨论的值“X”将变成在一时间点在队列上具有消息的流的数目或具有当前正在被处理的消息的流的数目。)
[0030]以举例说明的方式考虑图1中所示的队列100。队列100包含3个消息101、102、103,并且消息101在队列的头部处一也就是说,消息101是要排队的消息中的第一个消息。消息101和102两者都是同一流的一部分,以举例说明的方式称为流“A”,并且因此表示为样本队列100中的消息“Al”和“A2”。另一方面,消息103是针对不同的流,称为流“B”,并且因此在样本队列100中将此消息表示为消息“BI”。假设两个线程Tl、T2可用于处理来自队列100的消息。相应地,当使用本发明的实施方式时,可由这两个线程来并发地处理消息Al 101和消息BI 102,但是防止消息Al 101和A2102被并发地处理。与其中按照严格的FIFO顺序将线程分配给排队消息的已知技术相反,其中(当使用已知技术时)消息AllOl将被分配给线程Tl,且消息A2102将在正在Tl正在处理消息Al的同时被分配给线程T2。 [0031]仍参考图1,假设消息AllOl和A2102构成银行事务的一部分,其中,消息Al表示存入$100到账户持有者的支票帐户,并且消息A2表示在该帐户上提取$105的支票。在处理消息Al完成之前处理消息A2,在某些情况下导致支票帐户的透支。另一方面,如果保证消息Al在消息A2之前被处理,则不发生此透支(当仅考虑这两个消息时)。本发明的实施方式确保一旦消息已被确定为是同一流的一部分,则按照特定顺序来处理消息。相应地,遵守消息之间的各种依赖一诸如在银行示例中。
[0032]特别地,本发明的实施方式并不严格地要求由一个且仅一个线程来处理特定流的所有消息。例如,如果线程Tl在线程T2请求来自队列的消息时已完成消息Al的处理时,则本发明的实施方式允许将消息A2分配给线程T2。
[0033]通过使用单个线程来完成特定消息的处理,即使可在上下文切换期间将线程换出(即,变成暂时不活跃的),也可以实现处理效率。线程必须执行一定量的消息解析,例如在能够处理消息之前。这甚至适用于被浏览消息,其中,调取浏览操作的线程解析被浏览消息,以确定该消息所属的流——在某些情况下还注意到,在浏览期间必须对多个字段进行定位和评估以便确定该流。还可发生的是,排队消息被加密,在这种情况下浏览操作包括将消息的至少一部分解密。相应地,使用在解析期间由第一线程获悉的信息(以及随着消息处理的继续而被获悉或创建的其他信息)、而不允许将消息切换到不同的线程、并要求该线程来重复由原始线程执行的操作,这是有利的。
[0034]仍参考图1中的样本队列100,本发明的实施方式防止流B饥饿,如在使用已知技术并根据队列100中的消息101、102、103的FIFO排序而将全部的N (其中在这种情况下N=2)个线程分配给流A的消息的情况下,将导致流B饥饿。
[0035]在本发明的实施方式中,在队列上支持三种不同的调取。那些调取中的两个从队列读取消息,在本文中称为(I) “浏览”调取和(2) “获得”调取。在本文中称为(3) “提交”的队列上的第三调取,其信号通知分派器来提交从队列去除消息。本发明的实施方式还支持能够在分派器上调取的三个不同类型的请求,在本文中称为(I) “检查”,(2) “分派”以及
(3)“完成”。分派器可根据被调取请求和当前上下文而返回在本文中称为(I)前进(go),
(2)“交换”或(3) “跳过”的回答。在本文中将更详细地描述这些调取和回答中的每一个。
[0036]现在参考图2,根据本发明的实施方式,提供了示出调取线程和与队列和分派器接口之间的典型交互的总体流程200。调取线程调用Dispatcher.Check (没有输入参数)(参见205),以查看是否存在先前被阻止且被分派器记住的、现在已变得可用于处理的任何消息,或者调取者是否应替换地跳到队列上的下一消息上。如果分派器不知道任何此类先前被阻止但现在可用的消息,则其返回“跳过”210。这通知调取者调用队列上的Queue.Browse(参见220 )以查看是否存在尚未被读取的任何排队消息。如果在队列上不存在排队消息(参见215),则目前不存在用于此线程的工作,并且线程将通过返回至205而在随后的时间调用Dispatcher.Check。(注意,分派器可在其在各种点处返回回答之前等待,虽然在图2中没有描述等待。)
[0037]另一方面,当Queue.Browse220对队列上的消息(即,尚未被读取的队列消息)进行定位时,然后该消息的消息ID被返回至调取者(参见225)。调取者然后优选地调用Dispatcher.Dispatch (参见230),以便询问调取者是否能够处理该消息。其结果将是“前进”、“交换”或“跳过”。
[0038]当分派器正在信号通知调取者暂时忘记所请求消息时,在230处从调用返回“跳过”(参见235),并且将从队列取回不同的消息,然后将再次地调取分派器。(例如,如果线程T2请求在线程Tl正在处理消息AllOl的时间处理图1的样本队列中的消息A2102,则其将接收到“跳过”。)相应地,调取者从230返回至220以浏览来自队列的下一消息。
[0039]当分派器判定调取者应处理与在230处由调取者所请求的消息225不同的消息时,将从230处的调用返回“交换”(参见245)。相应地,将(不同的)消息ID与“交换”回答245 —起提供给调取者。[0040]当分派器正在信号通知调取者继续进行处理在230处由调度程序请求的消息225至完成时,从230处的调用返回“前进”(参见240)。(注意,这是刚刚被调取者浏览220的相同消息。)根据本发明的实施方式,如果不存在当前正在处理同一流上的消息的其他线程时,分派器将仅仅给出此“前进”回答。
[0041]对于“前进”240和“交换”245两种情况而言,调取者使用对Queue.Get的调用(参见255)中的消息ID (分别用于先前浏览消息或已交换消息),该调用请求从队列读取并去除所标识消息。
[0042]返回至Dispatcher.Check205的讨论,如果分派器知道现在已变得可用于处理的先前被阻止消息,则其连同该消息的ID —起返回“交换”250。这用信号通知调取者其应处理现在可用的此消息。(例如,在图1中所示的示例性情形中,线程将在其已完成处理消息AllOl之后接收到“交换”,其中,交换通知其处理最初被请求——但被拒绝——的消息A2102,以便分配给线程T2。)调取者然后在对Queue.Get的调用(参见255)中使用此ID,该调用请求从队列读取并去除所标识消息。
[0043]在调取者已发出Queue.Get255呼叫之后,调取者开始处理消息,并处理该消息至完成(参见260)。当处理完成时,调取者调用Queue.Commit (参见265)以在队列上执行提交,并调用Dispatcher.Complete (参见270)以用信号通知分派器此消息的处理现在完成。在270的处理之后,线程现在能够请求来自分派器的芯工作,并因此控制到205的返回,在那里调取者将发出另一 Dispatcher.Check。
[0044]现在将更详细地讨论图2中所示的各种元件。
[0045]请注意,分派器被调取者调用以确定是否浏览来自队列的下一消息(即,经由Dispatcher.Check调取205) ,并且还在浏览之后调取分派器(即,经由Dispatcher.Dispatch调取230)以确定是应处理被浏览消息(即,“前进”回答240)、跳过之后稍后(SP,“跳过”回答235)还是通过处理不同消息(即,“交换”回答245)来替换。
[0046]当调取Dispatcher.Check调用205时,并不要求从调度程序输入参数。来自此无输入调用的回答是跳过210或交换250,其中回答250还提供消息ID作为输出参数,如上所述。
[0047]当调取Dispatcher.Dispatch调用230时,优选地向分派器提供多个输入参数。这些输入参数可以包括由于220处的浏览调用而获得的值。在一个实施方式中,由调取者在Dispatcher.Dispatch230时提供的参数包括:
[0048]?所请求消息的唯一标识符,即消息ID ;
[0049]?所请求消息所属的流的名称;
[0050]?可由分派器存储的关于所请求消息的上下文一例如,浏览光标的值或序号,其反映此调度程序现在正在哪里浏览该队列;以及
[0051]?可被分派器与消息相关联地存储,且如果其被“交换”(例如在245处)可与此消息一起返回,以使得能够重用该信息的上下文。
[0052]假设例如Dispatcher.Dispatch230的调取者已将当在220处执行浏览操作时作为输入而传递的所标识消息解密,并且已经确定已解密消息表示图3的消息M1300。在本示例中,消息M1300和M2310表示银行事务的两个消息。在浏览操作期间,调取者可以查找消息中的特殊定界符(在图3中示为“ I ”),其指示各种字段之间的边界,并且可能已检查一个或多个字段的值。出于举例说明的目的,假设用于确定哪些消息形成用于银行事务的流的准则包括在消息的第三字段中具有相同的帐号,并且因此能够看到消息M1300和M2310是单个流的两个消息。如果线程在第一字段中观察到事务类型,且在第二字段中观察到事务量,则将值得记住该信息,这是因为其很可能在处理消息时是在另一点处所需要的。因此,除将“Ml”作为唯一消息ID传递并将“ACCOunt#001”作为流名称传递之外,本发明的实施方式还可提供“Credit”和“$100”作为上下文信息,以便由分派器与消息Ml相关联地存储。请注意,分派器本身并不利用此上下文信息,除非当消息Ml被分配给线程以用于处理时将其返回给调取者。以这种方式,可避免处理资源的冗余使用。(然而,替换实施方式也被认为在本发明的范围内,该替换实施方式不通过分派器来传递此类上下文信息且可因此导致信息的一定量的冗余处理。)
[0053]现在将参考图1中的样本队列100来讨论图2中所示的交互的流程图200。在本讨论中假设两个线程可用于处理排队消息101、102、103,并且这些线程被称为Tl和T2。
[0054]首先,Tl在205处在没有输入参数的情况下检查分派器,以查看是否存在应被换入处理中的任何先前被阻止但现在可用的消息。由于队列100现在是新的,所以在本示例中,不存在此类消息。相应地,分派器返回跳过回答210。线程Tl因此发出浏览请求220,提供浏览光标或指向此线程的当前位置的指针(其优选地已被初始化成指向队列头部)作为输入参数以便浏览队列,并接收第一排队消息101的唯一标识符225,其在本示例中为“Al”。(对于本领域的技术人员而言将显而易见的是,本文所使用的样本消息标识符“Al”、
等是为了便于参考而选择的,并且在本发明的实际实施方式中将替代地使用实际唯一消息标识符。)线程Tl然后解析所标识消息Al (其仍在队列上)以确定流名称(即,此消息所属的流的名称)。如先前所述,用于消息Al的流名称在本示例中为“Α”。Tl然后发出分派请求230,将流名称A和消息Al的唯一标识符作为输入连同如上文所讨论的上下文信息一起传递。由于不存在当前正在处理用于流A的消息的其他线程,所以在本示例中,分派器返回用于所请求消息(即用于刚刚浏览的消息Al)的“前进”240。线程Tl因此发出获得请求255以从队列获得消息`Al,并且Tl然后开始处理260该消息。
[0055]同时,线程Τ2准备好进行工作。Τ2因此在205处在没有输入参数的情况下检查分派器,以查看是否存在应当被换入处理中的任何先前被阻止但现在可用的消息。由于到目前为止尚未遇到此类消息,所以分派器返回跳过回答210。线程Τ2因此发出浏览请求220,提供浏览光标或指向此线程的当前位置的其他指针作为输入参数以便浏览队列,并接收唯一标识符225,在这种情况下为“Α2”102。线程Τ2然后解析所标识消息Α2 (其仍在队列上)以确定流名称,其为“A”。Τ2然后发出分派请求230,将流名称A和消息Α2的唯一标识符作为输入,连同如上文所讨论的上下文信息一起传递。分派器现在检测到在线程Tl正在并发地处理该流上的消息的同时,Τ2正在请求处理流A上的消息。本发明的实施方式旨在预防这种情况(因为例如流内的消息可彼此具有依赖性,如参考图3中所示的银行消息举例说明的)。相应地,分派请求230返回跳过235以通知Τ2跳过所请求消息(即,其刚刚浏览的消息),并且分派器将保持或阻止消息Α2用于处理直至诸如Tl完成处理流A上的另一消息的时间为止。响应于接收到跳过235,线程Τ2调用另一浏览操作220以浏览下一排队消息。此调用返回下一排队消息103的唯一标识符225,其在本示例中为“BI”。Τ2解析所标识消息(其仍在队列上)以确定流名称。针对消息Β1103,流名称在本示例中为“B”。线程Τ2然后发出分派请求230,将流名称B和唯一标识符BI作为输入连同如上文所讨论的上下文信息一起传递。由于不存在当前正在处理用于流B的消息的其他线程,所以在本示例中,分派器返回用于所请求消息(即用于刚刚浏览的消息BI)的“前进”240。线程T2因此发出获得请求255以从队列获得消息BI,并且T2然后开始处理260该消息。
[0056]当Tl完成消息Al 101的处理时,其调取队列上的提交265和分派器上的完成270,其导致提交消息Al从队列的去除。队列100的新头部现在将是消息A2102。Tl然后在没有输入参数的情况下发出新的检查205,以查看是否存在应被换入处理中的任何先前被阻止但现在可用的消息。在本示例中,存在一个此类消息,即响应于T2的处理请求而被阻止的消息A2。相应地,来自检查请求205的响应是交换回答205连同现在可用消息A2的唯一标识符。线程Tl因此使用消息ID A2作为输入发出获得请求255,以请求读取消息102并将其从队列去除。线程Tl然后开始处理260消息A2。
[0057]请注意,通过允许分派器在220处浏览队列之前在205处被调用,分派器能够确保已浏览的任何消息优先级高于尚未被浏览的消息。
[0058]作为另一简单但说明性示例,考虑图4中所示的样本队列400。此样本队列最初包含四个排队消息A1、A2、B1、C1。假设两个线程T1、T2再次被用来处理队列,并且线程Tl在Τ2仍在处理BI的同时完成其消息Al的处理(如上文已参考图1的样本队列100所讨论的)。现在,消息Α1、Α2和BI全部已被浏览(且消息Al已被去除),因此在本示例中要浏览的下一消息是Cl。然而,虽然消息Α2已被浏览,但其尚未被处理,并且由于消息Al (即连同消息Α2 —起形成流A的另一消息)的处理现在已完成,所以在本示例中现在不存在不能处理消息Α2的原因。相应地,作为由线程Tl在220处浏览消息Cl的替代,检查206将把消息Α2交换至线程Tl以用于处理,如在250处所示。
[0059]针对队列100以及队列400的处理,当浏览消息Α2时,分派器需要关于如下进行进行判定:使Τ2等待Tl完成其消息Al的处理(后面是将消息Α2分配给线程Τ2),还是替代地将消息Α2换出并使线程Τ2跳过至队列上的下一消息。当仅使用两个线程时,回答是简单直接的:Τ2不应被阻止,没有可用工作,并且因此分派器在235处用跳过进行回答。根据本发明的实施方式,当存在N个线程(N > 2)且在不存在跳过的情况下那些线程中的所有空闲线程将等待时,也遵循跳过至下一排队消息的这种方法。
[0060]还请注意,在使用队列100和400的示例中,当存在超过两个线程、其中的至少两个是空闲的且线程Τ2已请求消息Α2而仅发现此消息由于消息Al的并发处理而被阻止时,本发明的实施方式可指引Τ2等待而不是在235处跳过。在这里能够提供给Τ2的仅有选项是跳过或等待(即,因为在本示例中不存在能够被交换至Τ2的先前被阻止但现在可用的消息)。如本文中公开的跳过的使用允许线程在下一消息是用于不同流、且因此不适于处理的情况下查看队列。然而,当分派器知道存在可用的多个空闲线程时,不能通过让Τ2跳过而获得益处。也就是说,能够由并未存储关于被阻止消息的上下文信息的另一空闲线程Τ3来处理下一排队消息BI。相应地,能够让Τ2等待直到消息Al的处理完成,在该时间,Τ2然后能够处理Α2。这种等待方法改善了效率,因为Τ2在浏览消息Α2的同时已消耗资源,并且能够重用该信息,因为Τ2正忙于另一消息,这与与将Τ2分配给另一消息并要求不同的线程Tx重复消息Α2的处理相反。
[0061]作为另一示例,假设存在可用的N个线程,并且队列上的消息是按以下顺序:[0062]Al,A2,...A(n-l),An,Bl,Cl
[0063]换言之,存在用于流A的N个排队消息以及用于其他流的附加排队消息。本发明的实施方式确保并不是全部的N个线程都将被分配给流A,而将其他流B和C排除在外。这优选地包括使分派器通过阻止线程而开始,使得可读取、解析并最后在进行最初读取的同一线程上处理消息,同时仍确保以下各项中的一个为真。
[0064]?始终存在能够将跳过到下一排队消息的至少一个空闲线程;
[0065]?所有线程当前正在处理消息;或者
[0066]?在队列上不再存在消息。
[0067]现在将更详细地讨论优选实施方式的分派器。由分派器实现的机制优选地包括(O为每个流动态地分配锁以确保每次仅一个线程来处理给定流的消息;(2)实现算法以判定是回答前进、跳过还是交换;以及(3)保持存储器内数据结构以记录用于已被换出的那些消息的标识符、流名称以及上下文信息(亦即,保持以便随后分配给线程并因此不按顺序地分配,如上文参考图2的245和250所讨论的)。
[0068]参考该锁,分派器优选地在用于该流的消息被分派时为特定流创建锁。此分派可以是前进消息240、交换消息245或交换消息250的结果。优选地,在230处测试该锁以确定是否能够将所请求消息分配给调取者,并且优选地在针对消息的处理完成期间在270处释放。
[0069]参考存储器内数据结构,优选地在其中记录在230处针对特定消息作为输入传递至分派器的信息,以在将信息作为输入而传递的调取者被通知进行交换以处理不同消息的情况下,支持重用,在该情况下特定消息变成被阻止消息。然后,当特定被阻止消息最后被分配给线程(例如,通过245或250处的交换)时提供所记录消息作为输出`,以求改善用于该线程的处理效率。数据结构优选地使用流名称作为键。可以当选择哪个换出消息将分配给线程时,以FIFO方式来处理此数据结构中的条目。如果存在用于特定流名称的多个记录,则优选地选择用于该流的最早添加(即,最旧)存储记录以便分配给线程。
[0070]现在转到图5-7,提供了描述可在实现本发明的实施方式时使用的逻辑的流程图。这些流程图分别地表不Dispatcher.Check调取205、Dispatcher.Dispatch调取230以及Dispatcher.Complete调取270的处理。如先前所述,Dispatcher.Check不具有输入参数;用消息ID (除早先所描述的其他信息之外)来调取Dispatcher.Dispatch ;以及调取Dispatcher.Complete以通知分派器消息已被处理至完成。另外,如早先已讨论的,来自用于这些调取的分派器的响应包括:用于Dispatcher.Check的跳过(参见210)或交换(参见250),以及用于Dispatcher.Dispatch的跳过(参见235)、前进(参见240)或交换(参见245)。Dispatcher.Complete调取并不返回这种类型的输出事件。当从分派器返回交换时,其包括换入消息的消息ID,并且优选地还包括与该消息相关联的上下文信息。
[0071]如图5中所示,Dispatcher.Check205的处理包括确定应被换入的任何先前被阻止但现在可用的消息。此处理通过从上述存储器内数据结构获得下一记录而开始(方框500)。方框510测试数据结构是否已到最后。如果是这样(即,方框510处的测试具有肯定结果),则使用此存储器内数据结构没有定位到记录,因此处理在方框520处继续,在那里返回图2中的210处所示的“跳过”回答。然后存在图5的处理。
[0072]当方框510处的测试具有否定结果时,在存储器内数据结构中存在要评估的更多记录。相应地,处理在方框530处继续,其使用来自当前记录的流名称来确定锁对于该流而言在当前是否是活跃的。如果是这样(即,方框530处的测试具有肯定结果),则此流中的消息正在被处理,并且存储器内数据结构的此行所表示的被阻止消息因此必须在当前时间保持被阻止。处理因此返回至方框500以从存储器内数据结构获得下一记录(如果有的话)。
[0073]当方框530处的测试具有否定结果时,来自存储器内数据结构的当前记录是用于当前不在被处理的流。相应地,对应于此行的消息将被换入——也就是说,其将被分配给用于由Dispatcher.Check205的当前调取者处理。处理因此到达方框540,其从存储器内数据结构的当前行提取消息ID、连同存储于该行中的任何上下文信息,并将此信息作为输出提供给调用线程。这对应于在图2中的250处所示的“交换”回答。然后存在图5的处理。
[0074]如图6中所示的Dispatcher.Dispatch230的处理对应于分派器确定是否应由调取者来处理所请求消息,且如果不是的话将做什么来作为替代。此处理在方框600处通过确定用于被调取者作为输入而传递的消息的流名称而开始。方框605测试锁对于该流而言在当前是否是活跃的。如果不是(即,方框605处的测试具有否定结果),则对于此流而言消息当前不在被处理,并且所请求消息因此将被给定“前进”回答。处理因此在方框610处继续。否则,当方框605处的测试具有肯定结果(即,在所请求消息的流上存在锁)时,则处理在方框635处继续,其开始确定要做什么来代替允许调取者处理所请求消息的过程。
[0075]在方框610处,为所请求消息的流创建锁。方框615-625然后执行针对确保始终存在可用的至少一个线程的处理(即,不处理消息且不等待),以检查来自排队系统的更合格消息。方框615递增对所分派消息的数目——即当前正被处理的消息的数目——进行计数的计数器。方框620然后测试忙碌线程的数目(即,向其分派活跃消息的线程的数目,如在方框615处递增的计数器所表示的)加当前等待(即,被阻止)线程的数目是否等于N,其中N表示系统中的活跃线程的总数。当此测试具有肯定结果时,不存在空闲线程。相应地,控制转移至方框625,其唤醒最近等待线程。(替换地,在不脱离本发明的范围的情况下可以以另一方式来选择要唤醒的线程。)在任何情况下,方框630向调取者返回“前进”,然后图6的此调用的处理退出。此“前进”回答对应于图2的240。
[0076]当控制到达方框635、指示所请求消息的流被阻止时,执行测试以确定忙碌线程的数目加当前等待(即,被阻止)线程的数目是否小于(N-1),其表示比系统中的活跃线程的总数小一。当此测试具有肯定结果时,在系统中存在至少一个空闲线程。相应地,处理在方框640处继续。否则,当不存在空闲线程时,如方框635处的否定结果所确定的,则控制转移到方框675。
[0077]当调取者被要求在处理所请求消息之前等待时,到达方框640。相应地,方框640递增等待的线程的数目,并且方框645设置变量或标志以表示此调取者是最近的等待者。在方框650处,执行等待,其等待当前在此流上保持的锁被释放(例如,由图7的方框740的处理)或者此线程被另一线程唤醒(例如,由图6的方框625的处理)的信号。在任一种情况下,当等待结束时,方框652将等待线程的数目递减。方框655然后测试等待为什么结束。如果等待因为线程被唤醒而结束,则方框655处的测试具有肯定结果,并且在方框660处向调取者返回“跳过”。此“跳过”回答对应于图2的235。图6的处理然后退出。
[0078]假设排队消息按照FIFO顺序包括Al、A2、...、A (n_l )、An、B1、Cl,且存在总共N个可用线程。针对请求来自流A的消息的每个线程T (X),其中1 = 2至(^1),分派器将优选地在方框640处使用所有先前线程上的等待来阻止线程。然而,当线程T (N)用消息A(N)来调取分派器时,分派器不阻止此线程。替代地,分派器将把消息A (N)换出并向调取线程返回“跳过”。此“跳过”对应于图2的235。线程T (N)应因此在220处浏览队列,此时其将对消息BI进行定位。线程T (N)然后将以此消息BI作为输入来调取Dispatcher.Dispatch,并且分派器将分配线程T (N)以处理消息BI至完成——亦即将向线程T (N)返回“前进”240。在这里,线程T (N-1)将从其等待唤醒(促使方框655处的测试具有肯定结果),因为所有其他线程都被分派或阻止。作为来自线程T (N-1)的输入的消息A (N-1)将被换出,并且此线程T (N-1)然后将在方框660处被命令“跳过”至下一消息。
[0079]当方框655处的测试因为所请求流(即,在230处被作为输入传递至Dispatcher.Dispatch的流名称)上的锁已被释放而具有否定结果时,然后处理到达方框665,其创建用于该流的锁,以便当前调取者处理当前请求消息。方框668递增对所分派消息的数目进行计数的计数器。方框670然后向调用线程返回“前进”回答,其对应于图2的“前进”240,并且图6的处理然后退出。
[0080]当看起来并不期望使调取者等待、且因为该流上的另一消息已正在被处理而当前不能处理所请求消息时,到达方框675。相应地,方框675向上文所讨论的存储器内数据结构写入记录,其中,此记录包含被调取者作为输入而传递的信息。此信息优选地包括所请求消息的唯一 ID、用于该消息的流名称以及如早先所讨论的上下文信息。
[0081]方框680从此存储器内数据结构获得下一记录,并且方框685测试数据结构是否已在末端(即,所有记录已被读取)。如果此测试具有肯定结果,则不存在可用于换入此调取者的替换消息,并且方框690因此返回“跳过”回答,然后图6的处理退出。此“跳过”回答对应于图2的235。
[0082]当方框685处的测试具有否定结果,指示在存储器内数据结构中不存在能够被评估的更多记录,则处理到达方框695。方框695包括根据当前数据结构记录来确定流名称,并确定对于该流而言锁是否当前是活跃的。如果是这样,则相应的被阻止消息现在必须保持被阻止,并且处理因此返回至方框680以从存储器内数据结构获得下一记录(如果有的话)。当方框695具有否定结果时,这指示对应于来自存储器内数据结构的当前记录的流未被锁定。也就是说,已发现先前被阻止消息现在能够被处理,因为在该流上没有另一消息当前正在被处理(除满足方框635的要求之外)。处理因此到达方框699,其从存储器内数据结构的当前行提取消息ID连同存储于该行中的任何上下文信息,并在“交换”回答中将此信息作为输出提供给调取线程。这对应于在图2中的245处所示的“交换”回答。图6的处理然后退出。
[0083]如图1中所示的Dispatcher.Complete270的处理对应于由线程进行的消息的处理完成。此处理在方框700处通过确定用于现在已完成处理的消息的流名称而开始。可将该流名称作为输入而传递,或者例如其可能已被存储在分派器可访问的共享储存器中,或在随着消息被处理或结束其处理而由分派器使用的变量。方框710测试锁对于该流而言当前是否是活跃的。如果是这样(即,方框710处的测试具有肯定结果),则方框730将被分派的消息的数目——也是忙碌线程的数目——的计数器递减,然后,方框740将锁释放,使得然后能够处理此流中的不同消息。以这种方式,锁确保在每个流内每次处理不超过一个消息。然后图7的处理退出。[0084]当方框710处的测试具有否定结果时,则这是错误情况,因为对其而言用信号通知了处理完成的消息,假设该消息的流被锁定。方框720因此生成错误代码。此错误的处理可包括各种情况,诸如向错误日志写入记录、为操作员控制台响起警报等。然后图7的处理退出。
[0085]如上文已证明的,本发明的实施方式在执行在本文中被称为流的逻辑分组内的排序的同时,对来自消息队列的消息提供可缩放、并行(即,并发)处理的技术。因此能够遵守消息之间的依赖性。虽然本文中的讨论参考具有特定属性的消息排队系统,但本发明的实施方式不限于与此类排队系统一起使用。替代地,本发明的实施方式一般地可与任何排队系统一起使用,其提供某些能力以便(I)按顺序读取消息;(2 )按照任何顺序来完成那些消息的处理,包括不按顺序获取消息;以及(3)完成(提交)最初从其读取消息的不同线程上的消息的处理。
[0086]现在参考图8,根据本发明描述了数据处理系统的框图。数据处理系统800、诸如本文所述的处理设备中的一个处理设备可包括对称多处理器(“SMP”)系统或包括被连接到系统总线804的多个处理器802的其他配置。替换地,可采用单个处理器802。被连接到系统总线804的还有存储器控制器/高速缓存806,其提供到本地存储器808的接口。I/O桥810被连接到系统总线804,并提供到I/O总线812的接口。可利用I/O总线来支持一个或多个总线814和相应的设备,诸如总线桥、输入输出设备(“I/O”设备)、储存器、网络适配器等。还可以将网络适配器耦合到系统以使得数据处理系统能够通过中间私人或公共网络而耦合到其他数据处理系统或远程打印机或存储设备。
[0087]被连接到I/O总线的还有诸如图形适配器816、储存器818以及具有其上体现的计算机可用程序代码的计算机可用存储介质820之类的设备。可执行计算机可用程序代码以执行本发明的任何方面,如本文已描述的。
[0088]图8中所描述的数据处理系统可以是IBM系统p7系统、纽约州阿蒙克市的国际商用机器公司的产品,运行高级交互执行体(AIX7)操作系统。诸如Java之类的面向对象程序设计系统可与操作系统相结合地运行,并从在数据处理系统上执行的Java7程序或应用程序向操作系统提供调用。(“系统P”和“AIX”是国际商用机器公司在美国、其他国家或两者的注册商标。“Java”是Oracle America公司在美国、其他国家或两者的注册商标。)
[0089]所属【技术领域】的技术人员知道,本发明的各个方面可以实现为系统、方法或计算机程序产品。因此,本发明的各个方面可以体现为以下形式,即:完全的硬件实施方式、完全的软件实施方式(包括固件、驻留软件、微代码等),或硬件和软件方面结合的实施方式,这里可以统称为“电路”、“模块”或“系统”。此外,在一些实施方式中,本发明的各个方面还可以采取在一个或多个计算机可读介质中体现的计算机程序产品的形式,该计算机可读介质中包含计算机可读的程序代码。
[0090]可以采用一个或多个计算机可读介质的任意组合。计算机可读介质可以是计算机可读信号介质或者计算机可读存储介质。计算机可读存储介质例如可以是一但不限于——电、磁、光、电磁、红外线、或半导体的系统、装置或器件,或者任意以上的组合。计算机可读存储介质的更具体的例子(非穷举的列表)包括:具有一个或多个导线的电连接、便携式计算机盘、硬盘、随机存取存储器(RAM)、只读存储器(ROM)、可擦式可编程只读存储器(EPROM或闪存)、光纤、便携式紧凑盘只读存储器(CD-ROM)、光存储器件、磁存储器件、或者上述的任意合适的组合。在本文件中,计算机可读存储介质可以是任何包含或存储程序的有形介质,该程序可以被指令执行系统、装置或者器件使用或者与其结合使用。
[0091]计算机可读的信号介质可以包括在基带中或者作为载波一部分传播的数据信号,其中承载了计算机可读的程序代码。这种传播的数据信号可以采用多种形式,包括——但不限于——电磁信号、光信号或上述的任意合适的组合。计算机可读的信号介质还可以是计算机可读存储介质以外的任何计算机可读介质,该计算机可读介质可以发送、传播或者传输用于由指令执行系统、装置或者器件使用或者与其结合使用的程序。
[0092]计算机可读介质上包含的程序代码可以用任何适当的介质传输,包括一但不限于一无线、有线、光缆、RF等等,或者上述的任意合适的组合。
[0093]可以以一种或多种程序设计语言的任意组合来编写用于执行本发明操作的计算机程序代码,所述程序设计语言包括面向对象的程序设计语言一诸如Java、Smalltalk、C++等,还包括常规的过程式程序设计语言一诸如“C”语言或类似的程序设计语言。程序代码可以完全地在用户计算机上执行、部分地在用户计算机上执行、作为一个独立的软件包执行、部分在用户计算机上部分在远程计算机上执行、或者完全在远程计算机或服务器上执行。在涉及远程计算机的情形中,远程计算机可以通过任意种类的网络一包括局域网(LAN)或广域网(WAN) —连接到用户计算机,或者,可以连接到外部计算机(例如利用因特网服务提供者来通过因特网连接)。
[0094]下面将参照根据本发明实施方式的方法、装置(系统)和计算机程序产品的流程图和/或框图描述本发明。应当理解,流程图和/或框图的每个方框以及流程图和/或框图中各方框的组合,都可以由计算机程序指令实现。这些计算机程序指令可以提供给通用计算机、专用计算机或其他可编程数据处理装置的处理器,从而生产出一种机器,使得这些计算机程序指令在通过计算机或其他可编程数据处理装置的处理器执行时,产生了实现流程图和/或框图中的一个或多个方框中规定的功能/动作的装置。
[0095]也可以把这些计算机程序指令存储在计算机可读介质中,这些指令使得计算机、其他可编程数据处理装置、或其他设备以特定方式工作,从而,存储在计算机可读介质中的指令就产生出包括实现流程图和/或框图中的一个或多个方框中规定的功能/动作的指令的制造品(article of manufacture)0
[0096]也可以把计算机程序指令加载到计算机、其他可编程数据处理装置、或其他设备上,使得在计算机、其他可编程数据处理装置或其他设备上执行一系列操作步骤,以产生计算机实现的过程,从而使得在计算机或其他可编程装置上执行的指令能够提供实现流程图和/或框图中的方框中规定的功能/操作的过程。
[0097]附图中的流程图和框图显示了根据本发明的多个实施方式的系统、方法和计算机程序产品的可能实现的体系架构、功能和操作。在这点上,流程图或框图中的每个方框可以代表一个模块、程序段或代码的一部分,所述模块、程序段或代码的一部分包含一个或多个用于实现规定的逻辑功能的可执行指令。也应当注意,在有些作为替换的实现中,方框中所标注的功能也可以以不同于附图中所标注的顺序发生。例如,两个连续示出的方框实际上可以基本并发地执行,它们有时也可以按相反的顺序执行,这依所涉及的功能而定。也要注意的是,框图和/或流程图中的每个方框、以及框图和/或流程图中的方框的组合,可以用执行规定的功能或动作的专用的基于硬件的系统来实现,或者可以用专用硬件与计算机指令的组合来实现。
[0098] 虽然已描述了本发明的实施方式,但一旦本领域的技术人员获悉基本发明概念,其可想到那些实施方式中的附加变更和修改。因此,意图在于应将所附权利要求理解成包括所述实施方式和落在本发明的范围内的所有此类变更和修改。
【权利要求】
1.一种并发地处理来自消息队列的排队消息的流的计算机实现的方法,包括: 接收用以分配来自所述消息队列的排队消息以由线程处理的请求,所述排队消息属于已标识的消息流;以及 响应于确定属于已标识的所述消息流的另一消息当前不在被处理,分配所述排队消息以用于由所述线程处理。
2.根据权利要求1所述的方法,其中所述消息流是通过评估指定如何标识所述消息流的至少一个准则而被标识的。
3.根据权利要求1或权利要求2所述的方法,其中所述请求包括所述排队消息的标识符和已标识的所述消息流的名称。
4.根据任何前述权利要求所述的方法,还包括: 响应于确定属于已标识的所述消息流的另一消息当前正在被处理,分配所述排队消息中的不同的一个排队消息以由所述线程处理,所述不同的排队消息属于不同的消息流。
5.根据权利要求4所述的方法,还包括: 响应于分配所述排队消息中的所述不同的排队消息,在记录关于被阻止消息的信息的数据结构中存储关于对其而言接收到所述请求的所述排队消息的信息;以及 随后评估所述数据结构中存储的所述信息,以确定对其而言接收到所述请求的所述排队消息是否能够被解除阻止、并作为所述排队消息中的所述不同的排队消息而被分配给不同线程以由所述不同线程处理。
6.根据权利要求5所述的方法,其中响应于确定属于已标识的所述消息流的所述另一消息当前不再被处理,所 述请求能够被解除阻止。
7.根据权利要求6所述的方法,其中所述数据结构中的条目被评估以在所述不同的线程检查所述排队消息的下一排队消息之前分配给所述不同的线程,从而对所述排队消息中的先前被阻止但现在被解除阻止的排队消息给予优先权以分配给所述不同的线程。
8.根据权利要求1所述的方法,其中确定属于已标识的所述消息流的另一消息当前不在被处理包括:确定已标识的所述消息流当前未被锁定。
9.根据权利要求1所述的方法,还包括: 响应于确定属于已标识的所述流的另一消息当前不在被处理,执行: 如果当前处理消息的线程的计数加当前处于所述等待状态的线程的计数小于活跃线程的总数,使得所述线程进入等待所述另一消息结束的等待状态,且然后分配所述排队消息以用于由所述线程处理;以及 否则分配所述线程以处理所述排队消息中的不同的排队消息。
10.根据权利要求9所述的方法,其中所述排队消息中的所述不同的排队消息是通过查阅一数据结构来选择的,所述数据结构标识所述排队消息中的先前已被评估以分配给不同线程、但未被分配给所述不同线程的排队消息。
11.一种用于并发地处理来自消息队列的排队消息的流的系统,包括: 计算机,包括处理器;以及 指令,使用所述处理器来可执行以实现功能,所述功能包括: 接收用以分配来自所述消息队列的排队消息以由线程处理的请求,所述排队消息属于已标识的消息流;以及响应于确定属于已标识的所述消息流的另一消息当前不在被处理,分配所述排队消息以用于由所述线程处理。
12.根据权利要求11所述的系统,其中: 所述消息流是通过评估指定如何标识所述消息流的至少一个准则而被标识的;以及 所述请求包括所述排队消息的标识符和已标识的所述消息流的名称。
13.根据权利要求11或权利要求12所述的系统,其中所述功能还包括: 响应于确定属于已标识的所述消息流的另一消息当前正在被处理,分配所述排队消息中的不同的排队消息以由所述线程处理,所述不同的排队消息属于不同的消息流。
14.根据权利要求13所述的系统,其中所述功能还包括: 响应于分配所述排队消息中的所述不同的排队消息,在记录关于被阻止消息的信息的数据结构中存储关于对其而言接收到所述请求的所述排队消息的信息;以及 随后评估所述数据结构中的存储的所述信息,以确定对其而言接收到所述请求的所述排队消息是否能够被解除阻止、并作为所述排队消息中的所述不同的排队消息而被分配给不同线程以由所述不同线程来处理,其中所述请求能够响应于确定属于已标识的所述消息流的所述另一消息当前不再被处理而被解除阻止。
15.根据权利 要求14所述的系统,其中所述数据结构中的条目被评估以在所述不同的线程检查所述排队消息的下一排队消息之前分配给所述不同的线程,从而对所述排队消息中的先前被阻止但现在被解除阻止的排队消息给予优先权以分配给所述不同的线程。
16.根据权利要求11所述的系统,其中确定属于已标识的所述消息流的另一消息当前不在被处理包括:确定已标识的所述消息流当前未被锁定。
17.一种用于并发地处理来自消息队列的排队消息的流的计算机程序产品,所述计算机程序产品包括: 计算机可读存储介质,具有体现在其中的计算机可读程序代码,所述计算机可读程序代码被配置成用于: 接收用以分配来自所述消息队列的排队消息以由线程处理的请求,所述排队消息属于已标识消息流;以及 响应于确定属于已标识的所述消息流的另一消息当前不在被处理,分配所述排队消息以由所述线程处理。
18.根据权利要求17所述的计算机程序产品,其中: 所述消息流是通过评估指定如何标识所述消息流的至少一个准则来标识;以及 所述请求包括所述排队消息的标识符和已标识的所述消息流的名称。
19.根据权利要求17所述的计算机程序产品,其中所述计算机可读程序代码还被配置成用于: 响应于确定属于已标识的所述消息流的另一消息当前正在被处理,分配所述排队消息中的所述不同的排队消息以由所述线程处理,所述不同的排队消息属于不同的消息流。
20.根据权利要求19所述的计算机程序产品,其中所述计算机可读程序代码还被配置成用于: 响应于分配所述排队消息中的所述不同的排队消息,在记录关于被阻止消息的信息的数据结构中存储关于对其而言接收到所述请求的所述排队消息的信息;以及随后评估所述数据结构中存储的所述信息,以确定对其而言接收到所述请求的所述排队消息是否能够被解除阻止、并作为所述排队消息中的所述不同的排队消息而被分配给不同线程以用于由所述不同线程来处理,其中所述请求能够响应于确定属于已标识的所述消息流的所述另一消息当前不再被处理而将被解除阻止。
21.根据权利要求20所述的计算机程序产品,其中所述数据结构中的所述条目被评估以在所述不同的线程检查所述排队消息的下一排队消息之前分配给所述不同的线程,从而对所述排队消息中的先前被阻止但现在被解除阻止的排队消息给予优先权以分配给所述不同的线程。
22.根据权利要求17所述的计算机程序产品,其中确定属于已标识的所述消息流的另一消息当前 不在被处理包括:确定已标识的所述消息流当前未被锁定。
【文档编号】H04L12/863GK103814557SQ201280045928
【公开日】2014年5月21日 申请日期:2012年9月4日 优先权日:2011年9月23日
【发明者】J·霍塞, J·里夫 申请人:国际商业机器公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1