java.lang.MosuchfieldErrar: class com.sun.tools.javac.tree 解决错误 lombok依赖版本不兼容导致 面试题,rocket如何去重

解决错误 lombok依赖版本不兼容导致,pojo实体类中的data等注解影响报错

java: java.lang.NoSuchFieldError: Class com.sun.tools.javac.tree.JCTree$JCImport does not have member field ‘com.sun.tools.javac.tree.JCTree qualid’
在这里插入图片描述

<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.30</version>
		</dependency>

面试题,rocket如何去重

发送放需要给消息写带一个唯一标记(自己业务控制),消费者方需要控制消息的幂等性。

建立一个去重表,对于我们特定的字段加上唯一索引,然后消息一过来,直接插入,如果插入失败就代表已经消费过这个消息了(如果先判断的话,就不能保证原子性了,所以我们直接先新增,如果重复就会失败)

(我们设计一个去重表,对消息的唯一key添加唯一索引,每次消费消息的时候,先插入数据库,如果成功则执行业务逻辑,如果插入失败,则说明消息来过了,直接签收了)

上代码!

@SpringBootTest
class ARocketmqDemo1ApplicationTests {
    @Autowired
    private JdbcTemplate jdbcTemplate;
   @Test
    void sendMessage() throws Exception {
        DefaultMQProducer producer = new DefaultMQProducer("repeatA-producer-group");
        producer.setNamesrvAddr("192.168.88.128:9876");
        producer.start();
        String key = UUID.randomUUID().toString();
        Message message = new Message("repeatOptic", null, key, "扣减库存-1".getBytes());
        SendResult sendResult = producer.send(message);
        System.out.println("发送结果: " + sendResult);
        producer.shutdown();
    }

    @Test
    void receiveMessage() throws Exception {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("repeatA-consumer-group");
        consumer.setNamesrvAddr("192.168.88.128:9876");
        consumer.subscribe("repeatOptic", "*");
        consumer.registerMessageListener((List<MessageExt> msgs, ConsumeConcurrentlyContext context) -> {
            for (MessageExt messageExt : msgs) {
                System.out.println("收到消息 key: " + messageExt.getKeys());
                System.out.println("消息内容: " + new String(messageExt.getBody()));
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        });
        consumer.start();
        System.in.read(); // 让消费者保持运行
    }
}

消费重复

消息的结构:
在这里插入图片描述


/**
 * 重试机制
 * 1.重试的延时间隔:10s,20s,30s,1m,2m,3m,4m,5m,6m,7m,8m,9m,10m,20m,30m,1h,2h,3h,4h,5h,6h,7h,8h,9h,10h,20h,1d,
 * 分级别的重试,重试次数为16次(一般五六次)
 * 如果重试16次后,还是失败,则进入死信队列(并发模式)  顺序模式下(int最大值次)都是失败的   是一个死信消息
 *则会放到一个死信主题中%DLQ%+你的组名
 * 2.能否自定义重试次数
 *
 * 3.当消息重试次数达到16次后,进入死信队列,死信队列可以用来做消息的补偿
 *
 *------------------
 * 重试的次数一般写5次
 */
public class IRetryTest {
    @Test
    public void retryProducer() throws  Exception{
        DefaultMQProducer producer = new DefaultMQProducer("retry-producer-group");
        producer.setNamesrvAddr(MqConstant.NAME_SRV_ADDR);
        producer.start();
        //生产者发送消息,重试次数  2(默认值)
        producer.setRetryTimesWhenSendFailed(2);
        producer.setRetryTimesWhenSendAsyncFailed(2);
        String key = UUID.randomUUID().toString();
        System.out.println("key:"+key);
        Message message = new Message("retryTopic", "VIP1", key, "我是VIP11111111".getBytes());
        producer.send(message);
        System.out.println("发送成功");
        producer.shutdown();
    }
    @Test
    public void retryConsumer1() throws Exception{
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("retry-consumer-group");//消费者组名,信息会一个组一份
        consumer.setNamesrvAddr(MqConstant.NAME_SRV_ADDR);
        consumer.subscribe("retryTopic","*" );//订阅不同的消息

        //设定重试次数
        consumer.setMaxReconsumeTimes(2);

        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                MessageExt messageExt = msgs.get(0);
                System.out.println(new Date());
                System.out.println("消费消息:" + new String(messageExt.getBody()));
                //打印重试的次数 重试从第二次开始
                System.out.println(messageExt.getReconsumeTimes());
                //业务报错了   返回null  返回 RECONSUME_LATER 都会重试
                return ConsumeConcurrentlyStatus.RECONSUME_LATER;
            }
        });
        consumer.start();
        System.in.read();
    }
直接监听死信队列
    @Test
    public void retryDeadConsumer1() throws Exception{
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("retry-dead-consumer-group");//消费者组名,信息会一个组一份
        consumer.setNamesrvAddr(MqConstant.NAME_SRV_ADDR);
        consumer.subscribe("%DLQ%retry-consumer-group","*" );//订阅不同的消息

        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                MessageExt messageExt = msgs.get(0);
                System.out.println(new Date());
                System.out.println("消费消息:" + new String(messageExt.getBody()));
                System.out.println("记录到特别的位置  文件 mysql  通知人工处理");
                //业务报错了   返回null  返回 RECONSUME_LATER 都会重试
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        consumer.start();
        System.in.read();
    }

    /**
     * 第二种方案  用的多
     * @throws Exception
     */
    @Test
    public void retryConsumer2() throws Exception{
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("retry-consumer-group");//消费者组名,信息会一个组一份
        consumer.setNamesrvAddr(MqConstant.NAME_SRV_ADDR);
        consumer.subscribe("retryTopic","*" );//订阅不同的消息

        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                MessageExt messageExt = msgs.get(0);
                System.out.println(new Date());

                try {
                    handleDb();
                }catch (Exception e){
            //重试
                    int reconsumeTimes = messageExt.getReconsumeTimes();
                    if (reconsumeTimes<=3){
                        //不要重试了
                        System.out.println("重试次数超过3次了,记录到数据库,人工处理");
                        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                    }
                    //业务报错了   返回null  返回 RECONSUME_LATER 都会重试
                    return ConsumeConcurrentlyStatus.RECONSUME_LATER;
                }

                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;

            }

            private void handleDb() {
                int i = 10 / 0;

            }
        });
        consumer.start();
        System.in.read();
    }
}

  • 17
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值