MQについて、あなたは知っている必要があります

ルーチンは何OKその後、MQメッセージキュー?

  1. そして、メッセージキューのシーンを使用する利点
  2. メッセージキューはどのような問題が、どのような解決策をもたらします
  3. MQ(ActiveMQの持つ例えば簡単な例)を使用する方法

メッセージキューと利点のシナリオ:

  • 非同期 - 交通クリッピング

  のは、従来のサーバを見てみましょうことは、処理要求処理を受け、

  サーバのメッセージキューが使用していないときに、上記のように、ユーザの要求があるストレート憎悪に、データベース高い同時の場合、応答速度が遅くなるだけでなくように、データベースの圧力サージ、したがって直接ユーザページで、その結果、データベースをハングアップすることができますエラー、プロジェクトマネージャは*#そして、ドアに来ました!%@!#** ......(PS:サービスが、ユーザーの宝にリンクされているにもかかわらず、警告メッセージがネットワークにポットをスローされますどこにもああ〜)

  メッセージキューサーバーの追加は何が起こるかの要求処理の流れを受けた後、私たちは見て

上記のように、メッセージキューは、使用後、ユーザ要求は直ちにメッセージキューに送信した後も高い同時の場合にデータを返すために、その後、非同期データベースに書き込まれた消費者プロセスのメッセージ・キューによってメッセージキューからデータを取得します。メッセージキューサーバーはデータベースよりもはるかに高速のメッセージ、それゆえ**応答率(ユーザーエクスペリエンスインフルエンザ)**を大幅に向上させることを処理しますので。

  だから我々は、メッセージキューが良い持っていると結論付けることができクリッピングフローエフェクト機能を-つまり、非同期処理を通じて、メッセージは、それによって同時トランザクションのピークを大幅に削減、メッセージキューに発生した同時トランザクションの高い短時間のために保存されています特定の電子ビジネスプラットフォームのスパイク活動のいくつかのように、メッセージキューの使用の合理化ができる要求の流入の開始活動の多数耐えるシステムに衝撃を。ユーザーはすぐに戻ってユーザーにメッセージキューを書き込んだ後、データを要求したが、その後の要求のデータがあるため、運用データベースを作成し、操作性を検証失敗する可能性がありますだから、非同期処理のためにメッセージキューを使用した後、例えば、オーダーを提出した後、ユーザーは、注文データをメッセージキューに書き込まれると、ビジネスプロセスを適切に変更し、必要、注文が正常に送信され、すぐにユーザーに返すことができない、あなたは本当に消費者のプロセスのメッセージキューに順番に対処する必要がありますオーダー完了後、でも図書館の後、その後、貿易紛争を避けるために、成功した電子メールまたはSMS注文を介してユーザに通知します。これは、我々が通常ようにチケットを訓練し、携帯電話に似ています。

  • 非同期 - デカップリングシステム

 私が最初に見ない従来のシステムのデータ転送モード中

  上記のように、あまりにもメインシステムとあまりにも他の結合システムは、ダイレクトコールであるか、または少しの変更は、モジュールを追加し、両方のコードを変更する必要があり面倒

  その後、我々は、メッセージキュー、何が起こるかのシステム構成を追加することを見た後、

  上記のように、我々は間のモジュール場合ことを知っているダイレクトコールが存在しない、そして、影響が少ない他のモジュールにモジュールのようなシステムモジュールを追加または変更スケーラビリティを間違いなくより良いです。

メッセージキューの使用が公開-モデル購読する作業を、メッセージの送信者(プロデューサー)は、その1つまたは複数のメッセージの受信者(消費者)のサブスクリプションのメッセージを発表しました。図からメッセージ送信者(プロデューサ)とメッセージ受信者(消費者)との間に直接結合が存在しない、分散されたメッセージキューにメッセージを送信するメッセージ送信者がメッセージの処理を終了することがわかる、分布から受信者のメッセージその後の処理メッセージキューの後に、メッセージを取得し、そのメッセージが来る知っている必要はありません。新規事業のために、限りニュースのそのタイプに興味のように、あなたがこのメッセージを購読することができ、拡張性の高いビジネスのウェブサイトのデザインを可能にする既存のシステムやサービス、上の影響はありません。

 また、メッセージキューサーバー避けるために、メッセージの損失によるダウンタイムをメッセージは、メッセージを削除するには、実サーバの処理された後、メッセージが正常にメッセージサーバプロデューサーに保存されているメッセージのキュー、および他の消費者に送信されます。メッセージキューサーバーのダウンタイムの後、サーバーのメーカーは、メッセージキューサーバークラスタのポストメッセージを配布し、他のサーバーを選択します。

加えて、サブスクリプションモデルを公開する、外部メッセージキューを、輸送の他のモードがあります

  小数点モデルへのポイント

  ベースモデルのみ、送信者、受信者、および分散キュー。

  プロデューサーの消費者モデル

  送信者と受信者でも、異なる種類の複数のデプロイメントインスタンスを持つことができる場合は、同じキューを共有し、それが標準生産者、消費者のモデルとなります。このモデルでは、3の役割は、一般的に生産(プロデューサー)、分散キュー(待ち行列)、消費者(消費者)と呼ばれます。

   要約方法:のメッセージキューシステムの並行処理能力とスケーラビリティが向上しています

第二に、メッセージキューを使用することは、どのような問題をもたらすでしょう。

  • **削減可用性:** MQに入社する前に、MQを導入した後、あなたは可用性の減少を考慮する必要があります、状況MQサーバがハング考慮していません。
  • 複雑化:  MQを追加した後、あなたは、メッセージの損失の取り扱い、メッセージが消費を繰り返されないことを保証する秩序メッセージングやその他の問題を保証する必要があります。それでは、より多くの、システムの複雑さの増加を検討する必要があります。
  • **データの一貫性:**もたらした非同期メッセージキューは、実際にシステムの応答速度を向上させることができ、ただし、メッセージが何をどのように本当に正しい消費者ニュースの消費者ではありませんか?これは、一貫性のないデータの状況につながります。

2.1どのようなソリューション

  • ユーザビリティの問題について

  メッセージキューの導入後、システムの可用性が低下します。MQメッセージを送信する実際のプロジェクトで、そうでない場合は、機械ダウンへのMQ事故は、その後、MQメッセージは、システムが崩壊し、送信することはできませんので、そのうちの一つが決裂したときに我々はMQ、MQをクラスタ化する必要があるクラスタ、 MQマシンの残りの部分は、その後、生産で動作していないメッセージキューの誰もスタンドアローン使用し続けることができます。もしそうなら、それは確かであるためには、使用すると(技術的な複雑さが少し思える、ファッジはお金を過充電だけでなく)、そのことについては、我々は次のように、MQクラスタ技術、異なるメッセージングミドルウェア・クラスター・アプローチの多様性をより深く理解している必要があり例(飼育係+ ActiveMQの)としてクラスタをActiveMQの、地図を見て

  

  このシナリオでは、マスタ/スレーブ(マスタ/スレーブモード)と呼ばれている。このシナリオでは、私は3台のサーバ(プライマリおよびスタンバイ)を持って、どのような場合には、職場で唯一の「マスター」は、メインの失敗で「準備しました」サービスを提供する「マスター」を交換する際、。飼育係のサポートにより、このプロセスは、飼育係とノードは「私の3台のサーバが起動したとき、それは一時的なノードと呼ばれる指定されたディレクトリの飼育係さん(プロセスで、独自に対応して作成し、ディレクトリサービスを提供して達成されます登録「)、いわゆる一時的なノードをプライマリサーバに障害が発生したときのZooKeeperサーバーを維持するために(定期的にデータパケットを送信する)ハートビートである(のZooKeeperサーバーにデータパケットを送信することはできません、飼育係は、飼育係に登録する変更、一時的なノードのサーバーを削除し、飼育係ますシリアル番号を割り当て、我々は小さなシリアル番号は、「マスター」、大きな1のシリアル番号は、「準備。」であることを信じています

  私たちのクライアントの「マスター」サーバー(通常はWebサーバ)を設定したアドレスがサービスにアクセスするために必要なときに、あなたは、飼育係を接続するサーバ情報を登録されている指定されたディレクトリ、内のノードの一時的なリストを取得し、小型のシリアル番号にアクセスする必要があります、その後のアクセス動作。実現するためには、「常にプライマリサーバーにアクセスします。」「マスター」サーバーに障害が発生した場合には、飼育係が指定されたディレクトリから対応する一時的なノードを削除し、この変更を懸念するすべてのクライアントは、この情報の効率的かつ迅速な普及を通知することができます。時間と、次の要求、またはZooKeeperの接続が、この場合、実際のアクセスで交互MQ。

  ここでクラスタを構成する方法については、独自のインターネット検索のチュートリアル、たくさんの上、実証することはありません!

  • 問題の複雑さのために
  1. メッセージはそれの消費を繰り返さないことを確実にするためにどのように?

  この質問に答えるために、メッセージは、ネットワーク、情報はもはやメッセージキューに転送されるため、ほとんど無理が生じていない、消費を繰り返すことになるなぜ我々は最初に知っている必要があり、メッセージキューは、消費者にはなりません、彼らは再びメッセージ、およびメッセージの配信があったことを知っています他の消費者に。だから我々はこの問題に道を解決するには、次の3つのアイデアを持っています

①。メッセージは、データベースの挿入操作を行う場合には、このメッセージは状況繰り返さ消費が発生した場合でも、ユニークなプライマリキーを作ることです、それは汚れたデータを表示されたデータベースを避けるために、主キーの競合につながります。あなたは結果が同じであるかどうかを複数回設定するため②。あなたはニュースの操作はRedisの設定を取得した場合は、電源を操作し、他の操作を設定していた場合であっても、解決しません。上記2つの条件が十分でない場合③。、サービス消費者の記録を行うには、サードパーティを準備します。Redisの例では、メッセージに割り当てられたグローバルID、限り介してメッセージコンシューマ<IDは、メッセージ> RedisのはKVの形で書き込まれます。消費者はそれを費やして開始する前に、クエリをすることができ一切消費レコードがないのRedis、行きます。

   2. メッセージそれの送信の信頼性を確保するための方法は?

実は、これが最初の質問の拡張である、言い換えれば、我々は、伝送の信頼性を確保したい、実際には、それは防ぐことを確実にするためである生産者がデータを失った、メッセージキュー、失われたデータを、消費者のデータを失っただけ

  プロデューサーは、その後、MQ取引あれば実際には、これらの問題は、早期のミドルウェアの開発者が考慮に入れ、だけでなく、文書の数は、私たち自身のパラメータを設定するように構成することができます提供している、メッセージキューは、一般的にディスクに永続化におけるデータの損失を心配しないでくださいロールバックされます、ライン上の手動確認の修正として、それが消費者支出、MQへの呼び出しが完了した後と言うことです限り、削除された消費者への情報提供につながる消費者は言葉が一般的に自動確認メッセージモードを使用している失われ、再送信を試みることができますライン上の確認方法

  3. メッセージキューデータ実行順序からの保証を取得する方法は?

  アルゴリズムによって、我々は同じメッセージキューにメッセージの順序を維持し、その後のみキューを過ごすために、消費者にする必要があります。

  (1)のRabbitMQを:、各キューは、それがもう少しキュー消費者分割キューの複数である、確か点面倒であるか;またはそれがキューに対応するが、消費者は、その後、消費者は、分散次に、内部メモリキューにキューイングか労働者は、基礎となる異なる処理します

  カフカが住んでいた(2) トピック、パーティション、消費者、シングルスレッドの内部消費を、そしてNのメモリ待ち行列を書き込み、Nスレッドは、メモリキューに消費されています

  4. 遅延やメッセージキューを解決するためにどのように問題を期限切れ?数時間続けたメッセージのバックログの数百万人がありますが、どのように解決するには?

問題本番環境の後にすぐに問題を解決する方法を検討し、ある,,事故がメッセージキューを遅延し、自己保護メカニズムは、期限切れのメッセージキューで、目的は下落している自分自身を防ぐためですが、当然のことながら、例えば、保護するために閉じることができ、メッセージは、消費者が5回失敗すると、ニュースを入れ落としなど、保護メカニズムをオフにしないようにしよう、そう問題は、メッセージが破棄された方、され、それをしないのですか?そうでもない、私たちはこの事業のために、内部MQ再注入し、その後失われるデータのバッチをチェックアウトし、一時的なプログラムを書く、少しチェックアウト、およびすることができ、失われたデータは、彼にそれを構成しています。

データは、任意の欠点を有する各々が、プッシュ又はプル方式で最終消費者に与えられますか。

  • モデルのリアルタイムを押しますが、理由は、メンテナンスやその他の問題の状態に、実際にメッセージミドルウェアを置くことは困難である、など

  • 最後Brokerは消費者の消費者の消費速度が矛盾しているシーンの大規模な数をサポートするために適した状態ブローカー消費者、およびいないを維持する必要性では、ブローカーがあるため、メッセージを消費することはできません状況に対処するために消費者消費者のブローカーが困難なさまざまな状況に対処するためにハードにプッシュします私は別のプッシュメッセージが(量が大きいかもしれない)負荷や破砕消費者の消費が増加します)消費者のダウンタイムは、一時的または恒久的であるかわかりません。

    プッシュプルでより良いだけで消費者を、対応する場合。

  • プルモードは実装が比較的簡単になりますが、リアルタイムでの使用に適していないシーンの高いリアルタイムの要求に回転周波数に依存します。

III。MQを使用する方法(ActiveQMに例えば)

  公式サイトを取り付けますactivemq.apache.org/

  サービス・アクセス・アドレスを開始するためにアタッチ:http://127.0.0.1:8161/admin/を    ユーザ名/パスワードadmin / adminに

  コードを取り付け、ジャーを下に身を包んだpan.baidu.com/s/1SUBoypW -...

公開されたサブスクリプションモデル

プロデューサー - ポスト

public class JMSProducer {

    private static final String USERNAME=ActiveMQConnection.DEFAULT_USER; // 默认的连接用户名
    private static final String PASSWORD=ActiveMQConnection.DEFAULT_PASSWORD; // 默认的连接密码
    private static final String BROKEURL=ActiveMQConnection.DEFAULT_BROKER_URL; // 默认的连接地址
    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(JMSProducer.USERNAME, JMSProducer.PASSWORD, JMSProducer.BROKEURL);
        
        try {
            connection=connectionFactory.createConnection(); // 通过连接工厂获取连接
            connection.start(); // 启动连接
            session=connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); // 创建Session
            // destination=session.createQueue("FirstQueue1"); // 创建消息队列
            destination=session.createTopic("FirstTopic1");
            messageProducer=session.createProducer(destination); // 创建消息生产者
            sendMessage(session, messageProducer); // 发送消息
            session.commit();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally{
            if(connection!=null){
                try {
                    connection.close();
                } catch (JMSException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    
    /**
     * 发送消息
     * @param session
     * @param messageProducer
     * @throws Exception
     */
    public static void sendMessage(Session session,MessageProducer messageProducer)throws Exception{
        for(int i=0;i<JMSProducer.SENDNUM;i++){
            TextMessage message=session.createTextMessage("ActiveMQ 发送的消息"+i);
            System.out.println("发送消息:"+"ActiveMQ 发布的消息"+i);
            messageProducer.send(message);
        }
    }
}
复制代码

  消費者 - 購読

/**
 * 消息监听-订阅者一
 * @author Administrator
 *
 */
public class Listener implements MessageListener{

    @Override
    public void onMessage(Message message) {
        // TODO Auto-generated method stub
        try {
            System.out.println("订阅者一收到的消息:"+((TextMessage)message).getText());
        } catch (JMSException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
复制代码
public class JMSConsumer {

    private static final String USERNAME=ActiveMQConnection.DEFAULT_USER; // 默认的连接用户名
    private static final String PASSWORD=ActiveMQConnection.DEFAULT_PASSWORD; // 默认的连接密码
    private static final String BROKEURL=ActiveMQConnection.DEFAULT_BROKER_URL; // 默认的连接地址
    
    public static void main(String[] args) {
        ConnectionFactory connectionFactory; // 连接工厂
        Connection connection = null; // 连接
        Session session; // 会话 接受或者发送消息的线程
        Destination destination; // 消息的目的地
        MessageConsumer messageConsumer; // 消息的消费者
        
        // 实例化连接工厂
        connectionFactory=new ActiveMQConnectionFactory(JMSConsumer.USERNAME, JMSConsumer.PASSWORD, JMSConsumer.BROKEURL);
                
        try {
            connection=connectionFactory.createConnection();  // 通过连接工厂获取连接
            connection.start(); // 启动连接
            session=connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // 创建Session
            // destination=session.createQueue("FirstQueue1");  // 创建连接的消息队列
            destination=session.createTopic("FirstTopic1");
            messageConsumer=session.createConsumer(destination); // 创建消息消费者
            messageConsumer.setMessageListener(new Listener()); // 注册消息监听
        } catch (JMSException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
}
复制代码

高スループット、低レイテンシー(原因異なる場面に)、トランスミッション透明、強力な拡張性、冗長な災害を持っている能力、配達、非同期、同期+のための一貫性:私は良い分散メッセージキューは、次の機能を持つべきだと思います、送信運用・保守および監視ツールやオープンソースを改善

おすすめ

転載: juejin.im/post/5d064d4c5188256d37227a4b
おすすめ