zoukankan      html  css  js  c++  java
  • 消息队列面试专题

    怎么样可以避免重复消费

    RocketMQ 不保证消息不重复,如果你的业务需要保证严格的不重复消息,需要你自己在业务端去重

    接口幂等性保障 ,消费端处理业务消息要保持幂等性

    Redis

    1)setNX(),做消息 id 去重,java 版本目前不支持设置过期时间

    //Redis中操作,判断是否已经操作过 TODO
    boolean flag = jedis.setNX(key);
    if(flag){
        //消费
    }else{
        //忽略,重复消费
    }

    拓展(如果再用 expire 则不是原子操作,可以用下面方式实现分布式锁)

    加锁
    String result = jedis.set(key, value, "NX", "PX", expireTime)
    
    解锁(Lua脚本,先检查key,匹配再释放锁,lua可以保证原子性)
    String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
    Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
    
    备注:lockKey可以是商品id,requestId用于标示是同个客户端

    2)Incr 原子操作:key自增,返回值大于0则说明消费过

    int num = jedis.incr(key);
    if(num == 1){
        /消费
    }else{
        //忽略,重复消费
    }

    上述两个方式都可以,但是不能用于分布式锁,考虑原子问题,但是排重可以不考虑原子问题,数据量多需要设置过期时间。

    数据库去重表

    某个字段使用 Message 的 key 做唯一索引

    如何保证消息的可靠性,处理消息丢失的问题

    producer 端

    • 不采用 oneway 发送,使用同步或者异步方式发送,做好重试,但是重试的 Message key 必须唯一
    • 投递的日志需要保存,关键字段,投递时间、投递状态、重试次数、请求体、响应体

    broker 端

    • 双主双从架构,NameServer 需要多节点
    • 同步双写、异步刷盘 (同步刷盘则可靠性更高,但是性能差点,根据业务选择)

    consumer 端

    • 消息消费务必保留日志,即消息的元数据和消息体
    • 消费端务必做好幂等性处理

    投递到 broker 端后

    • 机器断电重启:异步刷盘,消息丢失;同步刷盘消息不丢失
    • 硬件故障:可能存在丢失,看队列架构

    如果消息大量堆积在 broker 里面,应该怎么处理

    线上故障了,怎么处理

    • 消息堆积了10小时,有几千万条消息待处理,现在怎么办?
    • 修复 consumer,然后慢慢消费?也需要几小时才可以消费完成,新的消息怎么办?

    正确的姿势

    • 临时 Topic 队列扩容,并提高消费者能力,但是如果增加 Consumer 数量,但是堆积的 topic 里面的 message queue 数量固定,过多的 consumer 不能分配到 message queue
    • 编写临时处理分发程序,从旧 Topic 快速读取到临时新 Topic 中,新 Topic 的 queue 数量扩容多倍,然后再启动更多 consumer 进行在临时新的 Topic 里消费

    RocketMQ 高性能的原因分析,高可用架构

    MQ架构配置

    • 顺序写,随机读,零拷贝
    • 同步刷盘 SYNC_FLUSH 和异步刷盘 ASYNC_FLUSH,通过 flushDiskType 配置
    • 同步复制和异步复制,通过 brokerRole 配置 ASYNC_MASTER、SYNC_MASTER、SLAVE
    • 推荐同步复制(双写),异步刷盘

    发送端高可用

    • 双主双从架构:创建 Topic 对应的时候,MessageQueue 创建在多个 Broker 上
    • 即相同的 Broker 名称,不同的 brokerid(即主从模式)当一个 Master 不可用时,组内其他的 Master 仍然可用。
    • 但是机器资源不足的时候,需要手工把 slave 转成 master,目前不支持自动转换,可用 shell 处理

    消费高可用

    • 主从架构:Broker 角色,Master 提供读写,Slave 只支持读
    • Consumer 不用配置,当 Master 用或者繁忙的时候,Consumer 会自动切换到 Slave 节点进行能读取

    提高消息的消费能力

    • 并行消费
      • 增加多个节点
      • 增加单个 Consumer 的并行度,修改 consumerThreadMin 和 consumerThreadMax
      • 批量消费,设置 Consumer 的 consumerMessageBatchMaxSize,默认是1,如果为N,则消息多的时候,每次收到的消息为N条
    • 选择 Linux Ext4 文件系统,Ext4 文件系统删除 1G 大小的文件通常耗时小于 50ms,而 Ext3文件系统耗时需要 1s,删除文件时磁盘IO 压力极大,会导致 IO 操作超时
  • 相关阅读:
    Asp.Net服务器控件开发的Grid实现(四)回发事件
    Win8的IIS中架设php
    jsonp其实很简单【ajax跨域请求】
    Asp.Net服务器控件开发的Grid实现(三)列编辑器
    Asp.Net服务器控件开发的Grid实现(二)Html标记渲染
    构建之法阅读笔记01
    四则运算2
    psp0
    随机生成30道四则运算
    学习进度条
  • 原文地址:https://www.cnblogs.com/jwen1994/p/12386430.html
Copyright © 2011-2022 走看看