美文网首页System Design
系统设计基础3:异步执行和消息队列

系统设计基础3:异步执行和消息队列

作者: MeazZa | 来源:发表于2019-03-19 20:42 被阅读0次

    本文将主要介绍系统设计中的异步执行和消息队列。这里假设读者已经有了一部分这方面的知识,一些概念的介绍不会过于深入,而会将重点放在各种实现方式的优劣比较上。

    异步执行

    客户端和服务器端的交互方式通常有两种:同步执行和异步执行。其中互联网应用普遍采用的是异步执行,异步执行可以极大的提高系统的处理能力。

    以下为两种交互方法的示意图:

    同步执行的方式 异步执行的方式

    不要使用数据库

    采用异步执行的方式,需要至少在客户端维护一个消息列表,接收由客户端发送来的消息。这个消息列表很容易的可以想到由数据库来实现,在数据库中记录每条消息本身及其状态,服务器端从数据库中获取待执行的任务并执行,同时进行消息的状态的更新。

    但我们说,数据库并不适合异步处理的场景。原因有以下三点:

    1. 需要频繁读数据库。服务器端需要以一个固定的时间间隔,不断从数据库中获取新的消息。如果间隔设置的很小,将在数据库中产生大量的查询请求,会影响数据库对写入和更新的处理;如果间隔设置的较大,会给异步执行带来一定的处理延迟,对延迟敏感的系统来说是影响很大的。

    2. 手动清理。对于已经处理过的消息,是需要清理掉的。因此又需要定期对数据库进行删除操作,增加了数据库的负担。

    3. 可扩展性不佳。如果消息量过大,数据库性能下降时,扩展的工作将会很复杂。

    需要特殊注意的是,PostgreSQL是提供对异步执行的支持的,也是通过消息队列的方式,因此对于少量或中等的消息量来说,是可以用PostgreSQL的。

    消息队列

    消息队列是连接消息发送方和消费方的中间件,它的几个特点是:

    • 可以处理海量的并发消息;
    • 消息通知采用推送的方式,而不是定期拉取的方式;
    • 消息持久化,服务中断时消息不会丢失;
    • 过期消息会自动清理;
    • 不用担心死锁和竞态的问题。
    消息队列示意图

    消息队列的一大特点是消息的拓扑结构可以任意设计,比如一个topic可以对应1个consumer,或多个consumer,如下图所示。

    消息队列的应用模型
    消息队列协议

    消息队列协议,随着协议的发展出现了很多,比如STOMP、AMQP、JMS等,其中AMQP是出现的比较晚的,相对技术更先进一些。由于不是本文的重点,这里不展开介绍了。

    消息队列协议
    消息队列中间件的选择

    目前开源的消息队列有RabbitMQ、ActiveMQ等,它们除了协议不同外,在实际使用时并没有明显的选择倾向性。通常来说,ActiveMQ和JVM的结合性更高,适合于Java应用;RabbitMQ适合于Ruby、Python的应用。

    消息队列除了做系统间的通信外,还可以作为系统内部的任务队列,实现任务的异步执行。此时选择哪种消息队列,更多的考虑的是消息队列的轻量级、易使用和易维护等方面。

    小结

    本文介绍了在异步执行中进行消息通信的方式,使用数据库的方式在许多场景并不是最好的,但在一些消息量小的情况也是可以使用的,更通用的做法是使用消息队列的方式,消息队列本身的特性,为异步执行提供了很多支持。

    欢迎大家订阅专题,其中包含了系统设计基础系列的全部文章:System Design

    • 参考文献:
    1. http://blog.codepath.com/2012/11/15/asynchronous-processing-in-web-applications-part-1-a-database-is-not-a-queue/
    2. http://blog.codepath.com/2013/01/06/asynchronous-processing-in-web-applications-part-2-developers-need-to-understand-message-queues/

    相关文章

      网友评论

        本文标题:系统设计基础3:异步执行和消息队列

        本文链接:https://www.haomeiwen.com/subject/qxanmqtx.html