JMS仕様とは何ですか
它是JavaEE体系中的一项Message Service
一般的なメッセージミドルウェアの比較
JMSの構成と特性
JMSプロバイダー
实现jms接口的消息中间件
JMSプロデューサー、JMSコンストマー
JMSメッセージヘッダー
1)jms destination 消息目的地 队列或者主题
2)jms deviverymode 持久化方式
3)jms expiration 消息过期时间
4)jms 优先级 1到4是普通消息 5-9是加急消息
5)消息id 唯一识别每个消息的标识,是有MQ自己生成
メッセージヘッダーの宛先
もちろん、メッセージで設定することもできます
4つのオーバーロード:宛先、メッセージ、優先度、存続時間、永続化するかどうか
。メッセージの宛先:キューとトピック
永続性
メッセージの有効期限がデフォルトで期限切れになることはありません
消息体
发送的消息类型有哪些:
StringMessage MapMessage ByteMessage StringMessage ObjectMessage 五中类型
要求:发送的消息体和接受的消息体要求类型一致。
要件:送信されたメッセージ本文と受信されたメッセージ本文には同じタイプが必要です。
カスタムメッセージ属性
自定义的消息属性能有什么还用呢 ?
去重、识别、重点标注等
TextMessage textMessage = session.createTextMessage("myTopic……"+ i );
messageProducer.send(textMessage);
textMessage.setStringProperty("自定义消息的key", "自定义消息的value");
メッセージの信頼性を確保するにはどうすればよいですか???
消息的可靠性可以从以下四个方面来回答:
1)消息的持久性
2)消息的事务特性
3)消息的签收机制
4)消息持久化
(キュー)メッセージの永続性
検証1:
メッセージを非永続に設定し、メッセージを生成して(サーバーはシャットダウンされません)、メッセージを消費します。
メッセージは通常消費されます。
検証2:
メッセージを非永続に設定します。次に、メッセージを生成し(サーバーが閉じている)、それを消費します。メッセージ
生成メッセージ
サーバーを閉じた後、メッセージを消費します。
メッセージは失われ、消費できません。
生成されたばかりのメッセージは失われます。
検証3:メッセージを永続的に設定してから、メッセージを生成します。これは、生成されたばかりのメッセージです。
メッセージサーバーをシャットダウンし、メッセージを再起動
します。メッセージはまだ存在しており、メッセージを消費します。メッセージは正常に消費されました
(トピック)メッセージの持続性
トピックメッセージの場合、永続性はあまり意味がありません。トピックモードでは、最初にコンシューマーを起動してからプロデューサーを起動する必要があるためです。メッセージの永続性が設定されているが、コンシューマーが起動されていない場合、これらのメッセージは失われ、消費者が消費することはできません
永続トピックジェネレータを設定する
package com.ttzz.activemq;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import org.apache.activemq.ActiveMQConnectionFactory;
public class ActiveMQProduceByTopic {
public static String url = "tcp://localhost:61616";
public static String topicName = "myTopic";
public static void main(String[] args) throws JMSException {
//1.获取工厂
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(url);
//2. 创建连接
Connection connection = activeMQConnectionFactory.createConnection();
//3.创建会话
// 第一个参数 是否开启开启事务
// 第二个参数 是签收模式
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//4. 创建目的地 Topic
Topic topic =session.createTopic(topicName);
//5. 创建生产者
MessageProducer messageProducer = session.createProducer(topic);
messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
connection.start();
//6. 发送消息
for (int i = 0; i < 4; i++) {
TextMessage textMessage = session.createTextMessage("myTopic……"+ i );
textMessage.setStringProperty("自定义消息的key", "自定义消息的value");
messageProducer.send(textMessage);
}
//关闭资源
messageProducer.close();
session.close();
connection.close();
System.out.println("OOKK");
}
}
トピック消費者
package com.ttzz.activemq;
import java.io.IOException;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicSubscriber;
import org.apache.activemq.ActiveMQConnectionFactory;
public class ActiveMQConsumerByTopic {
public static String url = "tcp://localhost:61616";
public static String topicName = "myTopic";
public static void main(String[] args) throws JMSException, IOException {
// 1.获取工厂
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(url);
// 2. 创建连接
Connection connection = activeMQConnectionFactory.createConnection();
connection.setClientID("消费者1");
System.out.println("topic消费者1");
// 3.创建会话
// 第一个参数 是否开启开启事务
// 第二个参数 是签收模式
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 4. 创建目的地Topic
Topic topic = session.createTopic(topicName);
// 5. 创建消费者
TopicSubscriber topicSubscriber = session.createDurableSubscriber(topic, "remark..."); // 创建持久化的订阅
connection.start();
Message message = topicSubscriber.receive();
while (message != null) {
TextMessage textMessage = (TextMessage) message;
System.out.println(textMessage.getText());
message = topicSubscriber.receive();
}
session.close();
connection.close();
System.out.println("OOKK2");
}
}
検証1:コンシューマーの開始
アクティブな耐久性のあるトピックサブスクライバー:アクティブ状態の
永続的なトピックコンシューマーオフラインの永続的なトピックサブスクライバー:オフライン状態の永続的なトピックコンシューマー
永続的なトピックジェネレーターの開始:
トピックコンシューマーがメッセージを消費する
メッセージサーバー
検証2:コンシューマー1をオフにしてコンシューマー2を開始するそして
消費者1がオフラインで、プロデューサーの消費を開始する。
消費者2が正常にメッセージを消費することができます。
[スタート]消費者1を再び、そして消費者1は、通常、メッセージを消費することができます。
メッセージのトランザクション特性
取引は主に生産者向けであり、署名は主に消費者向けです
//3.创建会话
// 第一个参数 是否开启开启事务
// 第二个参数 是签收模式
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
検証1:
トランザクションがfalseに設定され、メッセージがサーバーに自動的に送信されます。
メッセージの永続性が設定されているため、サーバーがシャットダウンされて再起動されますが、メッセージは引き続き存在します。
検証2:
トランザクションがtrueに設定され、メッセージの実行が送信され、
サーバーがメッセージを受信するかどうかを確認します。送信されたばかりのメッセージはサーバーから受信されませんでした。メッセージコミット操作がないため、
トランザクションがコミットされ、
メッセージがキューに入れられ、
トランザクションが複数のメッセージに対して同時に送信されます。これにより、
session.rollback()のアトミック性が保証されます。
必要性を確認するために、再起動する必要がある場合は、永続的なメッセージを削除してください
操作:構成ファイルactivemq.xmlのブローカーフィールドにdeleteAllMessagesOnStartup = "true"を追加し
て、永続メッセージが削除されていることを確認します。
プロデューサーはトランザクションを開始し、メッセージをメッセージサーバーに送信します。メッセージを
見ると、
コンシューマーはメッセージを消費します。
コンシューマーを再度開始し、メッセージが消費されたことを確認して、メッセージを再消費できないことを示します。
検証2:トランザクションを開始するようにコンシューマーを設定しますが、送信トランザクションはありません[メッセージは繰り返し消費されます]。コンシューマー1は初めてメッセージを正常に消費します
が、サーバー上でメッセージが消費されていないことを確認します。
別のコンシューマーを再起動して、メッセージが複数回消費される可能性があることを確認します。
面白い現象
プロデューサーは、トランザクション方式でプロデューサーをサーバーに送信します。
コンシューマーは、消費のためにトランザクションを開始しますが、トランザクションはコミットされません。コントロールが破壊されないことを確認してください。再び消費者2号を始めたのですが、繰り返し消費できないのでしょうか???
コンシューマーを4秒間設定した後、(remove:System.in.read();)の場合、メッセージは表示されず、自動的に閉じられます。コンシューマーNo.2がアクティブになり、繰り返し使用できます。
理由???ハハハッハッハ