小企业网站建设查询,wordpress怎样禁止采集,网站制作产品优化,清华大学自动化系#x1f44f;作者简介#xff1a;大家好#xff0c;我是爱吃芝士的土豆倪#xff0c;24届校招生Java选手#xff0c;很高兴认识大家#x1f4d5;系列专栏#xff1a;Spring源码、JUC源码、Kafka原理#x1f525;如果感觉博主的文章还不错的话#xff0c;请#x1f44… 作者简介大家好我是爱吃芝士的土豆倪24届校招生Java选手很高兴认识大家系列专栏Spring源码、JUC源码、Kafka原理如果感觉博主的文章还不错的话请三连支持一下博主哦博主正在努力完成2023计划中源码溯源一探究竟联系方式nhs19990716加我进群大家一起学习一起进步一起对抗互联网寒冬 文章目录 消息队列的应用场景从秒杀开始说起异步处理流量控制服务解耦非常多的应用场景 消息队列选型的基本标准选择消息队列的基本标准可供选择的消息队列RabbitMQRocketMQKafka 消息队列的消费模式队列模型发布-订阅模型RabbitMQ的消息模型RocketMQ的消息模型Kafka的消息模型 消息队列的应用场景
从秒杀开始说起 类似于秒杀的场景短时间内需要处理大量的请求的需要涉及两个东西一个是缓存一个是MQ。
首先从头来分析整个的流程到底是什么样的。
假如说我想举行一个秒杀活动我想定在明天上午的十点所以这个事就需要我们的运维人员提前通过 秒杀活动管理服务 来 配置秒杀活动及更改 后面有个动作就是 双写异步通知 将秒杀活动的信息同步到 缓存 和 数据库 中此时 查询秒杀活动 可以从 缓存 中去查询。
当配置完成后还需要发送一个 MQ 去进行 秒杀活动变更通知 那么谁去处理呢 一个是 **秒杀页面渲染服务 **
一个是 库存中心 对于库存中心来说它所做的就是 活动变更/更新库存/释放冻结 。对于我们的 秒杀页面渲染服务 我们打开前台的页面应该是静态的而我们少部分的活动信息应该是动态的所以我们应该为其生成这样的静态页面。基于模板技术渲染出HTML 渲染出来之后 推送给Nginx 这样的话将来不用访问后端服务直接到Nginx就可以拿到我们的所对应的秒杀商品的信息。但是光到这一步还是不够的因为用户是天南海北的都打到北京机房可能扛不住所以需要 向 CDN服务器 推送静态 由CDN做负载均衡分配到就近的机房上。这样的话这一路就差不多了。
对于我们的用户来说他登陆到我们的 商城系统就可以参与我们的 秒杀 了
在这之前需要进行一个 时间同步服务 主要涉及到一个 秒杀授时 的问题
当开始 点击秒杀按钮 30s内只能点击一次 但是我们不能只考虑到正常的流量我们还需要考虑商业程序批量来的用户流量。这里面有主要的限流手段如 商业验证码防刷限流 大数据AI判断验证码 DDoc高防 进行这些过程后 流量清洗 就能到达我们的设备也就是到了 Nginx 其内部也要进行 内部限流 比如只允许超过库存10%请求 。
假如说参加活动的有100w人但是实际能抢到茅台的只有1000个人对于大部分请求来说是不需要处理的先到先得。但是考虑到有一部分人下单失败下单了没有进行支付等等所以进行限流控制。
此时到了我们 反作弊服务 经过我们的 大数据分析 看看是不是 异常账号 僵尸账号
然后就是负载到了我们的 秒杀服务集群 此时我们就 可以用库存LUA脚本 去扣减Redis里面的库存。当扣减成功也就意味着 秒杀成功零丢失 发送一个 MQ 那么 秒杀下单服务 监听/消息积压/消息丢失/解决 此时就可以到我们的 订单系统 生成订单 然后去进行 支付 。
当然还需要考虑 失败/取消/回退库存 到redis集群以及 秒杀下单服务的幂等解决重复下单问题
以上方案适合于短时间内来高并发的场景。
异步处理
秒杀系统需要解决的核心问题就是利用有限的服务器资源短时间内处理海量的请求。秒杀场景一定离不开的是缓存和消息队列。
处理一个秒杀请求包含了很多步骤例如
风险控制库存锁定生成订单短信通知更新统计数据
如果没有任何优化正常的处理流程是APP将请求发送给网关依次调用上述5个流程然后将结果返回给APP。
决定秒杀是否成功取决于两个动作风险控制、库存锁定后续生成订单、短信通知、更新统计并不一定在秒杀请求中处理。 借助MQ将原来的5个步骤减少为2个步骤。
对于一些比较耗时的操作通过消息队列进行了异步处理了更快的返回结果。减少等待实现了步骤的并发、提升了系统的性能。
异步还可以提升系统的伸缩性。 流量控制
错峰与流控消峰与填谷。因为前端 和 后端的流量处理能力不一样
如何避免过多的请求压垮我们的秒杀系统呢
设计思路使用消息队列隔离网关和后端服务以达到流量控制和保护后端服务的目的。 假如消息队列之后整个秒杀的流程
网关收到请求后将请求放入到MQ中。后端服务从请求MQ获取请求完成后续秒杀处理过程返回响应。 代价
增加系统调用链环节导致总体的响应时延变长同步调用变成了异步调用增加了系统的复杂度成本问题MQ高性能 高可用
MQ太重了可以考虑其他简单的实现方案
常见限流算法
固定窗口算法滑动窗口算法漏桶算法令牌桶算法
令牌桶控制流量的原理是单位时间内只发放固定数量的令牌到令牌桶中规定服务在处理请求之前必须先从令牌桶中拿出来一个令牌如果令牌桶中没有令牌则拒绝请求。这样就保证单位时间内能处理的请求不超过发放令牌的数量起到了流量控制的作用。 而实现令牌的方式不像消息队列一样不需要破坏原有的调用链只要在网关里处理APP请求时增加一个获取令牌的逻辑。
服务解耦
微服务的通信模式
调用链模式A 调用 BB 调用 C弊端就是调用链太长了那么其实调用链的可用性就取决于每个服务的可用性相乘总的来说可用性是下降的性能的影响也是下降的聚合器模式业务聚合的情况其实就是将原有比较长的一个调用链缩减成两层基于事件的异步模式 当新订单创建时
支付系统发起支付流程风控系统验证合法性消息系统发送短信运营系统需要更新统计数据…
所有的电商都选择用消息队列来解决类似的系统耦合过于紧密的问题。引入消息队列后订单服务在订单变化时发送一条消息到消息队列的一个主题Order中所有下游系统都订阅主题Order这样每个下游系统都可以获得一份实时完整的订单数据。
非常多的应用场景
通过MQ实现分布式事务、最终一致性作为发布/订阅系统实现一个微服务级别的系统间的观察者模式连接流计算任务和大数据用于将消息广播给大量接收者数据同步
消息队列选型的基本标准
选择消息队列的基本标准
功能需求引入消息队列能不能解决我现在的问题非功能需求是否开源社区维护是否流行并且有一定的社区活跃度
开源的话如果在开发的过程中出现了bug最起码你可以通过看源代码规避这个问题。 开源的话网上有很多现成的解决方案使用的人多会和整体的生态有一个很好的兼容。
所以作为一款及格的消息队列产品必须具备的几个特性包括
可靠性消息可靠传递可靠存储不丢消息。高可用支持集群确保不会因为某个节点宕机导致服务不可用当然也不能丢消息。高性能具备足够好的性能能够满足绝大多数场景的性能要求。
可供选择的消息队列
RabbitMQ RabbitMQ使用Erlang语言编写号称是世界上使用最广泛的开源消息队列之一其支持灵活的配置并且支持的语言是最多的。
但是其还存在很多的问题
1.对消息堆积的支持并不好在其理念里面消息堆积本身是不正常的作为使用者自己应该去避免
2.其性能是几个常用的性能中最差的但是处理普遍的场景没啥问题几万数十万级别的
3.开发语言是Erlang语言比较小众语法还不一样不容易看懂
RocketMQ RocketMQ是阿里巴巴在2012年开源的消息队列产品后来捐赠给Apache软件基金会2017正式毕业成为Apache的顶级项目。阿里内部也是使用RocketMQ作为支撑其业务的消息队列经历过多次“双十一”考验它的性能、稳定性和可靠性都是值得信赖的。作为优秀的国产消息队列近年来越来越多的被国内众多大厂所使用。
如果所应用的非常在乎响应的时延那么请选择RocketMQ。其性能比RabbitMQ高出来一个数量级。
Kafka Kafka最早是由LinkedIn开发目前也是Apache的顶级项目。其最初的设计目的是用于处理海量的日志。
Kafka与周边生态系统的兼容性是最好的没有之一尤其是在大数据领域和流式计算领域几乎所有的相关开源软件系统都会优先支持Kafka。
Kafka使用Scala和Java语言开发设计上大量使用了批量和异步的思想这种设计使得Kafka能做到超高的性能。Kafka的性能尤其是异步收发的性能是三者中最好的但与RocketMQ并没有产生量级上的差异大约每秒钟可以处理几十万条数据。
但是Kafka这种异步批量的设计带来的问题就是它的同步收发消息的响应时延比较高因为当客户端发送一条消息的时候Kafka并不会立即发送出去而是要等一会攒一批再发送在它的Broker中很多地方都会使用这种“先攒一波再一起处理”的设计。当你的业务场景中每秒钟消息数量没有那么多的时候Kafka的时延反而会比较高。所以Kafka不太适合在线业务场景。
总结
如果对消息队列功能和性能都没有很高的要求只需要一个开箱即用易于维护的产品建议使用 RabbitMQ。
RocketMQ 对一致性的良好保证以及低延迟和金融级的稳定性可以应用在电商各级业务调用的拆分中比如在订单完成后通知用户物流信息更新以后对订单状态的更新等。
电商业务调用的拆分RocketMQ 可以用于将电商系统中的不同业务模块解耦通过消息队列传递各个模块之间的消息实现业务流程的拆分和解耦提高系统的可扩展性和灵活性。订单状态更新通知RocketMQ 可以用于在订单完成后通知用户以及当物流信息更新时更新订单状态。通过将通知消息发送到 RocketMQ其他系统或服务可以订阅并相应地处理这些消息。
Kafka 可以在各类数据埋点中使用比如电商营销的转化率日志收集和计算另外Kafka 的高性能使得特别它适合应用在各类监控、大数据分析等场景或是你的应用场景大量使用了大数据、流计算相关的开源产品那 Kafka 是最适合你的消息队列。
电商营销转化率日志收集和计算Kafka 可以用于收集电商网站的用户行为日志例如点击、购买等然后将这些日志提供给转化率计算引擎进行实时计算和分析从而评估和优化营销活动的转化率。监控和大数据分析Kafka 可以用作实时数据流的收集和传输工具将来自各种监控系统、传感器、应用程序日志等的数据发送到大数据分析平台进行实时分析和处理。
消息队列的消费模式
Queue数据结构先进先出FIFOFirst - In - First - Out的线性表在后端插入数据在前端删除数据。
队列模型
最初的一种消息模型队列模型
生产者发消息就是入队操作消费者收消息就是出队也就是删除操作服务端存放消息的容器自然就称之为“队列”需要严格有序。 如果存在多个消费者此时每个消费者消费的都是部分数据每个消费者加起来消费的数据才是生产者生产的数据。
发布-订阅模型
在发布订阅模型中消息的发送方称之为发布者消息的接收方称之为订阅者服务端存放消息的容器称之为主题 在发布订阅模式下每个订阅了主题的订阅者都可以完整的消费主题中的所有消息。
队列模式 VS 发布-订阅模式
生产者就是发布者消费者就是订阅者队列就是另一个形式的主题。一份数据能不能被消费多次的问题队列模式下每个消费者只能消费部分数据发布-订阅模式下每个订阅者消费者可以消费完整的数据。
RabbitMQ的消息模型
RabbitMQ是少数依然坚持使用队列模型的产品之一。 如果同一份消息希望被多个消费者完整消费配置Exchange将消息投递到多个队列中每个队列中都存储了完整的消息数据。
其实是等同于变量的实现了“发布 - 订阅” 模型。 RocketMQ的消息模型
使用的消息模型是标准的“发布 - 订阅”模型。 当我们Broker中的topic下的queue收到消息之后会向生产者发送确认的响应。如果消费者没有收到MQ的确认此时会重新发送消息。
对于消费者来说消费者收到消息并且完成自己的业务逻辑会给MQ发送消费成功的确认MQ收到确认后认为该消息被消费成功了否则它会给消费者重新发送该消息直到收到消费成功的确认。
在Broker节点中包括N个topic每个topic包括多个queue通过多个队列来实现多实例并行生产和消费。RocketMQ在队列层面保持消息的有序性而不是在Topic这一层。
消费组的概念Consumer Group多个消费者可以在逻辑上归为一个消费组。每个消费组都消费主题中的一份完整的消息不同的消费组之间起到了隔离的效果都是可以完整消费的彼此的消费进度是不受影响的。同一个消息被Consumer Group1消费过也会再给Consumer Group2进行消费。同一个组内的消费者是竞争关系每个消费者消费的是组内的一部分数据。
因为消息会需要在不同的消费组进行多次消费所以需要RocketMQ为每个消费组在每个队列上去维护一个消费位置Offset Kafka的消息模型
在这里先说一个重大的区别RocketMQ支持多个消费者消费同一个队列而Kafka不支持多个消费者消费同一个分区。
在RocketMQ中一个队列可以有多个消费者同时消费这种模式称为广播模式。每个消费者都会接收到队列中的所有消息实现了消息的高并发处理和负载均衡。
而在Kafka中一个分区只能由一个消费者组中的一个消费者进行消费这种模式称为竞争消费模式。不同的消费者组可以同时消费同一个主题的不同分区但一个分区只能被一个消费者消费。这种设计模式适用于按照顺序处理消息或确保每条消息只被一个消费者处理的场景。
因此RocketMQ的多个消费者消费一个队列的能力是它与Kafka的一个重要区别。
还有一个区别就是在 Kafka 中队列这个概念的名称不一样Kafka 中对应的名称是“分区Partition”含义和功能是没有任何区别的。