作者回复: 谢谢你的答案,观点基本我都是赞同的!
作者回复: 谢谢你的留言提问!个人觉得即便公司会开发自己的MQ,很多都是建立在这些开源项目之上的。一方面可能因为开源项目的一些属性并不能满足到自身的应用场景,所以加以改进。另一方面如果是大厂的话,可以打造出自己的一套生态圈,开发接口更加适合内部使用。
作者回复: 哈哈哈,感觉你的基本功很扎实啊,那这一讲你可以当作是复习章节,当然也可以留言和我讨论更高级的内容。我的专栏也希望能对初学者友好一点,对于初学者来说,这一讲是全新的内容呢。
作者回复: 谢谢你的留言!总结得很到位啊!
作者回复: 你好呀,感谢你的提问!
其实在观察者模式下,你也可以通过消息队列去传递消息。但是更本质的区别是在观察者模式下,观察者必须知道被监听者的存在。就像例子所示,观察者必须调用被监听者的接口。而发布/订阅模式下,两者是解耦的,互相都不用知道对方的存在。
消息队列中既可以使用push模式也可以使用pull模式,关键在于应用场景的考虑。例如如果消息跟新发布频繁,而下游的接收者能够处理的qps不高,那可能会更加倾向于采取pull模式。
作者回复: 谢谢你的留言提问!一般来说,这种发送机制叫做at least once delivery,这种情况需要消费者自身具备Idempotency,也就是幂等性。消费者需要自己知道哪些消息是duplicate的,从而知道怎么处理这些重复消息。
作者回复: 谢谢你的答案!分析得很详细,基本上我都是赞同的!
作者回复: 谢谢你的提问!这个看你的设计了,即便真的使用发布订阅模式的话,同一个队列的消费者可以通过设置filter来只接收自己感兴趣的内容。
作者回复: 谢谢你的提问!这个问题挺常见的,PubSub肯定是可以做到的。具体的做法还是看你的架构吧。如果你是own整一套系统的话,一种做法是你的service直接对这两个数据库进行dual write。如果你只是own这两个database的话,我相信Oracle应该是有一些database change notification的机制,这个时候你可以将这个data change publish到一个service中,然后再做同步。
作者回复: 谢谢你的提问!如果我没理解错你的问题的话,你是想问接收方是否回复了10000、10001和10003这三个Log offset对吧?是的,接收的log offset有10003。因为消息队列需要接收到连续的log offset才会判定接收方接收到消息,这里因为log offset从10002断开了,所以消息队列会认为接收方从10002开始往后的消息都没有接收到。
作者回复: 涵你好,谢谢你的留言与提问!
第一个问题,一般不同的系统有不同的机制去确定消息队列中消息会被保存多久。像Apache Kafka中可以通过设定Retention Period来确定消息被保存多久,甚至可以设置Retention Period为Forever来永久保存。
第二个问题,只要没有超过保留期,消息会一直保存在队列并且一直尝试发送给第五个订阅者。当然订阅者也可以自己设定retry times,如果第五个订阅者告诉消息队列只需要重试一次,那这条消息就不会再发送给第五个订阅者了。如果你要保证操作一定成功,就要考虑用RPC来调用了。
第三个问题还是要看系统设计了,设计上收到与不收到都可以做到,像Apache Kafka可以通过重设Log Offset的位置去实现新的订阅者收取队列里面旧的消息。如果你使用开源项目的话,文档里应该会有说明的。
作者回复: 谢谢你的答案!
作者回复: 谢谢你的留言!我觉得本质上还是有所不同的,毕竟在观察者模式中观察者需要知道被监听的对象,而发布/订阅模式通过消息队列解耦了这一层关系。
作者回复: 谢谢你的留言和分享!总结得不错啊!
作者回复: 啊哈哈,谢谢你的支持啊,同时也谢谢你的建议!
作者回复: 谢谢留言!总结得不错啊!不过消息队列也不一定是可靠性送达的,在一些极端的情况下也是有可能出现丢包。