Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | 51CTO学院 | CSDN程序员研修院 | OSChina 博客 | 腾讯云社区 | 阿里云栖社区 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏多维度架构

2.17. 多维度架构之消息队列

2.17.1. 你是怎样使用消息队列的?

十有八九的人是这样理解消息队列的,一段生产消息,另一端消费消息。多用于批量执行或者发送通知。

2.17.2. 你是否真正理解了消息队列?

2.17.2.1. 消息队列并不是实时的

消息队列并不是实时的,它不能替代传统 TCP/UDP Socket 通信。

			
消息生产者 —> 消息队列服务器 —> 消息消费者			
			
			

消息队列中有 Switch (交换机) 的概念,事实上消息队列的工作方式的确跟网络交换机类似,网络交换机是TCP/UDP包的接收存储和转发,消息队列是消息的存储与转发。

从生产者到达消费者是有延迟的,尤其是多个生产者持续生产和多个消费者持续消费,消息服务器会出现瓶颈,消息会出现堆积情况,这时消息的生产和消费都会出现延迟,且时间不可控。

类似消息通知这种需求,是非实时的需求,不考虑发送延迟和达到时间,可以使用消息队列解决方案,否则还是使用 TCP Socket。

2.17.2.2. 不能替代异步执行

当使用消息队列替代异步执行的时候也会出现前面所说的执行时间不可控。所以不是所有场景都适合使用消息队列的,更多时候我们开启一个线程去异步执行效果可能更好。

2.17.3. 使用的合理吗?

我曾经接手一个项目,这个项目中用户注册发送手机验证码和邮箱验证码使用了消息队列记录,真实让人哭笑不得,为了使用消息队列而使用消息队列。

2.17.4. 是否有必要使用消息队列?

两个团队分别负责商品信息和价格还有库存功能模块的开发,商品信息是静态化方案,商品价格和库存是AJAX动态载入,公司重金从杭州淘宝挖了一名架构师,并给了首席架构师的头衔。

最终架构师给出的方案,更新商品信息时,后通过 ActiveMQ 通知刷新缓存更新价格和库存,这样的方案是否可行?我认为是可有可无,这个方案中消息队列并不是刚需。

出现了 这个需求是因为,商品促销需要经常调整价格和库存量。修改商品信息这个后台运营的操作,这种操作分成两类,一类是临时单品调价,另一类是批量调价。

我想问是否有必要更新商品价格?换个思路可以吗?是否还有其他更好的方案?

这里还有一个故事,于是促销需要,商品需要统一调价,程序猿给了一条SQL:

		
update goods set price=price+10 where category_id = xxx
		
		

高薪聘用的 DBA 竟然执行了,然后就悲剧了。

让我们换个思路去解决这个问题,我们专门来建一个促销打折表 discount 用来存储需要做促销的商品:

		
+----------------------------------------+
| discount                               |
+----------------------------------------+
| Id | goods_id | price  | ctime | mtime |
+----------------------------------------+
| 1  | 100      | + 12.5 | xxx   | xxx   |
| 2  | 101      | - 0.5  | xxx   | xxx   |
+----------------------------------------+
		
		

当前价格 = 商品价格 + 折扣价格

相比 goods 表 discount 的数据量是非常小的,这样一来就无需异步执行,商品调价在Service 直接更新discount 表即可,刷新缓存也不过是一行代码,删除 cache key 在一个实例中完成原子性更好。

2.17.5. 最后总结

就如上面所说的更新商品信息需求,增加了消息队列之后,开发复杂了,测试复杂了,运维复杂了,监控复杂了,出现故障排查时间变长了。

架构设计中我们应该收缩技术栈,做减法,而不是做加法,强上消息队列?