京东内部有专门负责发送消息和接收消息的中间件JMQ。
消息中间件,功能目标都是相同的,2个系统之间解耦,通过异步消息的方式,完成信息同步。比如,常见的本地事务+消息队列,间接实现分布式事务,保证最终的数据一致性。
以开发业务为目标的话,开发者更加侧重技术的使用。
技术越简单,上手越快,才更能普及推广。
一、消息的生产者
1、定义消息的传输通道
<jmq:transport id="cavJmqTransport" address="${jmq.cavTransportAddress}"
user="${jmq.cavTransportUser}" password="${jmq.cavTransportPassword}" app="${jmq.cavTransportApp}" />
2、定义消息的发送者
<jmq:producer id="messageProducer" retryTimes="${jmq.cavTransportRetryTimes}" transport="cavJmqTransport" />
3、业务代码
把中间件封装的消息生产者messageProducer注入到service中,
构造1个消息体Message对象(主题、内容、业务id),发送完事。
只要调用方法成功,消息就进入到了消息服务的后台,消息服务保证“消息必达”。
如果接收方出了故障,消息服务自己负责重发。
@Service
public class BlacklistServiceJmq {
private Logger logger = Logger.getLogger(getClass());
@Resource
private MessageProducer messageProducer;
private String topic="cav_blacklist";
public void sync(BlacklistBeanJmq blacklistBeanJmq) throws JMQException {
logger.info("Send blacklist by jmq,start");
String text = JSONObject.toJSONString(blacklistBeanJmq);
Message message = new Message(topic, text , blacklistBeanJmq.getId()+"");
messageProducer.send(message);
logger.info("Send blacklist by jmq,end");
}
}
4、属性文件
jmq.properties
#dev
jmq.cavTransportApp=Ca016
jmq.cavTransportAddress=192.168.8.8:8888
jmq.cavTransportUser=jmq
jmq.cavTransportPassword=jmq
jmq.cavTransportRetryTimes=3
二、消息的消费者
1、定义消息的传输通道
<jmq:transport id="cavJmqTransport" address="${jmq.cavTransportAddress}"
user="${jmq.cavTransportUser}" password="${jmq.cavTransportPassword}" app="${jmq.cavTransportApp}" />
2、定义消息的接收者和关注的主题Topic
<jmq:consumer id="messageConsumer" transport="cavJmqTransport">
<jmq:listener topic="cav_blacklist" listener="cavBlacklistMessageListener" />
</jmq:consumer>
<bean id="cavBlacklistMessageListener" class="com.jd.cav.jmq.BlacklistMessageListenerDemo" />
3、业务代码
消息服务的客户端,从消息服务远程服务端,不断拉去消息,然后把消息传给咱们的业务监听器,每个业务负责自己的业务逻辑代码。
public class BlacklistMessageListenerDemo implements MessageListener{
private Logger logger = Logger.getLogger(getClass());
@Override
public void onMessage(List<Message> messages) throws Exception {
if(CollectionUtils.isEmpty(messages)){
return;
}
for(Message message:messages){
handleBlacklistMessage(message);
}
}
private void handleBlacklistMessage(Message message) {
String text=message.getText();
BlacklistBeanJmq blacklistBeanJmq=JSONObject.parseObject(text, BlacklistBeanJmq.class);
System.out.println(blacklistBeanJmq);
}
}
4、属性配置
jmq.cavAppointmentApp=cavappointment
jmq.cavAppointmentTransportAddress=192.168.6.40:66666
jmq.cavAppointmentUser=cavappointment
jmq.cavAppointmentPassword=6DFB7254
特别需要说明的是,生产者的App名称、账号和密码,与消费者的都是不同的。
因为,生产者是固定的1个,而消费者可以有很多个。
不同的消费者,是否需要接入、接入之后什么时候关闭,都是它自己输了算。
另外,消息服务的IP地址通常是一样的。
三、用户的后台管理
申请消息服务主题、账号、密码。
查看消息历史记录、生产者监控、消费者监控等。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)