背景:

A 系统是一个面向用户的 saas 系统,用户的所有操作都会在 A 系统上操作。
B 系统是一个独立的系统,A 系统的几乎所有核心操作都需要转发到 B 系统,等 B 系统通过以后,再重新下发到 A 系统做其他操作。

目前存在问题:

AB 系统通信使用 HTTPS, 有时会有多个消息,有相对应的顺序关系,比如有一个商品上架请求,再有一个商品库存变更请求,如果 B 系统下发给 A 系统时,A 先收到了库存变更,再收到上架,第一个库存变更就会失败。

虽然通信使用 HTTPS , 但是其实很多操作都是 A 系统的 MQ 处理后,HTTPS 到 B 系统,B 系统放 MQ ,然后 B 系统处理,即便业务中先调用的接口也不一定 B 系统先收到。

如果 A 系统消费失败某个消息,不好重试。

A 系统是一个 saas 系统,每个租户都会收到一次 B 系统给他发的信息(因为后期考虑独立化部署,B 系统都发给每一个租户),压力比较大

思考的解决方案:

一个是考虑用区块链,B 系统每次把内容丢到链上,A 系统慢慢消费,这样顺序可以保证,但是如果不用智能合约的话这个开发成本很高,如果用的话我司没有非常专业的合约开发,我这种半吊子怕到时生产有问题解决不了。

第二种就是考虑直接 mq 通信,但是这样其实也没有解决消息先后的问题,两个系统都是微服务,除非 mq 强制顺序,但这样性能过差

想问问各位 dalao 有没有合适的解决方案,或者有什么中间件云服务能解决此类问题,thk~

干掉 b

用 MQ 不能保证消息的顺序性?为啥

用长连接,B 处理完再返回给 A ,A 才能发下一个

MQ 单一消费者, 根据一定的业务规则分片, 保证针对一个业务规则的数据是串行的

干掉我比较容易 QAQ

性能过差了 QAQ

两个系统都是微服务架构,长链接这不好吧

没必要上链,代价太大,保证顺序可以用 redis ,或者自己单独维护一个有序队列(C 写一个,性能也不差)

因为 mq 真不能保证顺序,无论生产顺序和消费顺序我们都不能保证

不要考虑区块链,区块链是比集群更大的冗余,目前看区块链解决不了任何国内的合法问题

我们之前遇到过下发消息给移动端有点类似

集群也是多台机器同时消费 MQ 再下发给移动端的,移动端接收可能乱序的问题,只是在消息体里加一个 step 控制顺序,移动端每次执行时判断是否大于上次的 step ,如果小于就默认忽略,但是我们的业务场景可以忽略前面的指令

消息在 A 的 mq 里是有序的,那么 A
在处理消息之前就推到 B 的 mq 里,消息内容可以是只要 id ,那么在 B 里也是同样的顺序,A 处理完之后就发请求到 B ,B 把结果写到数据库。B 在处理 mq 的消息的时候就去读库查结果,要是当前消息还没结果,就停着等。

kafka 分区解决排序问题?

4L 的方案可以啊,你不是 A 、B 内部本来就用到了 mq 么,怎么再加个 mq 就性能不够了

不符合中文语法和表达习惯的语句实在有点多,理解起来有点困难。。

如果没理解错的话,这不是支持顺序消息的 mq 能解决的问题么,主流 mq 应该都支持?根据业务主键决定投递到哪个队列,一个操作序列内局部有序。如果这都觉得性能差( queue 和 consumer 足够多还能差?),那我觉得问题是需求带来的,不是顺序消息本身带来的。

按照你的描述至少同一个商品只能是单线程执行,否则就算是按照顺序消费了,两个服务同时操作一个商品也可能有问题
提供一个思路,根据算法(比如 hash ,或者自定义)计算商品 id ,再根据结果发送到对应服务进行消费,保证同一个商品只在一个服务,这样就可以保证顺序了

是个好方法,但我们的消息不能丢 QAQ
Y? 因为我把区块链理解为一本公开的账本,大家按照同样逻辑操作到同样高度的时候,保证了数据的一致和可靠,能辛苦解答一下吗

这个单一消费者性能过差了,如果不是单一消费者,服务多节点的时候,假设系统 B 可以做到 mq 的顺序,他保证了 mq 内消息的顺序,但是因为 B 系统和 A 系统用了 HTTPS 通信,所以 B 系统在消费 B 系统的 MQ 消息发送给 A 的时候,A 接收就已经没有顺序了。如果 AB 用 MQ 通信,则 A 系统在接收消息(假设消息已经由 B 系统做好了 hash 和规则分片)的时候,多个消费节点需要手动指定他需要的处理的 partition ,且这时要保证严格顺序,每一个 partition 只能有一个消费者。阿里嘎多
同上,阿里嘎多
同上,阿里嘎多

这个消费者的同一个服务下多节点有办法保证顺序吗?这个服务起多少个节点由 K8S 控制,非人为控制的

#17 吞吐、延时和一致性,区块链这货一致性完全就是靠牺牲吞吐和延时来得到的,而且并不能达到保持时序的作用,区块链的逻辑完全就是按照收到消息的顺序提交,然后谁得到的确认多谁有限,没说保证消息时序

kafka 分区保证时序是最容易实现的了,性能不够也可以考虑 mq 分队列啊,逻辑虽然都是一个分区或者一个队列只能有一个消费者来保证时序,但是 mq 的队列数量可以多一些

此外也可以加分布式锁,和多线程编程解决时序一致逻辑一样,其性能损失和冲突率有关,看你这描述,saas 系统的动作都是人产生的,冲突概率应该极低才对,加锁的性能损失可以不计了,加锁也可以放在消息队列后面,那消息队列就可以不用考虑使用分区保证顺序了

确认了一下,这个我们在 A 系统可以做到说他确认了再给他发下一个,因为只是同一个商品流程在某一操作过程中的上链,A 系统可以自己做分布式锁,保证某一商品在上链过程中的顺序。因为我理解链上只需要保证生产的顺序,这个比较好保证,最差情况等 ack 了再发下一个,得益于这个是个区块链,消费的顺序一定是固定的。

kafka 分区 加分布式锁这个确实好像也可以,是一个方案,我晚点想想画画图

我依然认为分 partition 能解决所谓的性能问题,不知道你们是什么样的业务解决不了,除非连每个业务 flow 的 id 都没法分,那就是场景本身的问题了。

算了跳过性能问题,“一个 partition 只能对应一个消费者”这难道不是默认行为么? partition 和 consumer 多对一,跟是不是顺序消息没有关系,感觉你对 mq 有深刻的误解。。(当然也可能是我没懂你的顾虑)