学习ActiveMQ的使用

一、什么是ActiveMQ?

     ActiveMQ是Apache出品的,非常流行的开源消息中间件,ActiveMQ是一个完全支持JMS1.1和J2EE1.4规范的JMS Provider实现,(JMS是一个Java平台中关于面向消息中间件的API,用于两个应用程序之间,或分布式系统中发送消息,进行异步通信,仅仅定义了一系列的接口,ActiveMQ是对于JMS接口的一种实现)。

二、ActiveMQ的消息形式

     对于消息的传递有两种类型:

    1)点到点:一个生产者和一个消费者一一对应;(使用时生产者提供的消息会进行缓存,直到消费者使用)

    2)发布/订阅:一个生产者产生消息发送后,可以由多个消费者订阅接收;(使用时消息不进行缓存,所以消费者需要提前做好接收准备,否则消息会丢失)

    JMS定义了5种不同的消息正文格式:  

  • StreamMessage--Java原始值的数据流
  • MapMessage--一套名称-值对
  • TextMessage--一个字符串对象(最常用的消息格式)
  • ObjectMessage--一个序列化的Java对象
  • BytesMessage--一个字节的数据流

三、ActiveMQ的安装

     需要到官方网站下载安装包。

    使用时需要提前安装好Java环境即JDK,然后解压到执行目录即可使用。

    进入解压后文件的bin目录下,使用命令:./activemq start启动服务。

    服务启动后,activemq会自己提供一个管理后台,通过浏览器访问:http://ip:8161/admin,用户名:admin,

密码:admin。

四、ActiveMQ的使用

    1)首先引入activeMQ的maven依赖

<!-- activeMQ -->
<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-all</artifactId>
    <version>5.11.2</version>
</dependency>

    2)queue队列形式

    创建生产者Producer,创建消息,发送消息:

public void testQueueProducer() throws Exception {
   // 创建一个连接工厂对象,brokerURL代表activeMQ服务所在的URL地址,默认连接端口号61616
  ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.1.8:61616");
  // 创建一个连接对象
  Connection connection = connectionFactory.createConnection();
  // 开启连接
  connection.start();
  // 创建一个Session会话对象
  // 第一个参数是是否开启事物,一般不开启事物,保证数据的最终一致性,可以使用消息队列实现
  // 为fase的话第二个参数是消息的应答模式;为true的话第二个参数自动忽略
  Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  // 使用Session对象创建一个Destination对象,两种形式queue、topic
  // 参数是消息队列的名称
  Queue queue = session.createQueue("test-queue");
  // 使用Session对象创建一个Producer对象
  MessageProducer producer = session.createProducer(queue);
  // 创建一个TextMessage对象
  /*
   * TextMessage textMessage = new ActiveMQTextMessage();
   * textMessage.setText("hello activemq");
   */
  TextMessage textMessage = session.createTextMessage("hello activemq");
  // 发送消息
  producer.send(textMessage);
  // 关闭资源
  producer.close();
  session.close();
  connection.close();
}
    创建消费者,向消费者添加消息监听器,接收消息:
public void testQueueConsumer() throws Exception {
		// 创建一个连接工厂对象,brokerURL代表activeMQ服务所在的URL地址
		ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.1.8:61616");
		// 创建一个连接对象
		Connection connection = connectionFactory.createConnection();
		// 开启连接
		connection.start();
		// 创建一个Session回话对象
		// 第一个参数是是否开启事物,一般不开启事物,保证数据的最终一致性,可以使用消息队列实现
		// 为fase的话第二个参数是消息的应答模式;为true的话第二个参数自动忽略
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
		// 使用Session对象创建一个Destination对象,两种形式queue、topic
		// 参数是消息队列的名称
		Queue queue = session.createQueue("test-queue");
		// 使用Session对象创建一个Consumer对象
		MessageConsumer consumer = session.createConsumer(queue);
		// 向Consumer对象中设置一个MessageListener对象,用来接收消息
		consumer.setMessageListener(new MessageListener() {

			@Override
			public void onMessage(Message message) {
				// 取消息内容
				if (message instanceof TextMessage) {
					TextMessage textMessage = (TextMessage) message;
					try {
						String text = textMessage.getText();
						// 打印消息内容
						System.out.println(text);
					} catch (JMSException e) {
						e.printStackTrace();
					}
				}
			}
		});
		// 系统等待接收消息
		System.in.read();
		// 关闭资源
		consumer.close();
		session.close();
		connection.close();
}
     3)topic主题形式

    使用方式基本一样,区别在于创建Destination对象时,需要创建对应的Topic对象。

Topic topic = session.createTopic("test-topic");
// 使用Session对象创建一个Consumer对象
MessageConsumer consumer = session.createConsumer(topic);
Topic topic = session.createTopic("test-topic");
/ 创建Producer对象
MessageProducer producer = session.createProducer(topic);

五、spring整合ActiveMQ使用:

    1)引入相关的依赖jar包

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jms</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>

     2)具体以商品添加时,发送消息通知搜索服务更新索引库为例:

    生产者的spring配置文件中配置如下:

<!-- 真正可以产生Connection的ConnectionFactory,由JMS服务厂商提供的 -->		
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <constructor-arg name="brokerURL" value="tcp://192.168.1.8:61616"></constructor-arg>
</bean>
	
<!-- spring对象ConnectionFactory的封装 -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
    <property name="targetConnectionFactory" ref="targetConnectionFactory"></property>
</bean>
	
<!-- 配置JMSTemplate -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="connectionFactory"></property>
</bean>
	
<!-- 配置消息的Destination对象,使用Topic主题方式 -->
<bean id="itemAddTopic" class="org.apache.activemq.command.ActiveMQTopic">
    <constructor-arg name="name" value="item-add-topic"></constructor-arg>
</bean>

    使用时先注入JmsTemplate和Destination对象:

@Autowired
private JmsTemplate jmsTemplate;
@Resource(name = "itemAddTopic")
private Destination destination;
     向数据库中添加商品后执行以下代码发布消息:
// 向Activemq发送商品添加消息
jmsTemplate.send(destination, new MessageCreator() {
    @Override
    public Message createMessage(Session session) throws JMSException {
        // 发送商品id
        TextMessage textMessage = session.createTextMessage(id + "");
        return textMessage;
    }
});

    消费者的spring配置文件中配置如下:

<!-- 真正可以产生Connection的ConnectionFactory,由JMS服务厂商提供的 -->		
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <constructor-arg name="brokerURL" value="tcp://192.168.1.8:61616"></constructor-arg>
</bean>
	
<!-- spring对象ConnectionFactory的封装 -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
    <property name="targetConnectionFactory" ref="targetConnectionFactory"></property>
</bean>

<!--itemAddTopic需与生产者提供的一样-->
<bean id="itemAddTopic" class="org.apache.activemq.command.ActiveMQTopic">
  <constructor-arg name="name" value="item-add-topic"></constructor-arg>
</bean>

<!-- 配置监听器 -->
<!--需自定义监听器类ItemAddMessageListener,该类继承MessageListener,重写onMessage方法实现自己的业务逻辑-->
<bean id="itemAddMessageListener" class="com.taotao.search.listener.ItemAddMessageListener"></bean>
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
  <property name="connectionFactory" ref="connectionFactory"></property>
  <property name="destination" ref="itemAddTopic"></property>
  <property name="messageListener" ref="itemAddMessageListener"></property>
</bean>

    ItemAddMessageListener监听类,监听商品添加消息,同步索引库:

public class ItemAddMessageListener implements MessageListener {

	@Autowired
	private SearchItemMapper searchItemMapper;
	@Autowired
	private SolrServer solrServer;

	@Override
	public void onMessage(Message message) {
		try {
			// 从消息中取商品id
			TextMessage textMessage = (TextMessage) message;
			String text = textMessage.getText();
			long itemId = Long.parseLong(text);
			// 根据商品id查询数据,取商品信息
			// 等待发送消息方法事物提交
			Thread.sleep(1000);
			SearchItem searchItem = searchItemMapper.getItemById(itemId);
			// 创建文档对象
			SolrInputDocument document = new SolrInputDocument();
			document.addField("id", searchItem.getId());
			document.addField("item_title", searchItem.getTitle());
			document.addField("item_sell_point", searchItem.getSell_point());
			document.addField("item_price", searchItem.getPrice());
			document.addField("item_image", searchItem.getImage());
			document.addField("item_category_name", searchItem.getCategory_name());
			document.addField("item_desc", searchItem.getItem_desc());
			solrServer.add(document);
			// 提交
			solrServer.commit();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

    


猜你喜欢

转载自blog.csdn.net/xiaoying0531/article/details/80986757