京东消息队列JCQ(消息推送服务)对接流程

京东消息队列JCQ(消息推送服务)对接流程

一、订阅消息

二、引入依赖

<dependencies>
    <dependency>
        <groupId>com.jdcloud</groupId>
        <artifactId>jcq-java-sdk</artifactId>
        <version>1.3.5</version>
    </dependency>
</dependencies>

三、SDK接入公共类(核心封装)

import com.jcloud.jcq.client.Exception.ClientException;
import com.jcloud.jcq.client.consumer.MessageListener;
import com.jcloud.jcq.common.consumer.ConsumeFromWhere;
import com.jcloud.jcq.protocol.Message;
import com.jcloud.jcq.sdk.JCQClientFactory;
import com.jcloud.jcq.sdk.auth.UserCredential;
import com.jcloud.jcq.sdk.consumer.Consumer;
import com.jcloud.jcq.sdk.consumer.ConsumerConfig;
import org.springframework.boot.CommandLineRunner;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 京东云鼎消息队列线程公共类
 * JCQ = JD Cloud Queue
 */
public class JCQRunner implements CommandLineRunner {

    /** 用户accessKey(需替换为实际值) */
    public static final String ACCESS_KEY = "<你的accessKey>";

    /** 用户secretKey(需替换为实际值) */
    public static final String SECRET_KEY = "<你的secretKey>";

    /** 元数据服务器地址(需替换为实际值) */
    public static final String META_SERVER_ADDRESS = "<你的元数据服务器地址>";

    /** 消费组id(需替换为实际值) */
    public static final String CONSUMER_GROUP = "<你的消费组id>";

    /**
     * 创建消费者实例
     * @return 配置完成的Consumer对象
     * @throws ClientException 客户端配置异常
     */
    public Consumer buildConsumer() throws ClientException {
        // 1. 初始化用户凭证
        UserCredential userCredential = new UserCredential(ACCESS_KEY, SECRET_KEY);
        
        // 2. 构建消费者配置
        ConsumerConfig consumerConfig = ConsumerConfig.builder()
                .consumerGroupId(CONSUMER_GROUP)
                .metaServerAddress(META_SERVER_ADDRESS)
                .enableMessageTrace(false)                          // 启用消息轨迹, 默认关闭。消息轨迹是异步发送的,强制关掉进程,可能会有轨迹丢失
                .defaultConsumePosition(ConsumeFromWhere.HEAD)      // 从哪里开始消费?ConsumeFromWhere.HEAD,ConsumeFromWhere.TAIL,默认值是HEAD。这个参数仅在第一次消费是起作用
                .consumePoolCoreSize(4)                             // JCQ是异步消费逻辑,推给客户端的消息。会交由消费线程池处理,这里指消费线程池的大小,默认值是4
                .consumeMaxRetryTimes(3)                            // 自动消费重试次数,JCQ是异步消费逻辑,推给客户端的消息,交由消费线程池消费。默认值是3。正常消费失败之后才算重试,所以最多消费次数是consumeMaxRetryTimes + 1
                .maxBatchSizePerPush(1)                             // 服务端一批推送的消息数,默认是1
                .messageBufferSize(1024)                            // 客户端消费线程池队列数,从推送到消费之间能缓存多少个请求,默认值是1024
                .ackPoolCoreSize(2)                                 // ACK也是异步的,这里指回ACK请求的线程池的线程数量,默认值是2
                .ackBufferSize(1024)                                // ACK 线程池队列数,默认值是1024
                .build();
        
        // 3. 创建并返回消费者对象
        return JCQClientFactory.getInstance().createConsumer(userCredential, consumerConfig);
    }

    /**
     * 启动消息监听
     * @param topic 订阅的topic名称
     * @param listener 消息处理监听器
     * @throws Exception 监听启动异常
     */
    public void listen(String topic, MessageListener listener) throws Exception {
        final Consumer consumer = this.buildConsumer();
        // 订阅主题并绑定监听器
        consumer.subscribeTopic(topic, listener, null);
        // 启动消费者
        consumer.start();
        
        // 注册JVM关闭钩子:优雅关闭消费者
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    consumer.shutdown();
                } catch (ClientException e) {
                    e.printStackTrace();
                }
            }
        }));
    }

    /**
     * 解析消息体(字节数组转字符串)
     * @param list 原始消息列表
     * @return 解析后的字符串列表
     */
    public List<String> parseMessage(List<Message> list) {
        if (list == null || list.isEmpty()) {
            return null;
        }
        return list.stream()
                .map(message -> new String(message.getBody(), StandardCharsets.UTF_8))
                .collect(Collectors.toList());
    }

	/**
     * Callback used to run the bean.
     *
     * @param args incoming main method arguments
     * @throws Exception on error
     */
    @Override
    public void run(String... args) throws Exception {
        // 由子类重写实现具体业务逻辑
    }
}

四、测试子类(业务实现)

import com.alibaba.fastjson.JSONObject;
import com.jcloud.jcq.client.consumer.ConsumeResult;
import com.jcloud.jcq.client.consumer.MessageListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

/**
 * 京东云鼎消息队列线程实现类
 * JCQ = JD Cloud Queue
 */
@Slf4j
@Component
public class JDRunner extends JCQRunner {

    /**
     * Topic名称格式:<tenantId>$<Namespace>$<Topic名称>(需替换为实际值)
     */
    public static final String TOPIC = "<你的tenantId>$<你的Namespace>$<你的Topic名称>";

    /** 注入业务处理服务 */
    @Resource
    private Service service;

	/**
     * Callback used to run the bean.
     *
     * @param args incoming main method arguments
     * @throws Exception on error
     */
    @Override
    public void run(String... args) throws Exception {
        try {
            // 1. 定义消息监听器
            MessageListener listener = list -> {
                log.info("收到原始消息:{}", list);
                
                // 2. 解析消息
                List<String> result = super.parseMessage(list);
                log.info("解析后消息:{}", JSONObject.toJSONString(list));
                
                // 3. 业务处理
                Boolean handleResult = service.handle(result);
                
                // 4. 返回处理结果(SUCCESS/FAILED)
                return handleResult ? ConsumeResult.SUCCESS : ConsumeResult.FAILED;
            };
            
            // 5. 启动监听
            this.listen(TOPIC, listener);
        } catch (Exception e) {
            log.error("京东订阅消息监听失败:", e);
        }
    }
}

五、注意事项

  1. 网络连通性
    SDK仅能在京东云鼎环境内调用,部署前需在云鼎服务器测试连通性(ping 元数据服务器地址)。
    如果连接超时,说明安全组端口未开放,需检查安全组端口配置。
    参考京东官方文档:常见问题 的Q13。
    文档里写的ACL没配置过可以不配置。

  2. Topic格式
    必须按照 <tenantId>$<Namespace>$<Topic名称> 格式填写,否则可能会报“Topic不存在”错误。
    参考京东官方文档:常见问题 的Q14第4点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值