ActiveMQのメッセージングミドルウェア上のエンタープライズクラスのアプリケーション

我々はすべて知っているように、メッセージングミドルウェア大規模分散システムは重要な要素です。これは、使用するのは簡単ですが、このような非同期処理、システムのカップリング、フローカット風水、分散トランザクション管理などの問題の多くを解決します。システムの高性能、高可用性、高スケーラビリティを実現。この章では、ミドルウェアメッセージングアプリケーションシナリオをミドルウェア伝送モードをメッセージングActiveMQのは、はじめ  ミドルウェアメッセージングのエントリを紹介する3つの側面。あなたはそれを学ぶために急いで、何を待っています!

説明:メッセージングミドルウェアは、当社の深刻学ぶための努力と使用の価値がある、非常に強いです。非同期githubのを完了してください。
テクノロジー:メッセージングミドルウェアアプリケーションのシナリオ、通信モード、ActiveMQの。
出典ます。https://github.com/ITDragonBlog/daydayup/tree/master/MQ
記事のディレクトリ構造:
記事のディレクトリ構造

ミドルウェアアプリケーションシナリオをメッセージング

非同期処理

非同期処理:呼び出し側が要求を開始した後、呼び出し側は、すぐに、そして結果を待たずに結果を得る他のビジネス・ロジックを続行されません。非同期要求の効率を向上させるが、非中核ビジネスロジックのための失敗のリスクがあります。
同期:呼び出し側が開始要求、呼び出し側は結果が返されるまで待機し、その後、返された結果に基づいて追加のビジネスロジックを実行する必要があります。非同期処理効率が高くはないが、それは、コアビジネスロジック処理のためのビジネス・ロジックの制御性を確保することができます。

より一般的なシナリオの場合:正常に登録が検証メッセージ認証コードやテキストメッセージが送信されます通常の後、登録ユーザーの信頼性を確保するためには、唯一の成功した認証されたユーザーが適切に機能するためにプラットフォームを使用することができます。
比較非同期同期処理:図に示すように。

非同期処理

で処理された非同期メッセージングミドルウェアの利点:
伝統的なシステムアーキテクチャでは、時間のかかるビジネスロジック、ユーザ登録は、ページから成功した送信メールを待つ真ん中の必要性をジャンプします。これはまた、ユーザーエクスペリエンスに影響を与えながら、CPUのスループットが低下、システムの応答時間に影響を与えていないだけ。
第二には、メッセージングミドルウェアのビジネスロジックを通じて非同期メッセージを処理し、メッセージングミドルウェアハンドルに加入するユーザーが正常メッセージングミドルウェアにデータを送信した後、成功のページにジャンプするために登録した後に送られ、その後、ロジック・メッセージは、他のシステムによって送信された
3読み取りおよび書き込み速度は非常に高速に時間がかかり無視できるミドルウェア、メッセージングれます。より多くの要求は、メッセージングミドルウェアによって処理することができます。

要約:非同期非コアビジネスロジック処理のためにメッセージミドルウェアが正しくユーザエクスペリエンスを向上させる、CPUのスループットを改善するために、システム応答の効率を向上させることができます。

最終的には一貫性のあるシステムとのカップリング業務

分散システムは、幾つかの別個のコンピュータ(システム)が設定されています。それぞれのシステムをデカップリングするだけでなく、システム全体のシングルポイント障害を避けるために、独自のコンピュータモジュールを担当しています。各システムはさらに、障害の確率を減らすために、クラスタを行うことができます。
このような分散システムでは、どのような役割ミドルウェアやプレイメッセージング?

より一般的なシナリオの場合:シングル成功の後オーダーシステム、我々は最高の出荷倉庫や商品在庫の更新を選択し、倉庫システム・インターフェースを呼び出す必要があります。何らかの理由で倉庫システム・インタフェースへの呼び出しが失敗した場合は、直接注文処理に影響を与えます。
以下に示すよう:メッセージングミドルウェアが果たした重要な役割を感じます。

デカップリング

メッセージングミドルウェアと結合されたシステムのメリットを実現:
システム間でのカップリングでき、メッセージングミドルウェアがあるため、異常の彼らのビジネスロジックに他のシステムに影響を与えない、減少しました。、彼らの仕事をするだけのオーダーシステムは、注文データを担当してデータベースに永続化、ストレージシステムは、単純ではないため、受注の流れに影響を与え倉庫システムのインベントリを更新する責任があります。
第二に、あなたは問題、受注や在庫の削減がトランザクションであるべき見つかったかどうかを教えてください。ので、強力なトランザクションの一貫性を確保することが困難な理由を分散。ここでの業務は、最終的な一貫性の効果を達成するためのミドルウェアメッセージングを通じて(フォローアップについて詳細に説明します)。

小结:事务的一致性固然重要,没有库存会导致下单失败是一个理论上很正常的逻辑。但实际业务中并非如此,我们完全可以利用发货期通过采购或者借库的方式来增加库存。这样无疑可以增加销量,还是可以保证事务的最终一致性。

流量削锋

流量削锋也称限流。在秒杀,抢购的活动中,为了不影响整个系统的正常使用,一般会通过消息中间件做限流,避免流量突增压垮系统,前端页面可以提示"排队等待",即便用户体验很差,也不能让系统垮掉。

フローカット豊

小结:限流可以在流量突增的情况下保障系统的稳定。系统宕机会被同行抓住笑柄。

消息中间件的传输模式

消息中间件除了支持对点对和发布订阅两种模式外,在实际开发中还有一种双向应答模式被广泛使用。

点对点(p2p)模式

点对点(p2p)模式有三个角色:消息队列(Queue),发送者(Sender),接收者(Receiver)。发送者将消息发送到一个特定的队列中,等待接收者从队列中获取消息消耗。
P2P的三个特点:
一、每个消息只能被一个接收者消费,且消息被消费后默认从队列中删掉(也可以通过其他签收机制重复消费)。
二、发送者和接收者之间没有依赖性,生产者发送消息和消费者接收消息并不要求同时运行。
三、接收者在成功接收消息之后需向队列发送接收成功的确认消息。

P2Pモード

发布订阅(Pub/Sub)模式

发布订阅(Pub/Sub)模式也有三个角色:主题(Topic),发布者(Publisher),订阅者(Subscriber)。发布者将消息发送到主题队列中,系统再将这些消息传递给订阅者。
Pub/Sub的特点:
一、每个消息可以被多个订阅者消费。
二、发布者和订阅者之间存在依赖性。订阅者必须先订阅主题后才能接收到信息,在订阅前发布的消息,订阅者是接收不到的。
三、非持久化订阅:如果订阅者不在线,此时发布的消息订阅者是也接收不到,即便订阅者重新上线也接收不到。
四、持久化订阅:订阅者订阅主题后,即便订阅者不在线,此时发布的消息可以在订阅者重新上线后接收到的。

パブ/サブモード

双向应答模式

双向应答模式并不是消息中间件提供的一种通信模式,它是由于实际生成环境的需要,在原有的基础上做了改良。即消息的发送者也是消息的接收者。消息的接收者也是消息的发送者。如下图所示

これは、双方向モードでなければなりません

ActiveMQ 入门

ActiveMQ是Apache出品,简单好用,能力强大,可以处理大部分的业务的开源消息总线。同时也支持JMS规范。

JMS(JAVA Message Service,java消息服务)API是一个消息服务的标准或者说是规范,允许应用程序组件基于JavaEE平台创建、发送、接收和读取消息。它使分布式通信耦合度更低,消息服务更加可靠以及异步性。

ActiveMQ 安装

ActiveMQ 的安装很简单,三个步骤:
第一步:下载,官网下载地址:http://activemq.apache.org/download.html。
第二步:运行,压缩包解压后,在bin目录下根据电脑系统位数找到对应的wrapper.exe程序,双击运行。
第三步:访问,浏览器访问http://localhost:8161/admin,账号密码都是admin。

ActiveMQ 工作流程

我们通过简单的P2P模式来了解ActiveMQ的工作流程。
生产者发送消息给MQ主要步骤:
第一步:创建连接工厂实例
第二步:创建连接并启动
第三步:获取操作消息的接口
第四步:创建队列,即Queue或者Topic
第五步:创建消息发送者
第六步:发送消息,关闭资源

import java.util.Random;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination; import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnection; import org.apache.activemq.ActiveMQConnectionFactory; /** * 消息队列生产者 * @author itdragon */ public class ITDragonProducer { private static final String QUEUE_NAME = "ITDragon.Queue"; public static void main(String[] args) { // ConnectionFactory: 连接工厂,JMS 用它创建连接 ConnectionFactory connectionFactory = null; // Connection: 客户端和JMS系统之间建立的链接 Connection connection = null; // Session: 一个发送或接收消息的线程 ,操作消息的接口 Session session = null; // Destination: 消息的目的地,消息发送给谁 Destination destination = null; // MessageProducer: 消息生产者 MessageProducer producer = null; try { // step1 构造ConnectionFactory实例对象,需要填入 用户名, 密码 以及要连接的地址,默认端口为"tcp://localhost:61616" connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, ActiveMQConnection.DEFAULT_BROKER_URL); // step2 连接工厂创建连接对象 connection = connectionFactory.createConnection(); // step3 启动 connection.start(); // step4 获取操作连接 /** * 第一个参数:是否设置事务 true or false。 如果设置了true,第二个参数忽略,并且需要commit()才执行 * 第二个参数:acknowledge模式 * AUTO_ACKNOWLEDGE:自动确认,客户端发送和接收消息不需要做额外的工作。不管消息是否被正常处理。 默认 * CLIENT_ACKNOWLEDGE:客户端确认。客户端接收到消息后,必须手动调用acknowledge方法,jms服务器才会删除消息。 * DUPS_OK_ACKNOWLEDGE:允许重复的确认模式。 */ session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); // step5 创建一个队列到目的地 destination = session.createQueue(QUEUE_NAME); // step6 在目的地创建一个生产者 producer = session.createProducer(destination); // step7 生产者设置不持久化,若要设置持久化则使用 PERSISTENT producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); // step8 生产者发送信息,具体的业务逻辑 sendMessage(session, producer); session.commit(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (null != connection) { connection.close(); } } catch (Exception e) { e.printStackTrace(); } } } public static void sendMessage(Session session, MessageProducer producer) throws Exception { for(int i = 0; i < 5; i++) { String []operators = {"+","-","*","/"}; Random random = new Random(System.currentTimeMillis()); String expression = random.nextInt(10)+operators[random.nextInt(4)]+(random.nextInt(10)+1); TextMessage message = session.createTextMessage(expression); // 发送消息到目的地方 producer.send(message); System.out.println("Queue Sender ---------> " + expression); } } }

消费者从MQ中获取数据消费步骤和上面类似,只是将发送消息改成了接收消息。

import javax.jms.Connection;  
import javax.jms.ConnectionFactory;  
import javax.jms.Destination;  
import javax.jms.MessageConsumer;  
import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnection; import org.apache.activemq.ActiveMQConnectionFactory; import com.itdragon.utils.ITDragonUtil; /** * 消息队列消费者 * @author itdragon */ public class ITDragonConsumer { private static final String QUEUE_NAME = "ITDragon.Queue"; // 要和Sender一致 public static void main(String[] args) { ConnectionFactory connectionFactory = null; Connection connection = null; Session session = null; Destination destination = null; // MessageConsumer: 信息消费者 MessageConsumer consumer = null; try { connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, ActiveMQConnection.DEFAULT_BROKER_URL); connection = connectionFactory.createConnection(); connection.start(); session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); destination = session.createQueue(QUEUE_NAME); consumer = session.createConsumer(destination); // 不断地接收信息,直到没有为止 while (true) { TextMessage message = (TextMessage) consumer.receive(); if (null != message) { System.out.print(ITDragonUtil.cal(message.getText())); } else { break; } } } catch (Exception e) { e.printStackTrace(); } finally { try { if (null != connection) { connection.close(); } } catch (Exception e) { e.printStackTrace(); } } } }

SpringBoot 整合ActiveMQ使用

SpringBoot可以帮助我们快速搭建项目,减少Spring整合第三方配置的精力。SpringBoot整合ActiveMQ也是非常简单,只需要简单的两个步骤:
第一步,在pom.xml文件中添加依赖使其支持ActiveMQ
第二步,在application.properties文件中配置连接ActiveMQ参数

pom.xml是Maven项目的核心配置文件

<dependency>  <!-- 支持ActiveMQ依赖 -->
    <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <dependency> <!-- 支持使用mq连接池 --> <groupId>org.apache.activemq</groupId> <artifactId>activemq-pool</artifactId> </dependency> 

application.properties是SpringBoot项目的核心参数配置文件

spring.activemq.user=admin
spring.activemq.password=admin
spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.in-memory=true
spring.activemq.pool.enabled=true

spring.activemq.in-memory 默认值为true,表示无需安装ActiveMQ的服务器,直接使用内存。
spring.activemq.pool.enabled 表示通过连接池的方式连接。

springboot-activemq-producer

システムspringboot-ActiveMQのプロデューサープロデューサーシミュレーションプロジェクトは、位置ポイントモードに同時送信可能ポイントとサブスクリプションモデルを公開しています。
コア二つのファイル:メッセージ送信の種類は、豆ベースのキュー管理構成です。
三つの主要なモード:1ポイントモードにある、「queue.name」という名前のキュー、サブスクリプションモデルが発売された、「topic.name」と呼ばれるテーマは、最後のものは、「response.nameという名前バイ応答モード、キューであります。 "

import java.util.Random;
import javax.jms.Queue;
import javax.jms.Topic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener; import org.springframework.jms.core.JmsMessagingTemplate; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; /** * 消息队列生产者 * @author itdragon */ @Service @EnableScheduling public class ITDragonProducer { @Autowired private JmsMessagingTemplate jmsTemplate; @Autowired private Queue queue; @Autowired private Topic topic; @Autowired private Queue responseQueue; /** * 点对点(p2p)模式测试 * 包含三个角色:消息队列(Queue),发送者(Sender),接收者(Receiver)。 * 发送者将消息发送到一个特定的队列,队列保留着消息,直到接收者从队列中获取消息。 */ @Scheduled(fixedDelay = 5000) public void testP2PMQ(){ for(int i = 0; i < 5; i++) { String []operators = {"+","-","*","/"}; Random random = new Random(System.currentTimeMillis()); String expression = random.nextInt(10)+operators[random.nextInt(4)]+(random.nextInt(10)+1); jmsTemplate.convertAndSend(this.queue, expression); System.out.println("Queue Sender ---------> " + expression); } } /** * 订阅/发布(Pub/Sub)模拟测试 * 包含三个角色:主题(Topic),发布者(Publisher),订阅者(Subscriber) 。 * 多个发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。 */ @Scheduled(fixedDelay = 5000) public void testPubSubMQ() { for (int i = 0; i < 5; i++) { String []operators = {"+","-","*","/"}; Random random = new Random(System.currentTimeMillis()); String expression = random.nextInt(10)+operators[random.nextInt(4)]+(random.nextInt(10)+1); jmsTemplate.convertAndSend(this.topic, expression); System.out.println("Topic Sender ---------> " + expression); } } /** * 双向应答模式测试 * P2P和Pub/Sub是MQ默认提供的两种模式,而双向应答模式则是在原有的基础上做了改进。发送者既是接收者,接收者也是发送者。 */ @Scheduled(fixedDelay = 5000) public void testReceiveResponseMQ(){ for (int i = 0; i < 5; i++) { String []operators = {"+","-","*","/"}; Random random = new Random(System.currentTimeMillis()); String expression = random.nextInt(10)+operators[random.nextInt(4)]+(random.nextInt(10)+1); jmsTemplate.convertAndSend(this.responseQueue, expression); } } // 接收P2P模式,消费者返回的数据 @JmsListener(destination = "out.queue") public void receiveResponse(String message) { System.out.println("Producer Response Receiver ---------> " + message); } }
import javax.jms.Queue;
import javax.jms.Topic;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * bean配置管理类 * @author itdragon */ @Configuration public class ActiveMQBeansConfig { @Bean // 定义一个名字为queue.name的点对点列队 public Queue queue() { return new ActiveMQQueue("queue.name"); } @Bean // 定义一个名字为topic.name的主题队列 public Topic topic() { return new ActiveMQTopic("topic.name"); } @Bean // 定义一个名字为response.name的双向应答队列 public Queue responseQueue() { return new ActiveMQQueue("response.name"); } }

springboot-ActiveMQの消費者

メッセージキューを監視するための主に担当サーバspringboot-ActiveMQの消費者のアナログ消費者が存在します。
2つのコアファイル:メッセージ受信クラスは、ポイントモードへのポイントは、サブスクリプションモデルと互換性があり、工場出荷時の設定クラスへのリンクを公開します。

import org.springframework.jms.annotation.JmsListener;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Service;
import com.itdragon.utils.ITDragonUtil;
/** * 消息队列消费者 * @author itdragon */ @Service public class ITDragonConsumer { // 1. 监听名字为"queue.name"的点对点队列 @JmsListener(destination = "queue.name", containerFactory="queueListenerFactory") public void receiveQueue(String text) { System.out.println("Queue Receiver : " + text + " \t 处理结果 : " + ITDragonUtil.cal(text)); } // 2. 监听名字为"topic.name"的发布订阅队列 @JmsListener(destination = "topic.name", containerFactory="topicListenerFactory") public void receiveTopicOne(String text) { System.out.println(Thread.currentThread().getName() + " No.1 Topic Receiver : " + text + " \t 处理结果 : " + ITDragonUtil.cal(text)); } // 2. 监听名字为"topic.name"的发布订阅队列 @JmsListener(destination = "topic.name", containerFactory="topicListenerFactory") public void receiveTopicTwo(String text) { System.out.println(Thread.currentThread().getName() +" No.2 Topic Receiver : " + text + " \t 处理结果 : " + ITDragonUtil.cal(text)); } // 3. 监听名字为"response.name"的接收应答(双向)队列 @JmsListener(destination = "response.name") @SendTo("out.queue") public String receiveResponse(String text) { System.out.println("Response Receiver : " + text + " \t 正在返回数据......"); return ITDragonUtil.cal(text).toString(); } }
import java.util.concurrent.Executors;
import javax.jms.ConnectionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; import org.springframework.jms.config.JmsListenerContainerFactory; @Configuration @EnableJms public class JmsConfig { @Bean // 开启pub/Sub模式 public JmsListenerContainerFactory<?> topicListenerFactory(ConnectionFactory connectionFactory) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setPubSubDomain(true); factory.setConnectionFactory(connectionFactory); return factory; } @Bean // JMS默认开启P2P模式 public JmsListenerContainerFactory<?> queueListenerFactory(ConnectionFactory connectionFactory) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setPubSubDomain(false); factory.setConnectionFactory(connectionFactory); return factory; } } 

概要

1)  ミドルウェアは、非同期処理、デカップリング、フローカット風水、分散トランザクション管理システムやその他の問題を解決することができるメッセージング。

2)  ポイントモードにミドルウェアのデフォルトの支持点をメッセージングおよびサブスクライブ・モデルを公開し、実際の作業は、2ウェイモードすることができます。

3)  ActiveMQのApacheは強力で、使いやすいように、生成された、オープンソースのメッセージ・バスの事業の大部分を処理することができます。

 

記事の再版にします。https://www.cnblogs.com/itdragon/p/8535187.html

おすすめ

転載: www.cnblogs.com/zaevn00001/p/12191183.html