在项目中将1系列复杂、耗时的操作 可以使用ActiveMQ发送异步消息,进行处理,减少程序后台交互时间
1.导入ActiveMQ相关依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>4.0.0.RELEASE</version> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-pool</artifactId> <version>5.9.0</version> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-all</artifactId> <version>5.9.0</version> </dependency> <dependency> <groupId>org.apache.xbean</groupId> <artifactId>xbean-spring</artifactId> <version>3.16</version> </dependency>
2.根据功能需要编写ActiveMQ消息发送端
public class QueueSender { public static void sendQueue(int customerUuid){ Connection connection = null; Session session = null; try { ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616"); connection = connectionFactory.createConnection(); connection.start(); session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); Destination destination = session.createQueue("order-queue"); MessageProducer producer = session.createProducer(destination); TextMessage message = session.createTextMessage(""+customerUuid); //通过消息生产者发出消息 producer.send(message); session.commit(); }catch (Exception e){ e.printStackTrace(); }finally { if(session != null){ try { session.close(); } catch (JMSException e) { e.printStackTrace(); } } if(connection != null){ try { connection.close(); } catch (JMSException e) { e.printStackTrace(); } } } } }
其中ActiveMQ地址可以配置在配置文件中,提供多个服务地址(集群)在多访问情况下,实现负载均衡
3.ActiveMQ消息接受端
@Component public class QueueReceiver implements ServletContextListener{ @Autowired private ICartService ics; @Autowired private IStoreService iss; @Autowired private IOrderDetailService iods; @Autowired private IOrderService ios; public void receiveQueue(){ Connection connection = null; final Session session; try { ConnectionFactory cf = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616"); connection = cf.createConnection(); connection.start(); session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); Destination destination = session.createQueue("my-queue"); MessageConsumer consumer = session.createConsumer(destination); consumer.setMessageListener(new MessageListener() { public void onMessage(Message message) { try { TextMessage msg = (TextMessage)message; int customerUuid = Integer.parseInt(msg.getText()); CartQueryModel cqm = new CartQueryModel(); cqm.getPage().setPageShow(1000); cqm.setCustomerUuid(customerUuid); Page<CartModel> page = ics.getByConditionPage(cqm); //2: float totalMoney = 0.0f; for(CartModel cm : page.getResult()){ totalMoney += 10; } OrderModel order = new OrderModel(); order.setCustomerUuid(customerUuid); order.setOrderTime(DateFormatHelper.long2Str(System.currentTimeMillis())); order.setSaveMoney(0.0F); order.setTotalMoney(totalMoney); order.setState(1); ios.create(order); // OrderQueryModel oqm = new OrderQueryModel(); // oqm.setOrderTime(order.getOrderTime()); // Page<OrderModel> orderPage = getByConditionPage(oqm); // order = orderPage.getResult().get(0); //3: for(CartModel cm : page.getResult()){ OrderDetailModel odm = new OrderDetailModel(); odm.setGoodsUuid(cm.getGoodsUuid()); odm.setOrderNum(cm.getBuyNum()); odm.setPrice(10.0f); odm.setMoney(odm.getPrice() * odm.getOrderNum()); odm.setSaveMoney(0.0f); odm.setOrderUuid(order.getUuid()); iods.create(odm);
synchronized (iss){//多线程并发时,减少库存的操作需要同步,否则会数量错误 //4: StoreModel storeModel = iss.getByGoodsUuid(cm.getGoodsUuid()); storeModel.setStoreNum(storeModel.getStoreNum() - odm.getOrderNum()); iss.update(storeModel); }//5: ics.delete(cm.getUuid()); } session.commit(); } catch (Exception e){ e.printStackTrace(); } } }); } catch (Exception e){ e.printStackTrace(); } finally { // 作为一个 servlet 监听器,在项目开始时启动,调用 receiveQueue 方法,监听 ActiveMQ 消息则 session 和 C 哦弄呢餐厅 不能关闭 /*session.close(); connection.close();*/ } } public void contextInitialized(ServletContextEvent servletContextEvent) { ApplicationContext ac = WebApplicationContextUtils. getWebApplicationContext(servletContextEvent.getServletContext()); QueueReceiver receiver = (QueueReceiver) ac.getBean( "queueReceiver"); receiver.receiveQueue(); } public void contextDestroyed(ServletContextEvent servletContextEvent) { }}
将消息接受端,配置成了Servelt监听器,是为了在项目启动时,调用receiveQueue方法,监听ActiveMQ的消息
4.在web.xml中添加监听器
<listener> <listener-class> com.lb.architecture1.ordermgr.queue.QueueReceiver </listener-class> </listener>