一次全栈,一生全栈。
消息队列
最终我们需要一个可以保证「消息至少到达一次」的东西。那么自然的,我们需要引入一个正经的消息队列服务。
所以我就来到了北京选择了 RabbitMQ. 对应地选择了 AMQP 0-9-1.
所谓正经的消息队列和 Redis 的 PUB/SUB 的主要不同点在于前者可以保证消息至少送达一次;而后者只保证消息至多送达一次。 在一些场景下,我们可能会需要不漏任何消息.
在 AMQP 中,消息的传递由两个组件进行:Exchange 和 Queue. 消息产生者将消息发给 Exchange, 再由 Exchange 转发到对应的 Queue 内。Exchange 有三种类型:Direct, Fanout 和 Topic. Direct Exchange 的作用是直接将接收到的消息转发到由路由键指定的 Queue 内;Fanout Exchange 则是将收到的任何消息都复制一份到所有的 Queue 内;Topic Exchange 则为典型的 Pub/Sub.
保证消息至少送达一次的方法则是引入消息确认机制。当消费者从 Queue 中取出消息后,这个消息必须由消费者进行确认后才会从 Queue 中移除。对于那些未被确认的消息,队列可能会重试投递直到消息过期。
连接去耦合
在上一篇,我们提到了一些与底层结合紧密的状态是难以去耦合的。所以我们需要将这一部分做得尽量的小。那么,使用一种方法将连接状托管起来就成了一种必要。这种将状态托管给外部的方法虽然说有点作弊的感觉,但是毕竟我们也知道一个典型的应用程序有三层:状态层、逻辑层和表示层。逻辑层和表示层通常是可以做成无状态的,但这是因为将状态托管给了状态层,而不仅仅是因为逻辑和表示本身是无状态的。
那么,结合上面的消息队列,对连接进行托管就非常简便了。同时,消息队列本身也可以提供一定程度的负载均衡,做横向扩展也比较方便。
但比较成问题的是,所有的有状态的程序想要进行扩展都是不太好搞的。所以这个部分仍然需要继续完善。
Your comments will be submitted to a human moderator and will only be shown publicly after approval. The moderator reserves the full right to not approve any comment without reason. Please be civil.