京东消息队列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;
public class JCQRunner implements CommandLineRunner {
public static final String ACCESS_KEY = "<你的accessKey>";
public static final String SECRET_KEY = "<你的secretKey>";
public static final String META_SERVER_ADDRESS = "<你的元数据服务器地址>";
public static final String CONSUMER_GROUP = "<你的消费组id>";
public Consumer buildConsumer() throws ClientException {
UserCredential userCredential = new UserCredential(ACCESS_KEY, SECRET_KEY);
ConsumerConfig consumerConfig = ConsumerConfig.builder()
.consumerGroupId(CONSUMER_GROUP)
.metaServerAddress(META_SERVER_ADDRESS)
.enableMessageTrace(false)
.defaultConsumePosition(ConsumeFromWhere.HEAD)
.consumePoolCoreSize(4)
.consumeMaxRetryTimes(3)
.maxBatchSizePerPush(1)
.messageBufferSize(1024)
.ackPoolCoreSize(2)
.ackBufferSize(1024)
.build();
return JCQClientFactory.getInstance().createConsumer(userCredential, consumerConfig);
}
public void listen(String topic, MessageListener listener) throws Exception {
final Consumer consumer = this.buildConsumer();
consumer.subscribeTopic(topic, listener, null);
consumer.start();
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
try {
consumer.shutdown();
} catch (ClientException e) {
e.printStackTrace();
}
}
}));
}
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());
}
@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;
@Slf4j
@Component
public class JDRunner extends JCQRunner {
public static final String TOPIC = "<你的tenantId>$<你的Namespace>$<你的Topic名称>";
@Resource
private Service service;
@Override
public void run(String... args) throws Exception {
try {
MessageListener listener = list -> {
log.info("收到原始消息:{}", list);
List<String> result = super.parseMessage(list);
log.info("解析后消息:{}", JSONObject.toJSONString(list));
Boolean handleResult = service.handle(result);
return handleResult ? ConsumeResult.SUCCESS : ConsumeResult.FAILED;
};
this.listen(TOPIC, listener);
} catch (Exception e) {
log.error("京东订阅消息监听失败:", e);
}
}
}
五、注意事项
-
网络连通性:
SDK仅能在京东云鼎环境内调用,部署前需在云鼎服务器测试连通性(ping 元数据服务器地址)。
如果连接超时,说明安全组端口未开放,需检查安全组端口配置。
参考京东官方文档:常见问题 的Q13。
文档里写的ACL没配置过可以不配置。
-
Topic格式:
必须按照 <tenantId>$<Namespace>$<Topic名称> 格式填写,否则可能会报“Topic不存在”错误。
参考京东官方文档:常见问题 的Q14第4点。