ActiveMQの概要(3)-組み込みおよびメッセージ永続化ソリューション

ActiveMQの高度な使用法1、組み込みMQ

実際の開発では、プロジェクトがあまり多くのリソースを提供せず、ビジネスでMQを使用する必要がある場合は、組み込みMQを検討できます。組み込みMQはActiveMQをインストールする必要はなく、関連する依存関係をインポートするだけで済みます。

1. pomファイルは依存関係をインポートする必要があります:(前の2つの記事のMQへの依存関係に基づいてこの依存関係をインポートします)

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

2.最初に組み込みMQサービスを開始します。コードは次のとおりです。

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.プロデューサー側:

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();
	                }
	            }
	        }
	    }
}

消費者側:

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.テスト

最初にサービスを開始し、コンシューマーを開始し、最後にプロデューサーを開始してメッセージを送信します。

ActiveMQの高度な使用法2、メッセージ永続化スキーム:

実稼働環境では、ActiveMQがハングする場合があります。ハングアップ後にメッセージが失われないようにするには、メッセージを永続化する必要があります。ActiveMQにはいくつかのソリューションがあります。

1. AMQ:ファイルストレージに基づいており、書き込み速度が速く、リカバリが簡単であるという特徴があります。メッセージはファイルに保存されます。ファイルのデフォルトサイズは32Mです。メッセージのサイズが32Mを超える場合は、この値を大きく設定する必要があります。保存されたファイル内のすべてのメッセージが消費されると、このファイルは削除可能としてマークされます。次のクリアフェーズで、このファイルは削除されます。AMQは、ActiveMQ5.3より前のバージョンに適用されます。

2. KahaDBメッセージストレージ-容量の改善とリカバリ機能を提供し、現在はデフォルトのストレージ方法です。KahaDBはファイルベースのローカルデータベースストレージフォームです。AMQほど高速ではありませんが、スケーラビリティが高く、リカバリ時間が高速です。 AMQよりも短く、バージョン5.4以降のデフォルトの永続化方法はKahaDBです。これはデフォルトのストレージスキームであるため、構成がなくてもActiveMQの起動時にKahaDBが起動します。この場合、ファイルの場所はActiveMQインストールパスの下の/ data / KahaDBサブディレクトリです。

3. JDBCメッセージストレージ-メッセージはJDBCに基づいて保存され、データはデータベースに保存されます。これはデフォルトの構成ではありません。使用する場合は、次の構成が必要です。                                

修改配置文件  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目录下,再次启动,启动成功

データベースを確認すると、さらに3つのテーブルがあることがわかりました

activemq_acks サブスクリプション関係を格納するために使用されます。永続的なトピックの場合、サブスクライバーとサーバー間のサブスクリプション関係がこのテーブルに格納されます。主なデータベースフィールドは次のとおりです。container:メッセージの宛先sub_dest:静的クラスターが使用されている場合、このフィールドには次の情報が含まれます。クラスター内の他のシステムに関する情報。client_id:各サブスクリプションsub_name:サブスクライバー名セレクター:セレクターを区別するために、各ユーザーは一意のクライアントIDを持っている必要があります。条件を満たすメッセージのみを使用するように選択できます。条件は、複数の属性や操作をサポートできるカスタム属性を使用して実装できますlast_acked_id:消費されたメッセージのIDを記録します

activemq_lock クラスター環境でのみ役立ちます。マスターブローカーと呼ばれるメッセージを取得できるブローカーは1つだけです。他のブローカーはバックアップとしてのみ使用でき、マスターブローカーが使用できなくなるのを待ってから次のマスターブローカーになります。このテーブルは、どのブローカーが現在のマスターブローカーであるかを記録するために使用されます。

activemq_msgs メッセージを格納するために使用され、キューとトピックはこのテーブルに格納されます。主なデータベースフィールドは次のとおりです。id:自己インクリメントデータベースの主キーコンテナ:メッセージの宛先msgid_prod:メッセージ送信者クライアントの主キーmsg_seq:メッセージの送信順序、msgid_prod + msg_seqはjmsのメッセージIDを形成できます

 

おすすめ

転載: blog.csdn.net/csdnbeyoung/article/details/91345548