提升单体应用软件的性能,对系统的扩展消息队列有着至关重要的作用,这一章简单写几个常见到的问题
1.消息队列的使用场景
- 校验用户名等信息,如果没问题会在数据库中添加一个用户记录
- 如果是用邮箱注册会给你发送一封注册成功的邮件,手机注册则会发送一条短信
- 分析用户的个人信息,以便将来向他推荐一些志同道合的人,或向那些人推荐他
- 发送给用户一个包含操作指南的系统通知
2.消息的重发补偿解决思路
- 可靠消息服务定时查询状态为已发送并超时的消息
- 可靠消息将消息重新投递到 MQ 组件中
- 下游应用监听消息,在满足幂等性的条件下,重新执行业务
- 下游应用通知可靠消息服务该消息已经成功消费
- 通过消息状态确认和消息重发两个功能,可以确保上游应用、可靠消息服务和下游应用数据的最终一致性
3.消息的幂等性解决思路
-
消息的幂等性解决思路
查询一次和查询多次,在数据不变的情况下,查询结果是一样的。select 是天然的幂等操作 -
删除操作
删除操作也是幂等的,删除一次和多次删除都是把数据删除。(注意可能返回结果不一样,删除的数据不存在,返回0,删除的数据多条,返回结果多个) -
唯一索引,防止新增脏数据
比如:支付宝的资金账户,支付宝也有用户账户,每个用户只能有一个资金账户,怎么防止给用户创建资金账户多个,那么给资金账户表中的用户ID加唯一索引,所以一个用户新增成功一个资金账户记录 -
Token 机制
防止页面重复提交 -
select + insert
并发不高的后台系统,或者一些任务JOB,为了支持幂等,支持重复执行,简单的处理方法是,先查询下一些关键数据,判断是否已经执行过,在进行业务处理,就可以了
注意:核心高并发流程不要用这种方法
- 对外提供接口的 API 如何保证幂等
如银联提供的付款接口:需要接入商户提交付款请求时附带:source 来源,seq 序列号 source + seq 在数据库里面做唯一索引,防止多次付款,(并发时,只能处理一个请求)
4.消息的堆积解决思路
如果还没开始投入使用 Kafka,那应该在设计分区数的时候,尽量设置的多点,从而提升生产和消费的并行度,避免消费太慢导致消费堆积
增大批次
瓶颈在消费吞吐量的时候,增加批次也可以改善性能
增加线程数
如果一些消费者组中的消费者线程还是有 1 个消费者线程消费多个分区的情况,建议增加消费者线程。尽量 1 个消费者线程对应 1 个分区,从而发挥现有分区数下的最大并行度
5.自己如何实现消息队列
大体上的设计是由一条线程 1 执行从等待列表中获取任务插入任务队列再由线程池中的线程从任务队列中取出任务去执行.
添加一条线程 1 主要是防止在执行耗时的任务时阻塞主线程.当执行耗时任务时,添加的任务的操作快于取出任务的操作,
当任务队列长度达到最大值时,线程 1 将被阻塞,等待线程 2,3… 从任务队列取出任务执行
6.如何保证消息的有序性
- 通过轮询所有队列的方式来确定消息被发送到哪一个队列(负载均衡策略)。订单号相同的消息会被先后发送到同一个队列中
- 在获取到路由信息以后,会根据算法来选择一个队列,同一个 OrderId 获取到的肯定是同一个队列
这一章节内容以及问题相对较少一些,这样也有助于大家的记忆吧,如果是想要提升技能的,其他博主写的都有详细的知识篇
前几期系列有心态篇,基础篇,集合篇,线程篇,锁机制篇,Spring框架篇,分布式篇,微服务篇,数据存储篇,缓存使用篇
本系列总共所涉及Java基础,集合,线程,锁机制,spring框架,分布式,微服务,数据存储,缓存使用,消息队列,安全,性能调优,设计模式以及需求分析