高并发系统设计40问
唐扬
美图公司技术专家
立即订阅
9202 人已学习
课程目录
已更新 38 讲 / 共 40 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 为什么你要学习高并发系统设计?
免费
基础篇 (6讲)
01 | 高并发系统:它的通用设计方法是什么?
02 | 架构分层:我们为什么一定要这么做?
免费
03 | 系统设计目标(一):如何提升系统性能?
04 | 系统设计目标(二):系统怎样做到高可用?
05 | 系统设计目标(三):如何让系统易于扩展?
06 | 面试现场第一期:当问到组件实现原理时,面试官是在刁难你吗?
演进篇 · 数据库篇 (5讲)
07 | 池化技术:如何减少频繁创建数据库连接的性能损耗?
08 | 数据库优化方案(一):查询请求增加时,如何做主从分离?
09 | 数据库优化方案(二):写入数据量增加时,如何实现分库分表?
10 | 发号器:如何保证分库分表后ID的全局唯一性?
11 | NoSQL:在高并发场景下,数据库和NoSQL如何做到互补?
演进篇 · 缓存篇 (6讲)
12 | 缓存:数据库成为瓶颈后,动态数据的查询要如何加速?
13 | 缓存的使用姿势(一):如何选择缓存的读写策略?
14 | 缓存的使用姿势(二):缓存如何做到高可用?
15 | 缓存的使用姿势(三):缓存穿透了怎么办?
16 | CDN:静态资源如何加速?
加餐 | 数据的迁移应该如何做?
演进篇 · 消息队列篇 (6讲)
17 | 消息队列:秒杀时如何处理每秒上万次的下单请求?
18 | 消息投递:如何保证消息仅仅被消费一次?
19 | 消息队列:如何降低消息队列系统中消息的延迟?
20 | 面试现场第二期:当问到项目经历时,面试官究竟想要了解什么?
用户故事 | 从“心”出发,我还有无数个可能
期中测试 | 10道高并发系统设计题目自测
演进篇 · 分布式服务篇 (9讲)
21 | 系统架构:每秒1万次请求的系统要做服务化拆分吗?
22 | 微服务架构:微服务化后,系统架构要如何改造?
23 | RPC框架:10万QPS下如何实现毫秒级的服务调用?
24 | 注册中心:分布式系统如何寻址?
25 | 分布式Trace:横跨几十个分布式组件的慢请求要如何排查?
26 | 负载均衡:怎样提升系统的横向扩展能力?
27 | API网关:系统的门面要如何做呢?
28 | 多机房部署:跨地域的分布式系统如何做?
29 | Service Mesh:如何屏蔽服务化系统的服务治理细节?
演进篇 · 维护篇 (5讲)
30 | 给系统加上眼睛:服务端监控要怎么做?
31 | 应用性能管理:用户的使用体验应该如何监控?
32 | 压力测试:怎样设计全链路压力测试平台?
33 | 配置管理:成千上万的配置项要如何管理?
34 | 降级熔断:如何屏蔽非核心系统故障的影响?
高并发系统设计40问
登录|注册

18 | 消息投递:如何保证消息仅仅被消费一次?

唐扬 2019-10-30
你好,我是唐扬。
经过上一节课,我们在电商系统中增加了消息队列,用它来对峰值写流量做削峰填谷,对次要的业务逻辑做异步处理,对不同的系统模块做解耦合。因为业务逻辑从同步代码中移除了,所以,我们也要有相应的队列处理程序来处理消息、执行业务逻辑,这时,你的系统架构变成了下面的样子:
这是一个简化版的架构图,实际上,随着业务逻辑越来越复杂,会引入更多的外部系统和服务来解决业务上的问题。比如说,我们会引入 Elasticsearch 来解决商品和店铺搜索的问题,也会引入审核系统,来对售卖的商品、用户的评论做自动的和人工的审核,你会越来越多地使用消息队列与外部系统解耦合,以及提升系统性能。
比如说,你的电商系统需要上一个新的红包功能:用户在购买一定数量的商品之后,由你的系统给用户发一个现金的红包,鼓励用户消费。由于发放红包的过程不应该在购买商品的主流程之内,所以你考虑使用消息队列来异步处理。这时,你发现了一个问题:如果消息在投递的过程中发生丢失,那么用户就会因为没有得到红包而投诉。相反,如果消息在投递的过程中出现了重复,那么你的系统就会因为发送两个红包而损失。
那么我们如何保证,产生的消息一定会被消费到,并且只被消费一次呢?这个问题虽然听起来很浅显,很好理解,但是实际上却藏着很多玄机,本节课我就带你深入探讨。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《高并发系统设计40问》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(27)

  • 👽
    处理方式:
    网络抖动处理:重发
    消息队列服务器宕机:集群
    消息重复:使用唯一 ID 保证消息唯一性。
    2019-10-30
    11
  • 我们目前是在消费消息后,将消息id(业务上定义的唯一标识)放入redis。消费前,先去redis查找,也算是业务上的一种防重复吧

    作者回复: 嗯那 这个也是的

    2019-10-30
    11
    5
  • 罗力友
    消息队列的服务端会存储 < 生产者 ID,最后一条消息 ID> 的映射。当某一个生产者产生新的消息时,消息队列服务端会比对消息 ID 是否与存储的最后一条 ID 一致,如果一致,就认为是重复的消息,服务端会自动丢弃。
    老师,只校验最后一条ID应该不能完全保证消息不重复吧?

    作者回复: 如果每条消息生产时都使用发号器发一个唯一的号就好了

    2019-10-31
    2
  • 高源
    老师请教一个问题,例如我开发个服务端程序,我想知道我开发的服务程序性能指标,怎么得的,例如机器配置 cpu有i3 i5的那个更适合怎么测试出来的,另外qps吞吐率等这些都是用工具测试的吗😊

    作者回复: 用哪种机器都可以,只是你在出性能报告的时候需要说明机器的配置:)

    qps的话一般会收集访问日志来统计,后面我讲到监控时会提到的

    2019-10-30
    1
    1
  • 欢喜哥
    比方说,消息生产时由于消息队列处理慢或者网络的抖动,导致虽然最终写入消息队列成功,但在生产端却超时了

    请教老师,这个地方,如果超时了,生产者还会把消息传递到消费队列,然后造成消息重复嘛?
    2019-12-09
  • 布小丫学编程
    通过数据库锁实现幂等性:insert ignore, insert ... on duplicate, insert replace, update set a where a等等
    2019-11-25
  • tchz
    【当 Leader 故障时,新选举出来的 Leader 会从 ISR 中选择,默认 Leader 的数据会异步地复制给 Follower,这样在 Leader 发生掉电或者宕机时,Kafka 会从 Follower 中消费消息】这里不太明白。当leader宕掉之后,kafka从follower中消费消息,这个follower是包括ISR的吗?那么是从哪个follower中消费呢?还是从选举成新leader的follower中消费呢

    作者回复: 是从ISR中选出一个follower作为新的leader

    2019-11-22
  • 何磊
    老师好,我对消息全局id存在疑问。该id是否应该是这个消息的签名呢?如果仅仅是全局id并不能判断两条消息是否一致
    2019-11-21
  • 微凉
    其实防止重复信息生产和消费,只需要围绕幂等性做文章就可以了。
    2019-11-17
  • 夏风
    目前我们遇到的消息重复的场景都是在时间很近的范围内,消费端在消费消息时会针对同一业务场景,比如“消费接受支付成功的消息”,会针对订单号增加分布式锁,来保证秒级别内不会有重复消息。针对一些比较敏感的数据,也会去数据库滤重。
    2019-11-14
  • 天机老人
    增加版本号那个方案好像有点问题,当并发生产消息时,拿到的版本号是一样的,在真正消费时,由于有版本号的过滤,第一条能执行成功,后面都会失败!!!
    2019-11-12
    2
  • 海罗沃德
    李玥老師消息對列課程裡專門有一顆講冪等的
    2019-11-11
  • XD
    它的做法是给每一个生产者一个唯一的 ID,并且为生产的每一条消息赋予一个唯一 ID,消息队列的服务端会存储 < 生产者 ID,最后一条消息 ID> 的映射。当某一个生产者产生新的消息时,消息队列服务端会比对消息 ID 是否与存储的最后一条 ID 一致,如果一致,就认为是重复的消息,服务端会自动丢弃。
    ……………………
    每一条消息的id应该是生产者生成的吧?

    作者回复: 是的

    2019-11-09
  • 星空123
    这个幂等性解释太合适了、😄
    2019-11-07
  • 云师兄
    Kafka的顺序io,是不是针对pagecache将批量日志一起刷盘时候,只需要一次随机io寻找磁盘位置,后续多条日志可以批量顺序写入?所以顺序io的第一条也需要随机io?

    作者回复: 是的

    2019-11-07
  • 云师兄
    Kafka的顺序io,是否是针对pagecache

    作者回复: 是的 不过Kafka是顺序写入日志,也是顺序io

    2019-11-07
  • 敏敏
    用分布式锁 解决重试 用 数据库cas解决多人同时减库存的逻辑
    2019-11-04
  • 肖大保健
    关于幂等性方案,上面先查后写操作,也不是绝对的,会有并发问题,同时多个线程,一个正在进行插入操作,一个正在进行查询操作,正好查不到,会有两条重复数据,当然概率比较小,
    解决方法
    1、有没有业务数据加唯一索引,插入失败抛异常,异常可能会MQ重试,所以还需要catch异常处理
    2、插入加入写锁,for update 影响会比较大
    3、当有唯一索引实,insert ignore 忽略重复插入问题,replace into 和 insert ... on duplicate key update,都是替换原有的重复数据
    2019-11-03
  • jiangjing
    生活老司机

    作者回复: 😎

    2019-11-01
  • 罗力友
    老师,我可不可以认为生产端产生的消息重复,都是因为生产端重复发送同一个消息?

    作者回复: 是的

    2019-10-31
收起评论
27
返回
顶部