これらの基本的なアプリケーションのいくつかについて話をするのRabbitMQ一つのこと

RabbitMQの話というのいくつかの一つの基本的なアプリケーション

  こんにちは、誰もが小さな技術パートナーあなたは良いですが、今年の流行大好き害ああ、心から完全に健康、あなたとあなたの家族は、私たちが平和でありたいです。数年前、今、私は何か、書き込み何か、または他の彼は、彼はそれを無駄にするつもりだったと感じた長い時間を学んでいないします。それは、知識ポイントのRabbitMQのビットを整理するためにいくつかの時間にこの週末を取りました。基礎部分にまず、最初に彼らと。私は指導の多くは、その種で何か間違っがある場合、お互いから学び、またサイドエッジ学習プロセスの一種です、ありがとうございました!

  使用前に、まず最初に、私たちは、最初の環境を設定します。ビルドにRabbitMQの環境については、私はこの長いったらしいで、オンライン検索の多くは、小規模な環境を構築するために何のパートナーはありませんでしょう、あなたはちょっと、あなたの母ヘクタールのオンライン程度を見つけることができます。

まず、MQは何ですか

  MQは、単にキュー機能がFIFOで、そのキューを意味します。実際には、我々は、パイプラインを介してメッセージを渡すメッセージキューのパイプライン、メッセージとして理解することができます。最終的に異なるプロセス、異なるサービス間の通信ニーズの間。

  プログラムでは、MQにより、異なるプロセス間通信を実現することができます。異なるプログラム/サービスの中に、我々はまた、この記事の焦点で、今日の主役デビューに関連して、この時点でMQ、を介して相互に通信することができます。

二、RabbitMQの導入

  RabbitMQのは、完全なAMQPに基づいて、エンタープライズメッセージングシステムの再利用可能なオープンソースです。私の個人的な理解では、メッセージ受信、保存、管理、および配布を達成するために簡単です。言語インターフェイスのサポートの開発では、すべての主要な開発言語のサポート;パフォーマンスで、メッセージの永続性、クラスタリング、高い同時実行などのサポートオペレーティングシステムのサポート、主要なオペレーティング・システム(Linuxでは、Windowsの場合)のための支持体上に。

三、RabbitMQのキーワードの説明

  ブローカー(サーバー)は:クライアント接続、AMQPメッセージキューとルーティング機能に向けた進捗状況を受け入れ、私たちは、ブローカーのRabbitMQサーバ呼び出すことができます。

  仮想ホスト:仮想概念、実際には、あなたが考えることができる理解しやすいは、このように直接MQ異なるビジネス交差感染を避け、右MQ論理的に分離されたパーティションです。Exchangeおよびキューを複数持つことができる仮想ホストは、主に、アクセス制御、アプリケーションの隔離のために使用しました。このようなアプリケーションの使用などA VhostA、アプリケーションの使用VhostB Bは、その後、我々は、キューおよびメッセージにVhostAでのみ交換アプリケーションAを格納し、ユーザーがアプリケーションA VhostAにのみアクセスすることができ、あなたはデータVhostBにアクセスすることはできません。

  交換:サーバーキューを結合規則に従ってプロデューサによって送信されたメッセージ、およびルートにメッセージを受け入れます。ExchangeTypeメッセージをルーティング交換の動作を決定し、例えば、RabbitMQの中に、ExchangeTypeは直接、ファンアウト、トピックおよびヘッダを有するExchangeルーティングルールの4種類である(詳細は後述)と同じではありません。

  キュー:メッセージを格納するためのメッセージキューがされていない消費者支出は、FIFOキューは、デフォルトでは、最初に格納されたメッセージが最初に処理されています。

  メッセージ:ヘッダとボディ組成物からのメッセージは、ヘッダをメッセージキューを優先して受け入れられている、メッセージが永続的であるかどうかなど、属性のコレクションの生産によるもので加えされ、何等、本体データは、実際の転送されますバイトとしてコンテンツフォーマット[]。

  接続:接続は、RabbitMQのために、実際には、クライアントとブローカ間のTCP接続にあります。

  チャンネル:チャンネルチャンネル、接続ブローカーの間の接続を作成するための唯一のクライアントは、クライアントがメッセージを送信するかどうか。AMQPプロトコルに基づいて作成されるチャネル接続のニーズチャンネル、接続、複数のチャネルを含むことができますすることによってのみAMQPコマンド実行順序を提供します。必要チャネル、TCPコネクションの確立と解放は非常に高価であるため。

四、RabbitMQの3つの役割の説明

  上記の簡単な紹介のいくつかのことで、私はあなたがMQの予備的な印象を持っていると信じています。あなたは、ああ本当の時点までに実行する方法である最後に霧があります。ハハ、、RabbitMQのにすぐに以下をアップ実行フェーズを心配しないでください。プロデューサー、サーバ、消費者:実際には、アップ実行し、我々はまた、簡単にしたいとRabbitMQの三つの重要な役割を説明するだろう。

  メーカー:すなわち、メッセージプロデューサは、APIはRabbitMQの、RabbitMQのプッシュメッセージサーバによって増加しました。

  サーバ:RabbitMQのサービスセンター、メッセージを生成するために生産を受信し、配信ルールに従って、プッシュメッセージコンシューマに対応します。

  消費者:名前が示すように、メッセージの最終的な受信及び処理です。

  その結果、私たちは私の心の内側に絵を持っていると信じて、プロデューサーは - >サーバー - - 転送 - >コンシューマ(最終処理メッセージ)メッセージを生成します。これは、メッセージの全体的なプロセスとライフサイクルです。

 

五、RabbitMQのアップ実行します

  上記の説明を通じて、我々はメッセージ対話MQの簡単なプロセスを知っている必要があります。この財団と、ここでは配送方法の3つの役割の分類データを紹介します。全体的に、マップを見つけるために、インターネット上の対話的データに5つの方法(5つの動作モード)以下、それはあなたの参照のために便利です。

  実際には、上記チャートにより、我々は、最初の2つのケースでは、消費者と生産者との間に背を3例、消費者と生産者を接続することにより直接つの直接交換(交換)があることがわかり。したがって、我々は全体として2つのカテゴリに分けることができる:まず、ダイレクトプッシュメッセージキュー;第二に、スイッチにプッシュメッセージ、ルーティングルールに従ってキューに転送されます。

  実際には、実用的な作品で、最初のカテゴリは、我々は使用しない、そして実際の開発ニーズを達成するために二番目に大きいプロジェクトに基づいています。しかし、私たちにとって非常に良い最初のカテゴリは、簡単に起動して実行プログラムを入れて、私たちのエントリをリードします。時間的な理由のためには、今日我々は最初のカテゴリの最初の2例、二番目に大きいカテゴリー、明日や細部への特別な記事の日を達成します。

シンプルモード:

シンプルモードのみの生産、消費者です。これは、次は実際の例を挙げて説明するが、非常に簡単です。直接コードに添付:

メーカーコード: 

/// <要約>
 ///ニュースプロデューサー
 /// </summary>
public class Program
{
    static void Main(string[] args)
    {
        // rabbitMQ链接对象
        var factory = new ConnectionFactory();
        // RabbitMQ服务在本地运行
        factory.HostName = "192.168.1.1";
        // RabbitMQ服务端口
        factory.Port = 5672;
        // 用户名
        factory.UserName = "guest";
        // 密码
        factory.Password = "guest";
        // 虚拟主机名称
        factory.VirtualHost = "/";

        // 队列名称
        string queueName = "hello";

        // 创建链接
        using (var connection = factory.CreateConnection())
        {
            // 创建通道
            using (var channel = connection.CreateModel())
            {
                // 创建一个名称为hello的消息队列--当然一步也可以通过RabbitMQ管理后台添加
                // 当已经存在该队列时,不会重复添加,但是如果已存在的队列和新建的队列存在属性差异时,会创建失败,会抛异常,所以在实际使用时,如果要通过程序创建队列,最好要捕捉异常,避免因为这样的问题而导致程序崩溃。
                channel.QueueDeclare(queueName, false, false, false, null);
                Console.WriteLine("我是生成者");

                while (true)
                {
                    Console.WriteLine("请输入你要发送的消息,并按Enter键结束");

                    // 接收用户输入的消息
                    string message = Console.ReadLine();
                    // 消息编码
                    var body = Encoding.UTF8.GetBytes(message);
                    // 向消息服务器推送消息
                    channel.BasicPublish("", queueName, null, body);

                    Console.WriteLine($"已发送 {System.DateTime.Now.ToString("HH:mm:ss")}: {message}");
                }
            }
        }
    }
}

  消费者代码:

 /// <summary>
 /// 消息消费者
 /// </summary>
 public class Program
 {
     static void Main(string[] args)
     {
         // rabbitMQ链接对象
         var factory = new ConnectionFactory();
         // RabbitMQ服务在本地运行
         factory.HostName = "192.168.1.1";
         // RabbitMQ服务端口
         factory.Port = 5672;
         // 用户名
         factory.UserName = "guest";
         // 密码
         factory.Password = "guest";
         // 虚拟主机名称
         factory.VirtualHost = "/";

         // 队列名称
         string queueName = "hello";

         // 创建链接
         using (var connection = factory.CreateConnection())
         {
             // 创建通道
             using (var channel = connection.CreateModel())
             {

                 // 创建一个名称为hello的消息队列--当然一步也可以通过RabbitMQ管理后台添加
                 // 当已经存在该队列时,不会重复添加,但是如果已存在的队列和新建的队列存在属性差异时,会创建失败,会抛异常,所以在实际使用时,如果要通过程序创建队列,最好要捕捉异常,避免因为这样的问题而导致程序崩溃。
                 channel.QueueDeclare(queueName, false, false, false, null);
                 Console.WriteLine("我是消费者");

                 // 创建一个消费者
                 var consumer = new EventingBasicConsumer(channel);
                 // 订阅对应的消息 autoAck:是否自动确认
                 channel.BasicConsume(queueName, autoAck:false, consumer);

                 consumer.Received += (model, ea) =>
                 {
                     var body = ea.Body;
                     var message = Encoding.UTF8.GetString(body);
                     Console.WriteLine($"已接收 {System.DateTime.Now.ToString("HH:mm:ss")}: {message}");

                     // 为了模拟推送过程,在此程序休息1分钟
                     Thread.Sleep(6000);
                     // 确认消费
                     channel.BasicAck(ea.DeliveryTag, false);
                 };
                 Console.ReadLine();
             }
         }
     }
 }

  

运行结果:

 

  通过实际的运行结果图,我们很清楚的知道,生产者的消息发生顺序,和消费者消费的顺序是一直的,这也就MQ的基本原理所在。

上面介绍了简单模式,下面我在来介绍一下比简单模式复杂一点的工作模式。

工作模式:

  我理解的简单模式,只是带我们入门,让我们明白MQ的运行效果是咋样的。但是在实际工作中,不可能只会有一个消费者,在实际的生产环境中生产者、消费者都可能会有多个存在,这也就是我们说的工作模式。那么,有多个生成的者的时候,不同的生产者之间又是怎么来消费消息的呢?下面我们先通过实践的例子来说明:

  具体的代码和上面的代码是一样的,我们可以直接开两个消费者就可以实现数据模拟,直接看运行结果:

  同上面的实际运行结果我们可以简单的得出以下结论:

  当一个队列有多个消费者时,在生成的实时消息时,消息队列服务器会轮询的均匀的分发给每一个消费者。

  哈哈哈,注意了,上面的结论我说的是实时消息哦,这里面就包含了一个坑,在实际的使用过程中要特别注意。那就是历史消息处理上,在实际项目使用过程中,我们经常会遇到,当消费者打开时,队列中已经有很多消息待消费,这个时候又该如何保证多个消费均匀分配消息呢?避免忙绿的消费者累死现象。其实很简单,只需在消费端加上如下一个配置即可:

 
 // 通过Qos设置每次接收消息的条数
 // 三个参数说明
 // prefetchSize:为预取的长度,一般设置为0即可,表示长度不限
 // prefetchCount:表示预取的条数,即发送的最大消息条数
 // global表示是否在Connection中全局设置,true表示Connetion下的所有channel都设置为这个配置。
 channel.BasicQos(prefetchSize: 0,
                  prefetchCount: 1,
                  global: false);

  

  上面的配置中,最关键的一个参数就是prefetchCount,当我们设置为1时,就是能够实现均匀的分发。下面分别对prefetchCount设置不同的值,来看看不同的效果:
  实例一:将prefetchCount设置为10,并生成3条历史消息,然后同时打开两个消费者,看看3条消息的分发消费情况:

  通过图,我们得出,3条历史消息全部推送给了一个消费者,这样就导致了一个消费者累死,一个消费者闲的慌。
  实例二:将prefetchCount设置为1,并生成4条历史消息,然后同时打开两个消费者,看看3条消息的分发消费情况:


  通过图,我们得出,4条历史消息平均的分发给了两个消费者,这也是我们想要的效果。
  所以在实际工作中,一定要注意这一个细节,不然有可能导致在服务器重启时,有的服务器直接卡死现象。
  好了,时间不早了,今天就先写到这,明天我们继续分享后面的几种模式。在分析完每一种模式后,我还好结合实际,封装一个dll出来,供大家参考,到时候也会直接把源码提出来。欢迎大家关注,持续交流。疫情无情,我们学习不能停。加油吧,每一个小伙伴!​

 

 

END
为了更高的交流,欢迎大家关注我的公众号,扫描下面二维码即可关注,谢谢:

 

 

おすすめ

転載: www.cnblogs.com/xiaoXuZhi/p/RabbitMQ_01.html