-
消息中间件作用:异步化提升性能、降低耦合度、流量削峰。
-
系统A发送消息给中间件,工作完成,不用管系统B什么时候操作,系统B拉取消息后,执行操作也不用告诉系统A执行结果,整个过程异步调用。
-
消息中间件相当于在中间插入一个接口约束,应用需求变化时可以独立修改两边的处理过程,只需确保他们遵守同样的接口约束。
-
在访问量剧增时,使用消息队列可以顶住突发的访问压力。
-
-
JMS : Java Message Service 一种消息队列规范
-
ConnectionFactory:连接工厂,客户端用来创建连接的对象。
-
Connection JMS 客户端到JMS服务端的连接
-
Session 会话 由Connection创建,实质为一个发送,接收消息的线程。生产者消费者都是用Session创建的。
-
Destination:消息目标 要么是queue消息队列 p2p点对点模式 要么是topic 发布订阅模式 pub/sub。 queue中,消费者无论是否离线后面都可以收到消息,topic只能消费自它订阅后发布的消息。
-
JMS消息组成:消息头、消息属性、消息体。 消息的类型:
-
TextMessage:文本消息
-
MapMessage:k/v
-
BytesMessage:字节流
-
StreamMessage:数据流
-
ObjectMessage:序列化的java对象
-
-
JMS结构流程
-
生产者:
-
创建工厂对象,指定ActiveMq ip地址和端口号 ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.11.186:61616")
-
使用连接工厂创建连接对象 Connection connection = connectionFactory.createConnection()
-
开启连接 使用连接对象创建会话对象,在创建会话时可以指定是否开启事务以及设置消息的签收方式) connection.start() Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);后面加重的表示自动签收
-
使用会话对象创建目标对象 destination包括queue和topic-一对一和一对多 Topic topic = session.createTopic(TOPIC_NAME);
-
使用会话对象创建生产者对象 MessageProducer producer = session.createProducer(topic)
消费者则createConsumer(topic)
-
使用会话对象创建消息对象 TextMessagetextMessage=session.createTextMessage("hello!test-topic"); 发送消息,关闭资源。 producer.send(textMessage); 注意此种创建的式TextMessage,也可以是MapMessage,StreamMessage等,接收端要以对应方式接收。
不开启事务,执行send方法就进入队列,开启事务后需要session.commit()才会提交到队列。
try{send .comit} catch{.rollback}
-
若是消费者则在创建完后订阅主题
-
.receive式,此种消费方式在接收消息之前一直阻塞
while(true){ //接收队列或主题的消息 TextMessage textMessage = (TextMessage) messageConsumer.receive(); if(textMessage != null){ //获取消息中的数据 String text = textMessage.getText(); System.out.println(text); }else{ break;} }
-
异步监听式,消息到达后自动调用onMessage方法
messageConsumer.setMessageListener(new MessageListener() { public void onMessage(Message message) { if(message != null && message instanceof TextMessage){ //获取消息并通过消息获得数据 TextMessage textMessage = (TextMessage) message;
(如果发送的是MapMessage则就是MapMessage mapMessage...)
try { System.out.println(textMessage.getText()); } catch (JMSException e) { e.printStackTrace();
-
除了消息字段以外,还可以使用消息属性-常用于识别,去重,重点标注。textMessage.setStringProperty("name", "property")
-
ActiveMq消息存储和持久化
为避免意外宕机丢失信息,消息中心首先将消息存储到本地数据文件等,再试图将消息发给接收者,成功了就删除存储信息,失败继续发送。默认方式为KahaDB日志文件方式。
2024.7.16