0

我试图找出实现队列系统的困难。我知道如何实现一个基本队列,所以我将解释一下我所追求的一些背景:

我将实现一个放置消息的队列,这将来自多个用户,消息将安排在用户定义的时间发布(允许以分钟为精度多次出现,从 UI 的角度来看,我将限制:“每分钟或每小时”发生,但 id 喜欢系统仍然能够处理这个)。

这是我的问题所在:最终我可能会处于当前需要发布许多消息的情况(也可能不是),我希望运行多个进程(脚本的多个实例)来获取一次来自队列的 [x,10,25] 条消息并处理它们。问题是:如何做到这一点,以便每个实例处理唯一的消息(不处理已经被另一个实例处理的东西)?我担心当前的连接、如何锁定记录以及我可能没有考虑的其他任何事情。

我将使用的技术是 PHP 和 MySQL。我正在寻找上述问题的一些解决方案,我应该在搜索中使用的术语,现实世界的例子,想法,评论和想法?

谢谢大家!

我遇到的一种解决方案是使用 Amazon Simple Queue Service ...它承诺独特的消息处理/锁定http://aws.amazon.com/sqs/

4

4 回答 4

5

好吧,我会这样做:

为消息制作表格并添加另外两个字段 - “PROCESS_ID”和“PROCESS_TIME”。这些将在后面解释。

给每个进程一个唯一的 ID。他们可以在启动时生成它(如 GUID),或者您可以自己分配它们(然后您可以更轻松地区分它们)。

当一个进程想要获取一堆消息时,它会执行以下操作:

  1. UPDATE messages SET process_id=$id, process_time=now() where process_id is null LIMIT 20
  2. SELECT * FROM messages WHERE process_id=$id

这将找到 20 条“免费”消息并“锁定”它们。然后它会找到它锁定的消息并处理它们。处理完每条消息后,DELETE它。

UPDATE 语句应该是非常原子的,特别是如果您使用 InnoDB,它会自动将每个此类语句包装在事务中。MySQL 应该处理那里的所有并发性。

PROCESS_TIME 字段是可选的,但您可以使用它来查看进程何时挂起。如果消息被锁定的时间过长,您可以断定出现问题并进行调查。

于 2009-07-04T18:26:33.240 回答
1

你可以扭转问题。

而不是同时将事情从队列中取出的问题。获得所有信息后立即发布。但是发布它的规则是它在特定时间之前不可见。以这种方式做事可以帮助您避免锁定/争用问题。

于 2009-07-04T18:55:46.127 回答
1

查看Beanstalkd消息队列。它有 PHP 客户端。Beanstalkd 的一个很好的特性(与例如 dropr 相对)是您可以延迟消息。也就是说,您可以将消息发布到队列中,并且在 X 秒过去之前它不会被传递到客户端。

Beanstalkd 确实有一个很大的缺点:它是一个内存队列。这意味着如果它(或您的机器)崩溃,则队列为空并且内容丢失。持久性是为下一个版本的 beanstalkd 计划的功能。

于 2009-07-06T07:25:22.743 回答
0

几个在线解决方案:

  1. 亚马逊 SQS
  2. 谷歌appengine队列系统

我猜谷歌的解决方案要便宜得多(如果不使用的话,甚至可以免费)。

我也一直在考虑在 PHP/MYSQL 中实现队列并考虑使用:

  1. mysql get_lock来实现某种锁。
  2. 将队列放在 MYSQL内存堆数据存储中,因为内存队列比磁盘队列快得多。但是当计算机崩溃时,您有丢失数据的风险。
  3. 使用命名管道与进程通信。
于 2009-07-04T18:29:35.233 回答