代码之家  ›  专栏  ›  技术社区  ›  farinspace MikeAr

什么是队列访问并发解决方案?

  •  0
  • farinspace MikeAr  · 技术社区  · 17 年前

    我试图找出实现队列系统的困难。我知道如何实现一个基本队列,因此我将用一些背景介绍一下我所追求的目标:

    我将实现一个队列,在其中放置消息,这将来自多个用户,消息将被安排在用户定义的时间发布(允许多次出现,精确到分钟,从用户界面的角度来看,我将限制:“每分钟或每小时”出现,但我希望系统仍然是能够处理这个)。

    这就是我的问题所在: 最终,我可能会遇到这样的情况(可能不是这样),在当前时间需要发布许多消息,我希望运行多个进程(脚本的多个实例),一次从队列中获取[x,10,25]个消息并处理它们。问题是:如何做到这一点,以便每个实例处理唯一的消息(而不处理已经由另一个实例处理的消息)?我担心当前的连接,如何锁定记录,以及其他我可能没有想到的事情。

    我将使用的技术是php和mysql。我正在寻找以上的一些解决方案,我应该在我的搜索中使用的术语,真实世界的例子,想法,评论和想法?

    谢谢大家!

    我遇到的一个解决方案是使用亚马逊简单队列服务…它承诺独特的消息处理/锁定 http://aws.amazon.com/sqs/

    4 回复  |  直到 17 年前
        1
  •  5
  •   Vilx-    17 年前

    好吧,我会这样做的:

    为消息创建表,再添加两个字段-“进程ID”和“进程时间”。这些将在后面解释。

    给每个进程一个唯一的ID。它们可以在启动时生成它(如guid),或者您可以自己分配它们(然后您可以更容易地将它们区分开来)。

    当一个进程想要获取一堆消息时,它会这样做:

    1. UPDATE messages SET process_id=$id, process_time=now() where process_id is null LIMIT 20
    2. 从消息中选择*,其中process_id=$id

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

    update语句应该是非常原子的,特别是使用innodb时,它会自动将每个这样的语句包装在事务中。MySQL应该处理所有的并发性。

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

        2
  •  1
  •   Shiraz Bhaiji    17 年前

    你可以扭转这个问题。

    而不是同时把事情从队列中拿出来。一旦你得到了所有的信息,就发布它。 但是 用一个规则发布它,直到某个时间它才被显示出来。这样做可以帮助您避免锁定/争用问题。

        3
  •  1
  •   Sander Marechal    17 年前

    看看 Beanstalkd 消息队列。它有PHP客户端。Beanstack的一个好特性(与Dropr相反)是您可以延迟消息。也就是说,您可以将消息发送到队列,直到x秒过去,它才会被传递到客户机。

    不过,beanstack有一个很大的缺点:它是内存队列。这意味着如果它(或您的机器)崩溃,那么队列是空的,内容也会丢失。持久性是为下一个版本的beanstack计划的一个特性。

        4
  •  0
  •   Alfred    17 年前

    一些在线解决方案:

    1. Amazon SQS .
    2. Google appengine queue system

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

    我还考虑在php/mysql中实现队列,并考虑使用:

    1. MySQL get_lock 实现某种锁。
    2. 把队列放到mysql中 memory heap 数据存储,因为内存队列比磁盘队列快得多。但是,当计算机崩溃时,您有丢失数据的风险。
    3. 使用 named pipes 与过程沟通。
    推荐文章