阿里云消息队列RocketMQ版消息轨迹显示消费结果未返回

1、

 

2、

【问题原因】: 消费消息的方法尚未返回结果,或者中断,导致本次消费结果未传回服务端。 【建议方案】: 建议您不要把业务逻辑放在返回给 mq 服务端的代码之前,最好是保证尽快给 到 mq 响应。这样可以避免消息消费失败,在进行消息重试。如果您的业务逻辑时间 的确很长,建议您可以将信息拉取到之后,存到数据库、redis 当中,然后尽快给到 mq ackMessage,之后再异步进行业务消费。

3、

package com.pojo.prj.aliyun.ons;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.mq.http.MQConsumer;
import com.aliyun.mq.http.common.AckMessageException;
import com.aliyun.mq.http.model.Message;
import com.pojo.common.core.utils.StringUtils;
import com.pojo.prj.aliyun.lot.DeviceServiceFactory;
import com.pojo.prj.aliyun.lot.service.DeviceConsumeService;
import com.pojo.common.core.enums.DeviceTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Slf4j
public class RocketMQMsgHandler implements Runnable {
    MQConsumer mqConsumer;

    @Override
    public void run() {
        while (true) {
            List<Message> messages = null;
            // 长轮询消费消息
            // 长轮询表示如果topic没有消息则请求会在服务端挂住3s,3s内如果有消息可以消费则立即返回
            try {
                messages = mqConsumer.consumeMessage(
                        1,// 一次最多消费1条(最多可设置为16条)
                        5// 长轮询时间5秒(最多可设置为30秒)
                );
            } catch (Exception e) {
                //获取消息失败 重连 todo 目前没有环境测试
                log.error("获取消息失败====" + e.getMessage() + "====" + e.getClass());
            }

            // 没有消息
            if (CollUtil.isEmpty(messages)) {
                continue;
            }


            // Message.nextConsumeTime前若不确认消息消费成功,则消息会重复消费
            // 消息句柄有时间戳,同一条消息每次消费拿到的都不一样
            List<String> handles = Lists.newArrayList();
            for (Message message : messages) {
                handles.add(message.getReceiptHandle());
            }

            try {
                mqConsumer.ackMessage(handles);
            } catch (Throwable e) {
                // 某些消息的句柄可能超时了会导致确认不成功
                if (e instanceof AckMessageException) {
                    AckMessageException errors = (AckMessageException) e;
                    log.error("Ack message fail, requestId is:" + errors.getRequestId() + ", fail handles:");
                    if (errors.getErrorMessages() != null) {
                        for (String errorHandle : errors.getErrorMessages().keySet()) {
                            log.error("Handle:" + errorHandle + ", ErrorCode:" + errors.getErrorMessages().get(errorHandle).getErrorCode()
                                    + ", ErrorMsg:" + errors.getErrorMessages().get(errorHandle).getErrorMessage());
                        }
                    }
                    continue;
                }
                e.printStackTrace();
                continue;
            }

            // 处理业务逻辑
            for (Message message : messages) {
                String str = new String(message.getMessageBodyBytes(), StandardCharsets.UTF_8);
                JSONObject object = JSONObject.parseObject(str);
                String devicetype = object.getString("devicetype");
                if (Objects.equals(devicetype, "ZHLZ02")) {
                    devicetype = "ZHLZ01";
                    object.put("devicetype", "ZHLZ01");
                }
                if (StringUtils.isNotBlank(devicetype)) {
                    DeviceConsumeService service = DeviceServiceFactory.getInstance(DeviceTypeEnum.getValue(devicetype));
                    if (Objects.nonNull(service)) {
                        service.consume(object);
                    }
                }
            }

        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非ban必选

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值