参考文章:消息队列(mq)是什么?、重复消费
老坑还没填完,就又开一个新坑:
Rocket MQ;Message Queue。
;比如:订单微服务,需要远程访问商品库存微服务,但是这样远程的整体响应速度较慢,为了解决速度慢的问题,可以加MQ进行异步处理。。如果异步处理失败怎么办?
如果用线程池,会出现:
a) 业务过多,每次加一个,要调用一个接口还要重新发布系统,效率低下。
如果只管订单微服务系统,那如果积分或者短信出错怎么办?
:涉及到分布式事务知识点,以后再来填坑。是否涉及耦合的问题?
:也就是之前的解耦主要指的是哪方面的解耦?
多了个中间件,就需要考虑各种问题,比如重复消费、消息丢失、顺序消费等,用了之后就是贼烦。
详情见文章:
分布式系统的通病
;
在MQ中,有分布式事务,把下单、优惠券、积分等都放在一个事务中,要么一起成功,要么一起失败。
后续展开;
比如主流的Kafka、Active MQ、Rabbit MQ、RocketMQ这几种
RocketMQ与Dubbo都是出自阿里之手,其架构设计很相像。
Kafka是消息队列的标杆,在其他类似于大数据领域也有很好的表现。
没有最好的技术,之后最合适的技术。不要为了用技术而用。
如果有服务发生错误,比如积分系统,则对应的重试机制会抛出异常,让重新发送一次。如果重新发送消息,其他的活动也都能看到这条“新”消息,如何避免重复消费该消息呢?
接口幂等;
幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。
在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。
例如,“setTrue()”函数就是一个幂等函数,无论多次执行,其结果都是一样的.更复杂的操作幂等保证是利用唯一交易号(流水号)实现.
帅气面试官您好,一般幂等,我会分场景去考虑,看是强校验还是弱校验,比如跟金钱相关的场景那就很关键呀,就做强校验,别不是很重要的场景做弱校验。
强校验:比如你监听到用户支付成功的消息,你监听到了去加GMV是不是要调用加钱的接口,那加钱接口下面再调用一个加流水的接口,两个放在一个事务,成功一起成功失败一起失败。每次消息过来都要拿着订单号+业务场景这样的唯一标识(比如天猫双十一活动)去流水表查,看看有没有这条流水,有就直接return不要走下面的流程了,没有就执行后面的逻辑。
弱校验:这个简单,一些不重要的场景,比如给谁发短信啥的,我就把这个id+场景唯一标识作为Redis的key,放到缓存里面失效时间看你场景,一定时间内的这个消息就去Redis判断。
;
一般都是同个业务场景下不同几个操作的消息同时过去,本身顺序是对的,但是你发出去的时候同时发出去了,消费的时候却乱掉了,这样就有问题了。
有时遇到这种情况:把所有的操作消息怼到队列里面去,然后慢慢消费的,那问题就来了呀,我们在数据库同时对一个Id的数据进行了增、改、删三个操作,但是你消息发过去消费的时候变成了改,删、增,这样数据就不对了。
生产者消费者一般需要保证顺序消息的话,可能就是一个业务场景下的,比如订单的创建、支付、发货、收货。
一个topic下有多个队列,为了保证发送有序,RocketMQ提供了MessageQueueSelector队列选择机制,他有三种实现:
选择哈希,根据订单号将对同一行数据的操作(创建、支付、发货、收获)映射到同一队列中,进而都在同一消费者端消费。
==为了保证消息的顺序,需要同步,只有当订单的创建消息发送成功,才发送支付消息。==这样就保证了消息的顺序性。
RocketMQ的topic内的队列机制,可以保证存储满足FIFO,剩下的只需要消费者顺序执行。
RocketMQ仅保证顺序发送,顺序消费由消费者业务保证!!!
分布式事务在现在遍地都是分布式部署的系统中几乎是必要的。
事务是恢复和并发执行的基本单位:要么一起执行,要么都不执行的一组数据库操作的集合。
事务的隔离级别、ACID(原子性、一致性、独立性 隔离性、持久化)
原子性:一个事务是一个不可分割的工作单位,包括的操作要么都做,要么都不做。
一致性:事务必须是使数据库从一个一致性状态变到另一个一致性状态。
隔离性:一个事务的执行不能被其他事务干扰。即某一事务的内部操作以及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性:一个事务一旦提交,对数据库中的数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
分布式事务,保证积分、优惠券等的相关业务的正确运行。
2pc,两段式提交:
好复杂: