时长:大小10.46M
作者回复: 总结到位,赞👍。
作者回复: 首先redis肯定是不适合存消息的,虽然redis性能很好,但那是和主流的数据库比,一般大概能到几万tps左右;而现代的消息队列都能很轻松的做到几十万tps级别的性能。
消息量特别大的时候,需要考虑使用有消息堆积能力的MQ,因为一旦消费慢,大量消息就会堆积到MQ中,这种情况不太适合用RabbitMQ,可以考虑RocketMQ、Kafka和Pulsar。
作者回复: 如果你说的共享内存指的是PageCache,很多消息队列都会用到,RDMA据我所知常见的几种消息队列应该都还没有使用,像Kafka它在消费的时候,直接使用Zero Copy,数据直接从PageCache写到NIC的缓冲区中,都不需要进入应用内存空间。
另外,现代的消息队列瓶颈并不在本机内存数据交换这块,主要还是受限于网卡带宽或者磁盘的IO,像JMQ、Kafka这些消息队列,都可以打满万兆网卡或者把磁盘的读写速度拉满。
作者回复: 如果计数只是为了控制流量,没必要那么精确。
如果计数是业务需求必须要求准确,简单一点的话,可以使用Redis的INCR命令来计数,这个是可以保证原子性的。Redis性能要是不能满足要求,也可以用Kafka+flink集群来解决。这两种方案都是可以保证完全准确计数的。
另外,计数不准的问题,并不一定是计数模块本身的问题,还要查一下是不是系统的其它部分有bug,导致重复计数或者漏计。
作者回复: 对于网关某一个处理前端请求线程来说,大致的流程是:
0.收到Request
1.发消息
2.阻塞等待,直到超时或者收到后端的秒杀结果;
3.返回Response
作者回复: 是的,令牌桶可以用消息队列实现,也可以用Redis实现,你也可以写一个简单的令牌桶服务,原理是一样的。
作者回复: 总结的很赞!
作者回复: 总结的非常到位!
作者回复: A1:实际上,只要有足够的磁盘容量,消息队列确实可以存放无限的消息。像秒杀请求这种数据,峰值并发高,但总数据量并不是很大,所以,堆积在消息队列中完全没问题。
A2:都按照秒杀失败处理即可。
A3:响应一般采用RPC来实现。超时或者返回秒杀结果之前,网关和APP确实要保持连接,这是HTTP协议决定的。至于网关能不能承受海量的APP连接,这个应该不用担心,网关的作用就是用来抗海量连接的,它也会有各种方法来解决这个问题。
4、是的,大部分生产系统中的消息队列要配置成集群,确保可用性和数据可靠性,这个后面的课程我们会讲。
作者回复: 你买不了吃亏,买不了上当,买到的只有知识。
作者回复: 这个取决于网关是如何实现的。大致的思路是,网关会把用户的request缓存起来,然后发消息,至于发的消息内容不一定就是这个原封不动的request对象,只要把Request中必要的信息发给后端就可以了。
后端服务可以用RPC通知网关秒杀结果,网关收到结果后找到对应的Request来构建Response返回即可。
作者回复: 这个就是比较细节的问题了,实现的方式也可以有多种,比如:在消息中带一个请求时间戳,后续服务在处理前先检查一下是否已经超时,超时就直接丢掉不处理。
作者回复: 涉及到钱的系统,数据可靠性是最先需要考虑的问题。
作者回复: 限流的方法有很多,当然不止令牌桶。令牌桶的优势是实现简单,易于控制。
作者回复: 一个主题设置多个分区,每个分区代表一个优先级。
发送的时候,根据优先级指定分区发送到对应的分区上。
消费的时候,按照优先级从高到低,指定分区消费。
作者回复: 是的,很多公司会用消息队列来做异构数据库之间的数据同步,但是一定要注意顺序问题。像MySQL Binlog这种,是要求严格有序的,否则会出现问题。
作者回复: 总结的很到位,加油!
作者回复: 异地容灾是个比较难解决的问题。
我的经验是:绝大部分主题是不需要异地容灾的,因为消息队列不会直接堆外提供服务,它直接服务都是机房内部的应用,当出现整个机房大面积断电或者机房外网中断的时候,消息的生产者本身已经不能提供服务了,这时候消息队列的容灾是没有意义的。如果生产者它本身支持异地容灾能自动把服务迁移到其它机房,那这个应用在其它机房的实例使用本机房内的消息队列就行了,也不需要消息队列做异地复制和容灾。
但是,确实有极少数应用比较特殊,它是有异地容灾的需求的,我们目前的方案是多副本分布在多个机房中,配合就近消费来实现。