系统可扩展设计方法之消息队列
消息队列在现在各种系统中都有广泛的应用,除非你做的就是一个单独的工具或小软件, 否则稍大点的系统都会用到消息队列,它对系统的可扩展性很重要。它基于这样的事实,如果系统的各个模块之间的协作不是通过直接的调用关系来实现的,那么系统的可扩展性就一定会更好。
系统各个模块之间只是通过消息队列来传输事件消息,而各模块之间并没有直接的调用关系、保持松散的耦合关系。
事件驱动架构最典型的一个应用就是操作系统中常见的生产者和消费者模式,将其应用到网站设计中就是分布式消息队列。
分布式消息队列同样采用了生产者和消费者模式:
- 消息的发送者负责将消息发布到消息队列中,也就是「生产者」;
- 另外,系统中会有一个或者多个消息接收者订阅消息,订阅目的是为了获取消息并进行处理,这里的消息订阅者其实就是「消费者」。消息接收者发现消息队列中有新的消息后,就会立马对其进行处理。
可以看到,在这种模式下,消息的发送者和接收者之间并没有任何直接的联系,是松耦合的。它们的协作是通过消息队列这个「中间人」进行的。消息的发送者将消息发送至消息队列后,就结束了对消息的处理,而消息的接收者只是从消息队列中获取消息进行后续的处理,并不需要知道这些消息从哪里来,因此可以很方便的实现高可扩展性。
所以,采用这种模式的话,当网站需要增加新功能的时候,只要增加对应的新模块,再由对此模块感兴趣的「消费者」进行订阅,就可以实现对原有系统功能的扩展了,而对原本的系统模块本身并没有影响。
![](https://pic4.zhimg.com/80/v2-13baedfd3f262c91ea8875b4d0080793_hd.jpg)
引入了消息队列后,不仅可以提高系统的可扩展性,还可以再一定程度上改善网站架构的高性能、高可用性和可伸缩性。
- 从性能方面来看,消息发送者不需要等接收者实际处理完成后才返回,也就是从原本的同步处理变成了异步处理,所以用户会感知到网站性能的提升。
- 从高可用方面来看,假如消息的接收者模块发生了短时间的故障,此时并不会影响消息发送者向消息队列中发送消息,等到消息接收者模块恢复后可以继续后续的处理,只要这段时间内消息队列本身没有被塞满而出现消息丢失的情况。从整体角度看,系统并不会感知到消息接收者模块曾经发生过短暂故障,也就相当于保证了系统的高可用。
- 从可伸缩性方面来看,消息队列的核心其实就是一个无状态的存储。所以,当系统需要能够保留更多的消息时,通过简单的增加存储空间就可以实现。尤其是,大规模的电商网站来更会将消息队列扩展成为分布式消息队列集群,来实现消息队列的可伸缩性。
引入消息队列后,测试人员需要额外关注的点。
- 从构建测试数据的角度来看,为了以解耦的方式测试系统的各个模块,需要在消息队列中构造测试数据。这也是为什么很多互联网的自动化测试框架中都会集成有消息队列写入工具的主要原因。
- 从测试验证的角度来看,不仅需要验证模块的行为,还要验证模块在消息队列中的输出是否符合预期。为此,互联网的自动化测试框架中也都会集成消息队列的读取工具。
- 从测试设计的角度来看,需要考虑消息队列满、消息队列扩容等情况下系统功能是否符合设计预期。
- 除此之外,还需要考虑,某台消息队列服务器宕机的情况下,丢失消息的可恢复性以及新的消息不会继续发往宕机的服务器等等。