php网站开发个人职责中国能建旗下公司排名
web/
2025/9/26 17:31:33/
文章来源:
php网站开发个人职责,中国能建旗下公司排名,仁怀哪儿做网站,今天西安最新通知继之前的mysql夺命连环之后#xff0c;我发现我这个标题被好多套用的#xff0c;什么夺命zookeeper#xff0c;夺命多线程一大堆#xff0c;这一次#xff0c;开始面试题系列MQ专题#xff0c;消息队列作为日常常见的使用中间件#xff0c;面试也是必问的点之一#xf…继之前的mysql夺命连环之后我发现我这个标题被好多套用的什么夺命zookeeper夺命多线程一大堆这一次开始面试题系列MQ专题消息队列作为日常常见的使用中间件面试也是必问的点之一一起来看看MQ的面试题。你们为什么使用mq具体的使用场景是什么mq的作用很简单削峰填谷。以电商交易下单的场景来说正向交易的过程可能涉及到创建订单、扣减库存、扣减活动预算、扣减积分等等。每个接口的耗时如果是100ms那么理论上整个下单的链路就需要耗费400ms这个时间显然是太长了。如果这些操作全部同步处理的话首先调用链路太长影响接口性能其次分布式事务的问题很难处理这时候像扣减预算和积分这种对实时一致性要求没有那么高的请求完全就可以通过mq异步的方式去处理了。同时考虑到异步带来的不一致的问题我们可以通过job去重试保证接口调用成功而且一般公司都会有核对的平台比如下单成功但是未扣减积分的这种问题可以通过核对作为兜底的处理方案。使用mq之后我们的链路变简单了同时异步发送消息我们的整个系统的抗压能力也上升了。那你们使用什么mq基于什么做的选型我们主要调研了几个主流的mqkafka、rabbitmq、rocketmq、activemq选型我们主要基于以下几个点去考虑由于我们系统的qps压力比较大所以性能是首要考虑的要素。开发语言由于我们的开发语言是java主要是为了方便二次开发。对于高并发的业务场景是必须的所以需要支持分布式架构的设计。功能全面由于不同的业务场景可能会用到顺序消息、事务消息等。基于以上几个考虑我们最终选择了RocketMQ。你上面提到异步发送那消息可靠性怎么保证消息丢失可能发生在生产者发送消息、MQ本身丢失消息、消费者丢失消息3个方面。生产者丢失 生产者丢失消息的可能点在于程序发送失败抛异常了没有重试处理或者发送的过程成功但是过程中网络闪断MQ没收到消息就丢失了。由于同步发送的一般不会出现这样使用方式所以我们就不考虑同步发送的问题我们基于异步发送的场景来说。异步发送分为两个方式异步有回调和异步无回调无回调的方式生产者发送完后不管结果可能就会造成消息丢失而通过异步发送回调通知本地消息表的形式我们就可以做出一个解决方案。以下单的场景举例。下单后先保存本地数据和MQ消息表这时候消息的状态是发送中如果本地事务失败那么下单失败事务回滚。下单成功直接返回客户端成功异步发送MQ消息MQ回调通知消息发送结果对应更新数据库MQ发送状态JOB轮询超过一定时间时间根据业务配置还未发送成功的消息去重试在监控平台配置或者JOB程序处理超过一定次数一直发送不成功的消息告警人工介入。一般而言对于大部分场景来说异步回调的形式就可以了只有那种需要完全保证不能丢失消息的场景我们做一套完整的解决方案。MQ丢失 如果生产者保证消息发送到MQ而MQ收到消息后还在内存中这时候宕机了又没来得及同步给从节点就有可能导致消息丢失。比如RocketMQRocketMQ分为同步刷盘和异步刷盘两种方式默认的是异步刷盘就有可能导致消息还未刷到硬盘上就丢失了可以通过设置为同步刷盘的方式来保证消息可靠性这样即使MQ挂了恢复的时候也可以从磁盘中去恢复消息。比如Kafka也可以通过配置做到acksall 只有参与复制的所有节点全部收到消息才返回生产者成功。这样的话除非所有的节点都挂了消息才会丢失。
replication.factorN,设置大于1的数这会要求每个partion至少有2个副本
min.insync.replicasN设置大于1的数这会要求leader至少感知到一个follower还保持着连接
retriesN设置一个非常大的值让生产者发送失败一直重试
虽然我们可以通过配置的方式来达到MQ本身高可用的目的但是都对性能有损耗怎样配置需要根据业务做出权衡。消费者丢失 消费者丢失消息的场景消费者刚收到消息此时服务器宕机MQ认为消费者已经消费不会重复发送消息消息丢失。RocketMQ默认是需要消费者回复ack确认而kafka需要手动开启配置关闭自动offset。消费方不返回ack确认重发的机制根据MQ类型的不同发送时间间隔、次数都不尽相同如果重试超过次数之后会进入死信队列需要手工来处理了。Kafka没有这些你说到消费者消费失败的问题那么如果一直消费失败导致消息积压怎么处理因为考虑到时消费者消费一直出错的问题那么我们可以从以下几个角度来考虑消费者出错肯定是程序或者其他问题导致的如果容易修复先把问题修复让consumer恢复正常消费如果时间来不及处理很麻烦做转发处理写一个临时的consumer消费方案先把消息消费然后再转发到一个新的topic和MQ资源这个新的topic的机器资源单独申请要能承载住当前积压的消息处理完积压数据后修复consumer去消费新的MQ和现有的MQ数据新MQ消费完成后恢复原状那如果消息积压达到磁盘上限消息被删除了怎么办这。。。他妈都删除了我有啥办法啊。。。冷静再想想。。有了。最初我们发送的消息记录是落库保存了的而转发发送的数据也保存了那么我们就可以通过这部分数据来找到丢失的那部分数据再单独跑个脚本重发就可以了。如果转发的程序没有落库那就和消费方的记录去做对比只是过程会更艰难一点。说了这么多那你说说RocketMQ实现原理吧RocketMQ由NameServer注册中心集群、Producer生产者集群、Consumer消费者集群和若干BrokerRocketMQ进程组成它的架构原理是这样的Broker在启动的时候去向所有的NameServer注册并保持长连接每30s发送一次心跳Producer在发送消息的时候从NameServer获取Broker服务器地址根据负载均衡算法选择一台服务器来发送消息Conusmer消费消息的时候同样从NameServer获取Broker地址然后主动拉取消息来消费为什么RocketMQ不使用Zookeeper作为注册中心呢我认为有以下几个点是不使用zookeeper的原因根据CAP理论同时最多只能满足两个点而zookeeper满足的是CP也就是说zookeeper并不能保证服务的可用性zookeeper在进行选举的时候整个选举的时间太长期间整个集群都处于不可用的状态而这对于一个注册中心来说肯定是不能接受的作为服务发现来说就应该是为可用性而设计。基于性能的考虑NameServer本身的实现非常轻量而且可以通过增加机器的方式水平扩展增加集群的抗压能力而zookeeper的写是不可扩展的而zookeeper要解决这个问题只能通过划分领域划分多个zookeeper集群来解决首先操作起来太复杂其次这样还是又违反了CAP中的A的设计导致服务之间是不连通的。持久化的机制来带的问题ZooKeeper 的 ZAB 协议对每一个写请求会在每个 ZooKeeper 节点上保持写一个事务日志同时再加上定期的将内存数据镜像Snapshot到磁盘来保证数据的一致性和持久性而对于一个简单的服务发现的场景来说这其实没有太大的必要这个实现方案太重了。而且本身存储的数据应该是高度定制化的。消息发送应该弱依赖注册中心而RocketMQ的设计理念也正是基于此生产者在第一次发送消息的时候从NameServer获取到Broker地址后缓存到本地如果NameServer整个集群不可用短时间内对于生产者和消费者并不会产生太大影响。那Broker是怎么保存数据的呢RocketMQ主要的存储文件包括commitlog文件、consumequeue文件、indexfile文件。Broker在收到消息之后会把消息保存到commitlog的文件当中而同时在分布式的存储当中每个broker都会保存一部分topic的数据同时每个topic对应的messagequeue下都会生成consumequeue文件用于保存commitlog的物理位置偏移量offsetindexfile中会保存key和offset的对应关系。CommitLog文件保存于${Rocket_Home}/store/commitlog目录中从图中我们可以明显看出来文件名的偏移量每个文件默认1G写满后自动生成一个新的文件。由于同一个topic的消息并不是连续的存储在commitlog中消费者如果直接从commitlog获取消息效率非常低所以通过consumequeue保存commitlog中消息的偏移量的物理地址这样消费者在消费的时候先从consumequeue中根据偏移量定位到具体的commitlog物理文件然后根据一定的规则offset和文件大小取模在commitlog中快速定位。Master和Slave之间是怎么同步数据的呢而消息在master和slave之间的同步是根据raft协议来进行的在broker收到消息后会被标记为uncommitted状态然后会把消息发送给所有的slaveslave在收到消息之后返回ack响应给mastermaster在收到超过半数的ack之后把消息标记为committed发送committed消息给所有slaveslave也修改状态为committed你知道RocketMQ为什么速度快吗是因为使用了顺序存储、Page Cache和异步刷盘。我们在写入commitlog的时候是顺序写入的这样比随机写入的性能就会提高很多写入commitlog的时候并不是直接写入磁盘而是先写入操作系统的PageCache最后由操作系统异步将缓存中的数据刷到磁盘什么是事务、半事务消息怎么实现的事务消息就是MQ提供的类似XA的分布式事务能力通过事务消息可以达到分布式事务的最终一致性。半事务消息就是MQ收到了生产者的消息但是没有收到二次确认不能投递的消息。实现原理如下生产者先发送一条半事务消息到MQMQ收到消息后返回ack确认生产者开始执行本地事务如果事务执行成功发送commit到MQ失败发送rollback如果MQ长时间未收到生产者的二次确认commit或者rollbackMQ对生产者发起消息回查生产者查询事务执行最终状态根据查询事务状态再次提交二次确认最终如果MQ收到二次确认commit就可以把消息投递给消费者反之如果是rollback消息会保存下来并且在3天后被删除。关注公众号科技缪缪获取更多精彩技术文章和电子书- END -
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/81464.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!