ActiveMQ study concluded (a)

I used to write their own online mall project of ActiveMQ, although compared to compared to RabbitMQ, kafka, RocketMQ etc., ActiveMQ performance may not be the best choice, but the message queue is actually not very principle difference here to learned about the message knowledge of the queue to sum, combined with their own interview about this problem encountered do a finishing move for the later autumn to prepare to find a job. This is a mainly introduce JMS, ActiveMQ installation and common interfaces both queue mode, how to integrate Spring project, summarizing the interview.

  • Java Message Service, Java Message Service Application Program Interface, API is a Java platform on message-oriented middleware (MOM) for transmitting messages between two programs, or distributed system, asynchronous communication, JMS is a specific platform-independent API, MOM vast majority of providers offer support for JMS. This is a more detailed definition of JMS, and more intuitive to say, JMS is a set of messaging services API, that is only JMS interface, the implementation class to do various manufacturers MOM.

  • JMS usage scenarios, applications deployed in Beijing A, B application deployed in Shanghai, whenever an event is triggered after A, B to get some information about A, B may also have wanted to get a lot of information A. In this case, Java provides the best solution -JMS. The same applies to JMS-based application events, such as chat service, he needed a release event mechanism to send message to all clients connected to the server. Different JMS and RMI, the recipient does not need online. That is, the server has finished sending a message that this event will have nothing to do with him.

  • JMS advantages:

    • Asynchronous, JMS inherently asynchronous, when the client gets the message and does not need to take the initiative to send a request, a message is automatically sent to the client available.
    • Reliable, JMS ensure the message is delivered only once. We have encountered problems create duplicate messages, JMS can help you avoid this problem, but not eliminate, the need MOM manufacturers to do more comprehensive mechanism to improve.
  • JMS common concepts:

    • Provider / MessageProvider: producer
    • Consumer / MessageConsumer: Consumer
    • PTP: Point To Point, point to point communication message model
    • Pub / Sub: Publish / Subscribe, publish-subscribe messaging model
    • Queue: Queue, one target type, and binding PTP
    • Topic: topic, type one of the goals, and Pub / Sub combination
    • ConnectionFactory: connection factories, JMS create a connection with it
    • Connnection: JMS Client connected to the JMS Provider
    • Destination: message destination, created by Session
    • Session: Session, created by Connection, essentially sending a message thread to accept, therefore producers, consumers are created Session

ActiveMQ Profile

Apache ActiveMQ is produced, most popular, strong ability to open source message bus. ActiveMQ is a fully supported JMS1.1 and J2EE1.4 standard JMS Provider implementation has been JMS above simple introduction.

ActiveMQ features:

  • Languages ​​and write client-side protocol, languages ​​including Java, C, C ++, C #, Ruby, Perl, Python, PHP, protocols include OpenWire, Stomp, REST, WS Notification, XMPP, AMQP
  • J2EE1.4 specification and fully support JMS1.1
  • Support for Spring, so that ActiveMQ is integrated into Spring which is very convenient
  • Support for multiple transport protocols: in-VM, TCP, SSL, NIO, UDP, JGroups, JXTA
  • JDBC support provided by high-speed messages and journal persistence
  • Ensure high-performance clusters from the design, client - server point
  • Support Ajax
  • Integration and support of the Axis

ActiveMQ message form

  • Point to point, which is a province of a car by pressing one consumer

  • After the publish / subscribe model, a message is generated and transmitted producer, the consumer may be received by a plurality of

JMS defines five different format of the message body and message information call, allows you to send and receive data in a number of different forms:

* StreamMessage --- 数据流
* MapMessage --- key-value
* TextMessage --- 字符串
* ObjectMessage --- 序列化的Java对象
* BytesMessage --- 一个字节的数据流

ActiveMQ installation

  1. activemq.apache.org download ActiveMQ
  2. unzip
  3. Start, ./activemq start, shut down ./activemq stop, view the status ./activemq status

Admin page: http://192.168.25.168:8161/admin, the user name admin, password admin

ActiveMQ is used

Add jar package

1
2
3
4
5
<!--引入ActiveMQ的jar包-->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
</dependency>

Form the message queue using the Queue

Producer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/ ** 
* Manufacturer mode the ActiveMQ queue
* @throws a JMSException
* /
@Test
public void testQueueProducer () throws a JMSException {
//. 1. Create a connection factory object, need to specify the IP and port / service port for the message 61616
the ConnectionFactory The connectionFactory new new = ActiveMQConnectionFactory ( "TCP: //192.168.25.128: 61616");
. // 2 are connected using the connection factory to create
connection connection connectionFactory.createConnection = ();
.. 3 // open connection
connection.start ();
//. 4. create a session,
// the first parameter is whether ActiveMQ open transactions, generally do not use the transaction
// if open transaction, the second parameter is automatically ignored, do not open the transaction, the second parameter indicates the answer mode messages, automatic answer , manual answer
Session = connection.createSession the session (to false, Session.AUTO_ACKNOWLEDGE);
.. 5 // use the Session object to create a Destination objects, topic or queue
= Session.createQueue Queue Queue ( "Test-Queue");
// create a producer. 6 to use the Session object.
The MessageProducer Producer = session.createProducer (Queue);
.. 7 // Create a TextMessage object
TextMessage textMessage = new ActiveMQTextMessage ( );
textMessage.setText ( "Hello!");
// send message. 8.
producer.send (textMessage);
// Close the resource. 9.
producer.close ();
Session.close ();
Connection.close ();
}

It can be seen that an object passing between producers and consumers, consists of three main parts: header + message attributes + message body. Of course, the creation process can also be persistent selection configuration message.

Consumer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/ ** 
* ActiveMQ consumer queue mode
* @throws JMSException
* /
@Test
public void testQueueConsumer () throws JMSException, IOException {
// 1. Create a connection factory object, you need to specify the IP and port / messaging port 61616
ConnectionFactory connectionFactory ActiveMQConnectionFactory new new = ( "TCP: //192.168.25.128: 61616");
. // 2 are connected using the connection factory to create
connection connection connectionFactory.createConnection = ();
.. 3 // open connection
connection.start ();
// 4. create a session,
// the first parameter is whether ActiveMQ open transactions, generally do not use the transaction
// if open transaction, the second parameter is automatically ignored, do not open the transaction, the second parameter indicates the answer mode message, automatic answer, manual answer
Session = connection.createSession the session (to false, Session.AUTO_ACKNOWLEDGE);
.. 5 // use the Session object to create a Destination objects, topic or queue
= Session.createQueue Queue Queue ( "Test-Queue");
// create a consumer to use. 6 Session object.
A MessageConsumer Consumer = session.createConsumer (Queue);
.. 7 // received message
consumer.setMessageListener (new MessageListener () {
@Override
public void the onMessage (the Message Message) {
TextMessage textMessage = (TextMessage) Message;
String = null text;
the try {
text textMessage.getText = ();
} the catch (a JMSException E) {
e.printStackTrace ();
}
the System. Out.println (text);
}
});
// Close the resource. 8.
System.in.read ();
consumer.close();
session.close();
connection.close();
}

Comment basically explain the basic process, only to note that when receiving a message, we first check setMessageListener this method, its interface is defined as follows:

1
void setMessageListener(MessageListener var1) throws JMSException;

That need to pass an object that implements MessageListener interface, while the interface MessageListener only one onMessage method as follows:

1
2
3
4
5
package javax.jms;

public interface MessageListener {
void onMessage(Message var1);
}

Anonymous class method to monitor the test-Queue queue, as long as the incoming message, it is immediately executed onMessage method.

Topic mode

Provider

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* ActiveMQ的订阅模式生产者
*/
@Test
public void testTopicProducer() throws Exception {
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.25.128:61616");
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic("test-topic");
MessageProducer producer = session.createProducer(topic);
TextMessage activeMQ_topic = session.createTextMessage("activeMQ topic");
producer.send(activeMQ_topic);

producer.close();
session.close();
connection.close();
}

和队列模式相比,只是由session生成的消息队列模式编程了订阅发布模式,其他完全一样。

Consumer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
* ActiveMQ的订阅者模式消费者
*/
@Test
public void testTopicConsumer() throws Exception{
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.25.1 大专栏  ActiveMQ学习总结(一)28:61616");
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic("test-topic");
MessageConsumer consumer = session.createConsumer(topic);
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();
}

ActiveMQ在Spring中的使用

上一节介绍的在项目中直接使用消息队列的方式,可以看出存在很大的重复代码,而且步骤很多,将ActiveMQ整合到Spring中可以大大改善这两个问题。

  1. 引入JMS相关jar包
1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
  1. 配置ActiveMQ整合Spring,配置ConnectionFactory
1
2
3
4
5
6
7
8
<!--ConnectionFactory,JMS服务厂商提供的ConnectionFactory-->
<bean id="targetConnecctionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<constructor-arg name="brokerURL" value="tcp://192.168.25.128:61616"/>
</bean>
<!--spring对ConnectionFactory的封装-->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnecctionFactory"/>
</bean>
  1. 配置生产者,使用JMSTemplate对象,发送消息
1
2
3
4
<!--配置JMSTemplate-->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
</bean>
  1. 配置Destination
1
2
3
4
5
6
7
<!--消息的目的地-->
<bean id="test-queue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg name="name" value="test-queue"/>
</bean>
<bean id="item-add-topic" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg name="name" value="item-add-topic"/>
</bean>
  • 完整的配置文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">

<!--ConnectionFactory,JMS服务厂商提供的ConnectionFactory-->
<bean id="targetConnecctionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<constructor-arg name="brokerURL" value="tcp://192.168.25.128:61616"/>
</bean>
<!--spring对ConnectionFactory的封装-->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnecctionFactory"/>
</bean>
<!--配置JMSTemplate-->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
</bean>
<!--消息的目的地-->
<bean id="test-queue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg name="name" value="test-queue"/>
</bean>
<bean id="item-add-topic" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg name="name" value="item-add-topic"/>
</bean>
</beans>

测试代码

  1. 发送消息,步骤注释中写的很清楚了,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 使用JMSTemplate来发送消息
* @throws Exception
*/
@Test
public void testJmsTemplate() throws Exception {
//初始化Spring容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring/applicationContext-activemq.xml");
//从容器中获得模板对象
JmsTemplate jmsTemplate = applicationContext.getBean(JmsTemplate.class);
//从容器中获得Destination对象
Destination destination = (Destination) applicationContext.getBean("test-queue");
//发送消息
jmsTemplate.send(destination, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("spring activemq send queue message");
}
});
}
  1. 接收消息

由于项目中使用ActiveMQ实现索引库和数据库的同步,为了接收ActiveMQ的消息,需要创建一个MessageListener实现类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 接收ActiveMQ发送的消息
* Created by cdx0312
* 2018/3/9
*/
public class MyMesseageListener implements MessageListener{
@Override
public void onMessage(Message message) {
//接收消息
try {
TextMessage textMessage = (TextMessage) message;
String text = textMessage.getText();
System.out.println(text);
} catch (JMSException e) {
e.printStackTrace();
}
}
}

然后在Spring中整合ActiveMQ的消息监听器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!--ConnectionFactory,JMS服务厂商提供的ConnectionFactory-->
<bean id="targetConnecctionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<constructor-arg name="brokerURL" value="tcp://192.168.25.128:61616"/>
</bean>
<!--spring对ConnectionFactory的封装-->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnecctionFactory"/>
</bean>
<!--消息的目的地-->
<bean id="test-queue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg name="name" value="test-queue"/>
</bean>
<bean id="item-add-topic" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg name="name" value="item-add-topic"/>
</bean>
<!--配置消息的接受者-->
<!--配置监听器-->
<bean id="messeageListener" class="com.market.search.listen.MyMesseageListener"/>
<!--消息监听容器-->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destination" ref="test-queue"/>
<property name="messageListener" ref="messeageListener"/>
</bean>

测试代码:

1
2
3
4
5
6
@Test
public void testQueueConsumer() throws Exception {
//初始化Spring容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring/applicationContext-activemq.xml");
System.in.read();
}

Guess you like

Origin www.cnblogs.com/lijianming180/p/12046818.html