现在很多人都喜欢上网购物,当然对我这种喜欢便宜的人来说,双十一,节假日抢购无疑是我的最爱。但是对于全国这么多人来说
大家都争先恐后地去抢一件上平,那服务器还不得炸了才怪;所以今天我就来说说用消息服务来处理这个问题。用户发送请求后,服务器
接到请求后,向消息队列发送一个消息,就立刻返回“订单正在处理”的消息给客户。而订单服务则不停的从消息队列中取出消息,按照自己
的节奏去处理订单,从而有效的避免了高峰期!!!
1 什么是JMS
java消息服务(Java Message Service, JMS)是一个允许应用创建、发送、接收和读取消息的Java API
好了,那么怎么去更好地理解他呢?
例如,一个汽车企业中某个库存量低于某个等级时,库存组件可以向工厂发送一个消息,使工厂产生更多的汽车
工厂组件可以向部件发送一个消息,使得工厂可以装配它需要的的部件
部件组件可以进一步向他们自己的库存和订单组件发送消息跟新库存
。。。。
通过消息传送来完成这些任务,不同组件之间可以高效地交互,而不需要占用网络或其他资源。
2 JMS的架构
JMS应用由以下部分组成
JMS提供者:是一个实现JMS接口的消息传送系统,提供管理和控制特性
JMS客户端:是用Java编程语言编写的程序和组件,可以生成(生产)和使用(消费)消息
消息:是在JMS客户端之间传递信息的对象
受管理对象:是为客户端配置的JMS对象,有两类JMS受管理
对象:目的工厂(destination) 和 连接工厂(connection factory)
3 发送方式
(1) 点对点(point to point)
* 每个消息只有一个消费者(即使用方)
* 接收者可以获取消息,而不论客户端发送消息时接收者是否在运行
所以说如果你发送一个每一个消息都必须由一个消费者成功地处理,就可以使用PTP消息传送
(2) 发布/订阅消息传送方式
* 每个消息可以有多个消费者
* 对于订阅一个主题的客户端,只有这个客户端创建一个订阅之后才能使用锁发送的消息,消费者必须保持活动状态才能使用消息
(对于这种情况相对与上一种要复杂一点。只有创建了共享订阅才能被多个订阅者订阅)
所以如果消息可以由任意多个消费者(或者没有任何消费者)处理,就可以使用发布/订阅消息传送方式
4 消息的接收
消息产品本质上市异步的:在消息的生成和使用之间并没有时间依赖关系,不过JMS还是提供了两种方案
(1)同步:消息者通过调用receive方法,显式地从目的地获取消息。receive方法会阻塞,直到消息到达,或者如皋消息未在指定的时限内到达则会超时。
(2)异步:应用客户端或Java SE客户端可以向消费者注册一个消息监听器(messagelistener).消息监听器类似于事件监听器。一旦有消息到达目的地,JMS
提供者就通过调用这个监听器onMessage方法传送消息,这个方法会处理消息的内容。在一个Java EE应用中,消息驱动bean会作为消息监听器(它也有
一个onMessage方法),不过客户端不需要消费者注册这个监听器。
通这张图然后理解下面的例子就简单了
5 参数分析:
- 连接工厂(connection factory)是客户端用来创建连接的对象,客户端可以用它创建与一个提供者的连接。
- 目的地(destination) 客户端可以用目的地(destination)对象指定所生成消息的目标以及所使用的来源。在PTP消息传送方式中,目的地称为队列。
- 在发布/订阅消息传送方式中,目的地称为主题。JMS应用可以使用多个队列或主题*或者两者都使用)。
- 连接(connection) 封装了与一个JMS提供者的虚拟连接
- 会话(session) 是生成和使用消息的一个单线程上下文。有时会通过JMSContext或connection来创建一个会话
- 消息生产者:由JMSContext或会话创建的一个对象,用来向目的地发送消息。
- 消息消费者:由JMSContext或会话创建的一个对象,用来接收发送到一个目的地的消息
好了上酸菜:(点对点 + 同步接收)
package Test1; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnection; import org.apache.activemq.ActiveMQConnectionFactory; public class Consumer { public static void main(String[] args) throws JMSException{ //从连接工厂里获取连接 ConnectionFactory factory=new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,ActiveMQConnection.DEFAULT_PASSWORD,"tcp://localhost:61616"); Connection connection=factory.createConnection(); connection.start(); //创建会话 Session session=connection.createSession(true, Session.AUTO_ACKNOWLEDGE); //创建目的地,它是用来接收信息的:这里创建一个序列 Destination destination=session.createQueue("MyQueue"); //创建消费者 MessageConsumer consumer=session.createConsumer(destination); Message message=consumer.receive(); if(message!=null){ TextMessage text=(TextMessage) message; System.out.println("接收到了:"+text.getText()); } } }
package Test1; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageProducer; import javax.jms.Session; import org.apache.activemq.ActiveMQConnection; import org.apache.activemq.ActiveMQConnectionFactory; public class Produecer { public static void main(String[] args) throws JMSException{ //从连接工厂里获取连接 ConnectionFactory factory=new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,ActiveMQConnection.DEFAULT_PASSWORD,"tcp://localhost:61616"); Connection connection=factory.createConnection(); connection.start(); //创建会话 Session session=connection.createSession(true, Session.AUTO_ACKNOWLEDGE); //创建目的地,它是用来接收信息的:这里创建一个序列 Destination destination=session.createQueue("MyQueue"); //创建生产者 MessageProducer producer=session.createProducer(destination); //创建一个发送消息 Message message=session.createTextMessage("你好啊!!!|"); //发送 producer.send(message); //这里可别忘了,提交会话 session.commit(); System.out.println("信息发送成功"); } }
发布/订阅 +异步处理
package Subcriber; import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; public class TopicPublisher { public static void main(String[] args) throws JMSException { ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616"); Connection connection = factory.createConnection(); connection.start(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); Topic topic = session.createTopic("myTopic.messages"); MessageProducer producer = session.createProducer(topic); //创建非持久的订阅 producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); while(true) { TextMessage message = session.createTextMessage(); message.setText("message_" + System.currentTimeMillis()); producer.send(message); System.out.println("Sent message: " + message.getText()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } // session.close(); // connection.stop(); // connection.close(); } }
package Subcriber; import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; public class TopicSubscriber { public static void main(String[] args) throws JMSException { ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616"); Connection connection = factory.createConnection(); connection.start(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); Topic topic = session.createTopic("myTopic.messages"); MessageConsumer consumer = session.createConsumer(topic); consumer.setMessageListener(new MessageListener() { public void onMessage(Message message) { TextMessage tm = (TextMessage) message; try { System.out.println("Received message: " + tm.getText()); } catch (JMSException e) { e.printStackTrace(); } } }); // session.close(); // connection.stop(); // connection.close(); } }