• 小伟
    2019-07-24
    个人的体会,消息队列的本质是将同步处理转成异步处理,异步会带来相应的好处,但也有弊端。
    Pros:
    1.可在模块、服务、接口等不同粒度上实现解耦
    2.订阅/消费模式也可在数据粒度上解耦
    3.可提高系统的并发能力,集中力量办大事(同步部分),碎片时间做小事(异步部分)
    4.可提高系统可用性,因为缓冲了系统负载

    Cons:
    1.降低了数据一致性,如要保持强一致性,需要高代价的补偿(如分布式事务、对账)
    2.有数据丢失风险,如宕机重启,如要保证队列数据可用,需要额外机制保证(如双活容灾)

    总体来说,消息队列的适用场景还是很多的,如秒杀、发邮件、发短信、高并发订单等,不适合的场景如银行转账、电信开户、第三方支付等。关键还是要意识到消息队列的优劣点,然后分析场景是否适用则会水到渠成。
    展开

    作者回复: 总结到位,赞👍。

     8
     64
  • beiler
    2019-07-25
    还有个问题,如果消息量特别大的时候,消息是适合存在到redis中还是适合存到rabbitmq中?必定您在文中提到一个词,小仓库,如果货量大了怎么办?

    作者回复: 首先redis肯定是不适合存消息的,虽然redis性能很好,但那是和主流的数据库比,一般大概能到几万tps左右;而现代的消息队列都能很轻松的做到几十万tps级别的性能。

    消息量特别大的时候,需要考虑使用有消息堆积能力的MQ,因为一旦消费慢,大量消息就会堆积到MQ中,这种情况不太适合用RabbitMQ,可以考虑RocketMQ、Kafka和Pulsar。

     4
     25
  • 游弋云端
    2019-07-24
    是否可以利用共享内存、RDMA加速消息队列的性能,老师在这块有没有实践经验?

    作者回复: 如果你说的共享内存指的是PageCache,很多消息队列都会用到,RDMA据我所知常见的几种消息队列应该都还没有使用,像Kafka它在消费的时候,直接使用Zero Copy,数据直接从PageCache写到NIC的缓冲区中,都不需要进入应用内存空间。

    另外,现代的消息队列瓶颈并不在本机内存数据交换这块,主要还是受限于网卡带宽或者磁盘的IO,像JMQ、Kafka这些消息队列,都可以打满万兆网卡或者把磁盘的读写速度拉满。

     4
     16
  • 白小白
    2019-07-23
    现在用的消息队列主要是做数据异步传输用的,之前也做过多个系统之间的解耦。看到用消息队列做秒杀系统,忽然想到之前只想过用redis去做,利用redis去做了流量的把控。不过细想想,这种情况下的redis和文章中的令牌桶很像……

    作者回复: 是的,令牌桶可以用消息队列实现,也可以用Redis实现,你也可以写一个简单的令牌桶服务,原理是一样的。

     1
     14
  • mhswordman
    2019-07-23
    生产项目中用到了kafka,
    1 异部的处理交易:提高用户请求的响应速度,同时也提升了用户的体验感。
    2 削峰 :保护服务器的一种方式,用户的请求放到kafka中,交易服务根据自己服务器的消费能力来消费交易数据。
    3 项目的解耦:交易服务和后续的服务之间是通过Kafka进行交付,当一个服务为多个服务提供数据的时候,可以通过MQ进行交换来解耦服务间的耦合。

    作者回复: 总结的很赞!

    
     14
  • beiler
    2019-07-25
    令牌桶给了我很大的启发,我们可以在策略中心设置令牌桶,然后通过令牌桶控制整个job的产出和数量。这样就不会经常有几百万个job了,缓存的压力也会大幅度减小。但是有一个很诡异的问题,就以秒杀系统为例(我们的系统要比秒杀复杂点),我发现这种异步系统如果需要统计任务数量的时候经常会计数不准,尽管在计数的时候我选择了原子操作,但是计数还是会出现不准的现象。这个让我很苦恼,而且往往是运行很久的任务会出现不准,往往只有在任务结束的时候发现任务不准,这个问题很难查,请问老师有什么好建议吗

    作者回复: 如果计数只是为了控制流量,没必要那么精确。

    如果计数是业务需求必须要求准确,简单一点的话,可以使用Redis的INCR命令来计数,这个是可以保证原子性的。Redis性能要是不能满足要求,也可以用Kafka+flink集群来解决。这两种方案都是可以保证完全准确计数的。

    另外,计数不准的问题,并不一定是计数模块本身的问题,还要查一下是不是系统的其它部分有bug,导致重复计数或者漏计。

     2
     13
  • 风中花
    2019-07-23
    要不要继续买,继续买要不要!老师讲得这么好!纠结

    作者回复: 你买不了吃亏,买不了上当,买到的只有知识。

     1
     10
  • 撒旦的堕落
    2019-07-31
    我懵的地方就是用队列 将同步改成了异步 那么原来同步的request 和response是一对 那么改成异步后 怎么通知用户 难道还用原来的那个response ? 还是当秒杀成功后 根据用户的id 查询到信息 比如手机号码 然后发短信给他 或者是向用户推消息什么的

    作者回复: 对于网关某一个处理前端请求线程来说,大致的流程是:

    0.收到Request
    1.发消息
    2.阻塞等待,直到超时或者收到后端的秒杀结果;
    3.返回Response

    
     6
  • Fortune
    2019-07-23
    看完了,也看完了评论,可能只有我一个没有实际项目中接触消息队列了,慢慢学吧,加油!
    目前做的是支付系统,只知道用redis用来存储用户token和进行验证这样子,当然中间用户请求过来的过程中,是可以加队列来进行削峰的,应该是系统的并发并不高哈,就做了个集群这样子,谢谢老师分享!
    
     6
  • 微微一笑
    2019-07-23
    看到消息队列的专栏很兴奋,能学到底层源码、设计思想一直是我的梦,哈哈哈。目前在一家互金公司负责一个资金平台的项目,负责对接车贷、消费金融两个系统,同时与第三方资金渠道进行对接。在于车贷、消费金融这俩系统对接中,使用了rocketMQ进行系统间的解耦,系统间升级优化上线互不影响。由于对接的第三方渠道越来越多渠道间耦合较严重,下一步准备进行系统拆分,系统与系统间经过消息队列进行解耦。

    作者回复: 涉及到钱的系统,数据可靠性是最先需要考虑的问题。

     4
     6
  • 落尘kira
    2019-07-30
    看了下评论,我就简单补充一下实际用过的场景:
    1.数据同步:包括业务服务之间的业务数据同步(主要是状态)、DB间的数据同步等等
    2.异步通知:包括发送IM消息、异步日志、异步短信/邮件(尤其是批量数据)或注册/开启任务等等
    3.信息收集:主要用于数据统计、监控、搜索引擎等等
    4.服务解耦:主要用于重构和新设计时,对频繁变动的接口服务进行解耦(通常是被需求给逼的)
    5.分布式事务消息:尤其是对数据一致性有要求的异步处理场景
    6.主动性防御:秒杀、限流
    展开

    作者回复: 总结的非常到位!

    
     5
  • linqw
    2019-07-30
    APP⇆网关--生产-->消息队列--消费-->秒杀服务,有几点疑惑,老师有空帮忙解答下哦
    1、海量的请求都放在消息队列中,消息队列的整体容量如何衡量了?消息队列不可能能存放无限的消息,消息队列满应该也会有拒绝策略,比如线程池的任务队列,任务队列满,并且超过最大的线程池数,四种的拒绝策略。
    2、APP响应超时,即网关超过一定的时间没有返回,消息还在任务队列中,还是会被秒杀服务处理,这样的话,返回给APP秒杀失败,但是秒杀服务已经消费了消息?难道是在网关做补偿么?如果连接已经断开,将秒杀服务对此消息的处理做回滚操作么?
    3、网关和秒杀服务是通过消息队列进行通信,那响应消息也通过队列进行返回么?队列中会有APP对应的地址比如IP之类的?那这样的话,APP的海量连接都同时连接着网关,不是会有问题么?
    4、消息队列应该也会做多备的策略?比如队列消息的服务挂了,那些消息全部不见,这样不是也会存在问题么?
    展开

    作者回复: A1:实际上,只要有足够的磁盘容量,消息队列确实可以存放无限的消息。像秒杀请求这种数据,峰值并发高,但总数据量并不是很大,所以,堆积在消息队列中完全没问题。

    A2:都按照秒杀失败处理即可。

    A3:响应一般采用RPC来实现。超时或者返回秒杀结果之前,网关和APP确实要保持连接,这是HTTP协议决定的。至于网关能不能承受海量的APP连接,这个应该不用担心,网关的作用就是用来抗海量连接的,它也会有各种方法来解决这个问题。

    4、是的,大部分生产系统中的消息队列要配置成集群,确保可用性和数据可靠性,这个后面的课程我们会讲。

     4
     5
  • 豆沙包
    2019-07-23
    我在公司负责审核系统,审核系统要求稳定性和可靠性比较高。消息队列很好的保证了系统的稳定性。与此同时,除了实时mq,还用了许多延迟mq来进行任务的检查和异常重试。
     1
     5
  • Jxin
    2019-07-23
    1.拆单失败的延时重拆,死信告警。2.消峰和解耦也用到。

    问题:控制topic消费线程也能限流,不一定要引入令牌桶,要弄令牌桶,其实走redis更好一点。

    作者回复: 限流的方法有很多,当然不止令牌桶。令牌桶的优势是实现简单,易于控制。

    
     5
  • 流氓无产者
    2019-07-23
    修改数据库做数据同步也可以用

    作者回复: 是的,很多公司会用消息队列来做异构数据库之间的数据同步,但是一定要注意顺序问题。像MySQL Binlog这种,是要求严格有序的,否则会出现问题。

     3
     5
  • QQ怪
    2019-07-23
    滴滴滴,打卡

    作者回复: 打卡已收到,记得每节课都来打卡。

    
     4
  • 花儿少年
    2019-07-28
    好像还有个用go语言写的开源的消息队列

    作者回复: NSQ

     2
     3
  • 無鱼
    2019-07-23
    收获总结:
    1. 消息队列可以理解为一个暂存消息(可以是一条数据或者一个请求等等)的地方,有生产者有消费者
    2.消息队列的主要三个用处:
    a. 实现异步处理,利用消息队列可以将串行化的功能,在非必要串行的地方实现并行化,从而提升系统性能,缩短响应时间
    b. 实现流量控制 在高并发的情况下,为了避免大量的请求冲击后台服务,可以使用消息队列暂存请求,后台服务以最大处理能力消费请求,保证后台的安全性,其缺点拉长系统调用链,响应时间变长,增加系统复杂度;另外一种不改变系统调用链的实现方式,引入令牌桶的概念,单位时间内生成一定量的令牌放到令牌桶(即消息队列)中,令牌的数量要依据后台系统的处理能力,网关接受到请求后取到令牌才能调用后台服务,取不到则请求失败
    c. 系统间解耦 多个下游系统会频繁调用上游系统的接口获取数据的情况下,若上游系统将消息放到指定queue中,多个下游系统订阅消息,就可以避免上游为对接多个下游时频繁地修改接口,降低系统间的耦合度
    思考题:
    目前erp项目中,订单数据需要同时发给工程去评估以及企划去进行物料核算,现在的实现方式则是系统之间通过接口进行拉去或者推送,这就可以使用消息队列,将订单放到消息队列中,供下游订阅使用,降低系统间解耦
    展开

    作者回复: 总结的很到位,加油!

     2
     3
  • Mark Yao
    2019-07-23
    打卡,打卡,我们系统目前使用rabbitmq,有些业务实时数据对接第三方厂家,有些数据是TCP接入,有些HTTP过来,为解决和我们业务耦合。在使用遇到因特殊情况出现异常,消息大量堆积,最后导致爆掉。

    作者回复: 接下来会有一节课专门讲消息积压的问题。

    
     3
  • 我知道了嗯
    2019-07-23
    打卡,滴滴滴

    作者回复: 记得每节课来打卡。

    
     3
我们在线,来聊聊吧