Introduction to ActiveMQ (3)-Embedded and message persistence solutions

ActiveMQ advanced usage one, embedded MQ

In the actual development, if the project does not give too many resources, and now the business needs to use MQ, you can consider embedded MQ, embedded MQ does not need to install ActiveMQ, only need to import related dependencies.

1. The pom file needs to import the dependency: (Import this dependency on the basis of the MQ dependency in the previous two articles)

            <dependency>
	            <groupId>org.apache.activemq</groupId>
	            <artifactId>activemq-all</artifactId>
	            <version>5.14.5</version>
            </dependency>

2. First start an embedded MQ service, the code is as follows:

public class EmbedMQ {
	
	public static void main(String[] args) throws Exception {
		
        BrokerService brokerService = new BrokerService();
        brokerService.setBrokerName("EmbedMQ");
        brokerService.addConnector("tcp://localhost:62000");
        brokerService.setManagementContext(new ManagementContext());
        brokerService.start();
	}
}

3. Producer side:

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class EmbedJmsProducter {
		//默认连接用户名
	    private static final String USERNAME= ActiveMQConnection.DEFAULT_USER;
	    //默认连接密码
	    private static final String PASSWORD= ActiveMQConnection.DEFAULT_PASSWORD;
	    //默认连接地址
	    private static final String BROKEURL= "tcp://localhost:62000";
	    //发送的消息数量
	    private static final int SENDNUM = 10;

	    public static void main(String[] args) {
	        ConnectionFactory connectionFactory;
	        Connection connection = null;
	        Session session;
	        Destination destination;
	        MessageProducer messageProducer;

	      connectionFactory= new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKEURL);
	        try {
	            connection = connectionFactory.createConnection();
	            connection.start();
	            session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
	            //destination = session.createQueue("HelloWAM");
	            destination = session.createTopic("EmbedMQ");
	            messageProducer = session.createProducer(destination);
	            for (int i = 0; i < SENDNUM; i++) {
	                String msg = "内置MQ" + i + " " + System.currentTimeMillis();
	                TextMessage message = session.createTextMessage(msg);
	                System.out.println("发送消息:" + msg);
	                messageProducer.send(message);
	            }
	            session.commit();
	        } catch (JMSException e) {
	            e.printStackTrace();
	        } finally {
	            if (connection != null) {
	                try {
	                    connection.close();
	                } catch (JMSException e) {
	                    e.printStackTrace();
	                }
	            }
	        }
	    }
}

Consumer end:

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.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class EmbedJmsConsumer {
	
	 private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
     private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
     private static final String BROKEURL = "tcp://localhost:62000";

     public static void main(String[] args) {
    	 ConnectionFactory connectionFactory;//连接工厂
    	 Connection connection = null;//连接
    	 Session session;//会话 接受或者发送消息的线程
    	 Destination destination;//消息的目的地
    	 MessageConsumer messageConsumer;//消息的消费者
    	 //实例化连接工厂
    	 connectionFactory = new ActiveMQConnectionFactory(USERNAME,PASSWORD, BROKEURL);
    	 try {
    		 //通过连接工厂获取连接
    		 connection = connectionFactory.createConnection();
    		 //启动连接
    		 connection.start();
    		 //创建session
    		 session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    		 //创建一个连接HelloWorld的消息队列
    		 destination = session.createTopic("EmbedMQ");

    		 //创建消息消费者
    		 messageConsumer = session.createConsumer(destination);
    		 messageConsumer.setMessageListener(new MessageListener() {
    		   public void onMessage(Message message) {
    			 try {
    			System.out.println("Accept msg : "+ ((TextMessage) message).getText());
    				 } catch (JMSException e) {
    					 e.printStackTrace();
    				 }
    			 }
    		 });
    	 } catch (JMSException e) {
    		 e.printStackTrace();
    	 }
     }
}

4. Test

Start the service first, start the consumer, and finally start the producer to send messages.

ActiveMQ advanced usage two, message persistence scheme:

In a production environment, ActiveMQ may hang. In order to ensure that the message is not lost after hanging up, the message needs to be persisted. ActiveMQ provides several solutions.

1. AMQ: Based on file storage, it has the characteristics of fast writing speed and easy recovery. Messages are stored in files. The default size of the file is 32M. If the size of a message exceeds 32M, then this value must be set larger. When all the messages in a stored file have been consumed, then this file will be marked as deleteable. In the next clearing phase, this file will be deleted. AMQ applies to versions before ActiveMQ5.3.

2. KahaDB message storage-provides capacity improvement and recovery capabilities, and is now the default storage method; KahaDB is a file-based local database storage form. Although it is not as fast as AMQ, it has strong scalability and recovery time is longer than AMQ is short, and KahaDB is the default persistence method since version 5.4. Because it is the default storage scheme, KahaDB will be started when ActiveMQ is started even without any configuration. In this case, the location of the file is the /data/KahaDB subdirectory under the ActiveMQ installation path

3. JDBC message storage-messages are stored based on JDBC, and the data is stored in the database; this is not the default configuration, if you want to use it, you need to configure the following                                

修改配置文件  conf/ActiveMQ.xml 
1.将:  
      <persistenceAdapter>
	      <kahaDB directory="${activemq.base}/data/kahadb"/>
      </persistenceAdapter>
修改为:
      <persistenceAdapter>
          <jdbcPersistenceAdapter  dataSource="#mysql-ds "/>
      </persistenceAdapter>

2.在</broker>标签后,增加数据源的配置:

 <bean id="mysql-ds" class="org.apache.commons.dbcp2.BasicDataSource" 
   destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/activemq?relaxAutoCommit=true&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=UTC"/>
        <property name="username" value="****"/>
        <property name="password" value="****"/>
        <property name="poolPreparedStatements" value="true"/>
    </bean>
其中数据库名activemq需要在mysql中提前创建好,relaxAutoCommit=true这个属性必须要有,其他属性根据自身数据库信息及业务配置

放入必须的jar包
将 mysql 的驱动包放到ActiveMQ/lib 包下,启动ActiveMQ,如果报错,查看data/activemq.log 文件,可能是缺少其他jar包,我启动时报错,根据启动日志显示缺少commons-dbcp2-2.5.0.jar和commons-pool2-2.5.0.jar这两个包,同样导入到ActiveMQ/lib目录下,再次启动,启动成功

Check the database and found three more tables

activemq_acks : used to store subscription relationships. If it is a persistent topic, the subscription relationship between the subscriber and the server is stored in this table. The main database fields are as follows: container: the destination of the message sub_dest: if a static cluster is used, this field will contain information about other systems in the cluster. client_id: each subscription Each user must have a unique client id to distinguish sub_name: subscriber name selector: selector, you can choose to only consume messages that meet the conditions. Conditions can be implemented with custom attributes, which can support multi-attribute and and or operations last_acked_id: record the id of the message consumed

activemq_lock : Only useful in a cluster environment. Only one Broker can obtain messages, called Master Broker. The others can only be used as backups and wait for the Master Broker to become unavailable before becoming the next Master Broker. This table is used to record which Broker is the current Master Broker.

activemq_msgs : Used to store messages, Queue and Topic are stored in this table. The main database fields are as follows: id: self-incremented database primary key container: the destination of the message msgid_prod: the primary key of the message sender client msg_seq: the order of sending messages, msgid_prod+msg_seq can form the messageid of jms

 

Guess you like

Origin blog.csdn.net/csdnbeyoung/article/details/91345548