书接上文。这次继续聊一聊MQ
面试官:如何保证消息的顺序性,可以简单聊聊什么场景需要避免这种问题的发生以及如何解决吗?
派大星:当然可以。其实就MySQL而言来说,比如需要依赖MySQL 的binlog做一个同步系统。用户在MySQL中增删改一条数据,对应出来增删改3条binlog,接着将这3条binlog同步到MQ里面。然后到消费出来一次执行,此时就需要保证消息的顺序性,不然就会出现问题。
面试官:嗯,不错那你简单说说不同MQ消息错乱的一个场景吗?
派大星:可以的。
解决方案:每个消费者建立对应的queue,并且让保持顺序的消息只发送到一个queue上,这样消费者消费数据处理的时候就不会出现顺序错乱。
首先来说Kafka是可以保证生产者写入一个partition的数据一定是有顺序的。
在Kafka使用中,只要Kafka内部不涉及多个线程并发处理
的情况下,其实我们只需要在生产者写入数据的时候可以指定一个key,比如指定某个订单id作为key,这个订单相关的数据就会被分发到一个partition。这里我们要知道一个原则是Kafka一个partition只能被一个消费者消费
,这样消费者从partition中取出来的数据一定是有顺序的。
面试官:什么情况下Kafka会出现消息顺序不一致的情况呢?
派大星:当消费者内部搞多个线程并发处理的时候,则可能会出现顺序不一致的问题。如图所示:
面试官:那如何解决Kafka多线程处理导致的消息错乱问题呢?
派大星:其解决方案可以是采用hash算法
进行hash分发。相同的订单key的数据分发到同一个内存queue
里面去。如图所示:
面试官:嗯,不错。那你在实际使用过程中有遇到过消息积压的问题吗?能说说遇到这种问题的时候你的解决思路是什么样的?
派大星:好的。其实在面对消息有积压的情况。多数都是消费者故障导致的。简单的解决思路如下:可以当做是一个临时紧急扩容的一个方案:
面试官:不错。思路不错。突然有个问题,如何解决RabbitMQ中消息延时过期失效的问题?
派大星:RabbitMQ有一个TTL过期时间,关掉不要开启TTL。