目录
前言
消息中间件,主要用于降低调用方和服务之间的耦合度,常用的中间件有activeMQ,rabbitMQ
这里我们使用的就是activeMQ,而jms只是一个规范,就和JDBC和msql驱动包的关系
比如快递,快递员送东西来了,但是你现在没空,所以快递员会把东西放到一个地方,比如菜鸟裹裹,然后我们下班再去拿
这样就会方便很多
spring jms 进阶 https://blog.csdn.net/yzj17025693/article/details/90490161
jms介绍
下面是一个简单的项目的项目依赖图
后台依赖于服务,运营商后台同时依赖4个服务,这就意味着耦合度高,消息中间件就能够降低这种耦合度
经过中间件后的图
可以看到这时候的运营商后台不经过注册中心(zookeeper),原本4个服务都启动了
运营商后台才能使用,现在只需要activeMQ和运营商后台通信了即可
jms的规范
activeMQ
activeMQ运行在linux下,只需要解压并启动即可
activeMQ后台管理页面是ip+8161
后台的用户名和密码均为admin
点对点模式演示
点对点模式,一般是在消息只需要传递一次的情况下使用的
消息提供者的创建
引入依赖
创建测试类
端口61616是activeMQ默认的端口
运行之后,在管理后台刷新一下,就能看到数字发送了编号,等待接收的消息有1条,进入队列的消息有1条
消费者数量是0,消费者消费的消息也为0,其次消费者数量是动态的,也就是如果消费者断开连接关闭资源了,这里就不再计数了
消息消费者的创建
后面的等待键盘输入,是为了不让程序直接执行完毕,因为如果启动了消费者段,而提供者段还没运行,这时候监消费者端的监听
就监听不到数据了,因为已经执行完了,资源都关闭了
发布订阅模式
需要先启动消费者端,然后提供者端发消息,消费者端才能接受到消息,
消息提供者端
只需要在点对点模式上修改辰Topic即可
消费者端
spring jms点对点模式
spring jms是java的MQ规范,而activeMQ实现了这个规范,spring jms就是把spring和activeMQ整合了
提供者
配置文件applicationContext-jms-producer.xml
消息类
@Component
public class QueueProducer {
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private Destination queueTextDestination;
/**
*
发送文本消息
* @param text
*/
public void sendTextMessage(final String text){
jmsTemplate.send(queueTextDestination, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(text);
}
});
}
}
消息类
消费者
监听类
加载配置文件就能启动监听
spring jms订阅模式
提供者修改关键配置
消费者修改关键配置
中间件案例
点对点
一个方法里调用了2个服务,这2个服务同步调用,调用完上面就调用下面,所以就会有问题
需要用中间件改成异步调用,其次这个只需要接受一次,加入这个服务项目部署在很多服务器上
如果采用发布订阅,那么这个就会导入4次,但我们只需要导入一次,所以采用点对点的方式
消费提供者
把service可以删掉了
消费者的监控类
还需要在配置文件里配置消费者的配置和这个监听类
如果有多种消息,比如还有一个删除,那么就再配置一个消息监听容器,和一个监听类
@Component
public class ItemSearchListener implements MessageListener{
@Autowired
private ItemSearchService itemSearchService;
@Override
public void onMessage(Message message) {
System.out.println("监听接收到消息...");
try {
TextMessage textMessage=(TextMessage)message;
String text = textMessage.getText();
List<TbItem> list = JSON.parseArray(text,TbItem.class);
for(TbItem item:list){
System.out.println(item.getId()+" "+item.getTitle());
Map specMap= JSON.parseObject(item.getSpec());//将spec字段中的json字符串转换为map
item.setSpecMap(specMap);//给带注解的字段赋值
}
itemSearchService.importList(list);//导入
System.out.println("成功导入到索引库");
} catch (Exception e) {
e.printStackTrace();
}
}
}
发布订阅
比如页面生成服务,当我们使用freemark生成页面的时候,每台Nginx都要有对应的页面,这样才是集群
一台挂了,其它的继续使用,这时候就可以使用发布订阅
在controller一般是消息的提供者
消息的消费者