プロジェクト開発におけるMQの選択

0、まとめ

RocketMQの土壌への侵入(1)初心者が理解できる原理と実際の戦闘!

土地へのRocketMQエントリ(2)トランザクションメッセージとシーケンスメッセージ

侵入から土壌へ(3)RocketMQは、メッセージが失われないようにどのように保証しますか?

土壌へのRocketMQエントリ(4)プロデューサー生産ニュースのソースコード分析

土壌へのRocketMQエントリ(5)メッセージ永続ストレージソースコード分析

土壌へのRocketMQエントリ(6)メッセージを送信するときにキューを選択するためのアルゴリズムは何ですか?

RocketMQの土地への入場(7)同じ消費者グループが異なるタグを設定するのはなぜ奇妙な現象に見えるのか

侵入から土壌へ(8)RocketMQの消費者はどのように負荷分散を行うのか

始めから土に入るまで(9)は、RocketMQデュアルマスターデュアルスレーブ同期クラスターを構築する方法を教えてくれます。学ぶことができないとは思わないでください。

侵入から土壌へ(10)RocketMQクラスタープロセスとコアコンセプト

1.あなたの会社のオンライン本番環境で使用されているメッセージミドルウェアを教えてください。

[2、複数のmqを選択する方法を参照してください。

2.複数のmqを選択する方法は?

SQM 説明
RabbitMQ Erlang開発、メッセージ蓄積のサポートは良くありません。多数のメッセージがバックログされると、RabbitMQのパフォーマンスが急激に低下します。1秒あたり数万から数十万のメッセージを処理できます。
RocketMQ Java開発、インターネット指向のクラスタリング機能が豊富で、オンラインサービスの応答遅延に関する多くの最適化。ほとんどの場合、ミリ秒レベルの応答を実現でき、1秒あたり数十万のメッセージを処理できます。
カフカ Scala開発、豊富なログ指向機能、最高のパフォーマンス。ビジネスシナリオでは、1秒あたりのメッセージ数がそれほど多くない場合、Kafkaの待機時間は比較的長くなります。したがって、Kafkaはオンラインビジネスのシナリオには適していません。
ActiveMQ Java開発は単純で安定しており、パフォーマンスは前の3つほど良くありません。小規模なシステムでも問題ありませんが、お勧めしません。主流のインターネットを使用することをお勧めします。

3.なぜMQを使用するのですか?

プロジェクトが比較的大きく、分散システムが構築されているため、すべてのリモートサービス呼び出し要求が同期的に実行され、問題が頻繁に発生するため、mqが導入されます。

効果 説明
デカップリング システム結合の程度が減少し、強い依存関係がありません
非同期 同期的に実行する必要のないリモート呼び出しは、応答時間を効果的に改善できます
ピーククリッピング リクエストがピークに達した後も、バックエンドサービスは固定消費率を維持でき、圧倒されることはありません。

4. RocketMQはどのような役割で構成され、各役割の機能と特徴は何ですか?

キャラクター 効果
ネームサーバー ステートレスで動的なリスト。これは、zookeeperとの重要な違いの1つでもあります。動物園の飼育係はステートフルです。
プロデューサー メッセージプロデューサーは、ブローカーにメッセージを送信する責任があります。
ブローカ メッセージの送受信、メッセージの永続化などを担当するのはMQ自体です。
消費者 メッセージコンシューマーは、ブローカーからメッセージをプルして消費し、消費後に確認する責任があります。

5. RocketMQのトピックキューとJMSキューの違いは何ですか?

キューは、データ構造から派生したFIFOキューです。トピックは抽象的な概念です。各トピックの最下層はN個のキューに対応し、データは実際にはキューに存在します。

6. RocketMQ Brokerのメッセージは、消費された直後に削除されますか?

いいえ、すべてのメッセージはCommitLogに永続化されます。各コンシューマーがブローカーに接続された後、消費の進行状況情報が維持されます。メッセージが消費されると、現在のコンシューマーの消費の進行状況(CommitLogオフセット)のみが更新されます。

フォローアップ:ニュースは蓄積されますか?期限切れのメッセージはいつクリーンアップしますか?

4.6バージョンでは、デフォルトで48時間後に使用されなくなったCommitLogファイルが削除されます。

  • このファイルの最終アクセス時刻を確認してください

  • 有効期限よりも長いかどうかを判断します

  • 指定された時間に削除します。デフォルトは午前4時です。

ソースコードは次のとおりです。

/**
 * {@link org.apache.rocketmq.store.DefaultMessageStore.CleanCommitLogService#isTimeToDelete()}
 */
private boolean isTimeToDelete() {
    // when = "04";
    String when = DefaultMessageStore.this.getMessageStoreConfig().getDeleteWhen();
    // 是04点,就返回true
    if (UtilAll.isItTimeToDo(when)) {
        return true;
    }
 // 不是04点,返回false
    return false;
}

/**
 * {@link org.apache.rocketmq.store.DefaultMessageStore.CleanCommitLogService#deleteExpiredFiles()}
 */
private void deleteExpiredFiles() {
    // isTimeToDelete()这个方法是判断是不是凌晨四点,是的话就执行删除逻辑。
    if (isTimeToDelete()) {
        // 默认是72,但是broker配置文件默认改成了48,所以新版本都是48。
        long fileReservedTime = 48 * 60 * 60 * 1000;
        deleteCount = DefaultMessageStore.this.commitLog.deleteExpiredFile(72 * 60 * 60 * 1000, xx, xx, xx);
    }
}
                                                                       
/**
 * {@link org.apache.rocketmq.store.CommitLog#deleteExpiredFile()}
 */
public int deleteExpiredFile(xxx) {
    // 这个方法的主逻辑就是遍历查找最后更改时间+过期时间,小于当前系统时间的话就删了(也就是小于48小时)。
    return this.mappedFileQueue.deleteExpiredFileByTime(72 * 60 * 60 * 1000, xx, xx, xx);
}

7. RocketMQの消費モードは何ですか?

消費モデルはコンシューマーによって決定され、消費ディメンションはトピックです。

  • クラスター消費

1.メッセージは、同じグループ内の1人のコンシューマーによってのみ消費されます

2.複数のグループが同時にトピックを消費する場合、各グループにはデータを消費するコンシューマーがあります

  • 放送消費

メッセージは、コンシューマーグループの下のコンシューマーインスタンスごとに消費されます。つまり、これらのコンシューマーが同じコンシューマーグループに属している場合でも、メッセージはコンシューマーグループ内の各コンシューマーによって1回消費されます。

8.消費者ニュースはプッシュまたはプルですか?

RocketMQには、すべてプルであるプッシュの本当の意味はありません。プッシュクラスはありますが、実際の基盤となる実装では、長いポーリングメカニズム、つまりプルメソッドが使用されます。

ブローカープロパティlongPollingEnableは、ロングポーリングが有効かどうかをマークします。デフォルトはオン

ソースコードは次のとおりです。

// {@link org.apache.rocketmq.client.impl.consumer.DefaultMQPushConsumerImpl#pullMessage()}
// 看到没,这是一只披着羊皮的狼,名字叫PushConsumerImpl,实际干的确是pull的活。

// 拉取消息,结果放到pullCallback里
this.pullAPIWrapper.pullKernelImpl(pullCallback);

フォローアップ:イベント監視方法を使用する代わりに、メッセージをプルするイニシアチブを取りたいのはなぜですか?

イベント駆動型の方法は、長い接続を確立し、イベント(データの送信)を使用してリアルタイムで接続をプッシュすることです。

ブローカーが積極的にメッセージをプッシュする場合、プッシュ速度が速く、消費速度が遅い可能性があります。これにより、メッセージがコンシューマー側に蓄積されすぎると同時に、他のユーザーによってメッセージが消費されなくなります。消費者。プル方式は、圧力をかけすぎたりボトルネックになったりすることなく、現状に応じてプルできます。そのため、プル方式を採用しています。

9.ブローカーはプルリクエストをどのように処理しますか?

消費者は初めてブローカーを要求します

  • ブローカーに適格なメッセージがあるかどうか

  • はい->

    • 消費者への対応

    • 次の消費者の要求を待っています

  • 番号

    • DefaultMessageStore#ReputMessageService#run方法

    • PullRequestHoldServiceはHoldに接続し、5秒ごとに実行されて、pullRequestTableにメッセージがあるかどうかを確認し、メッセージがある場合はすぐにプッシュします。

    • 1msごとにcommitLogに新しいメッセージがあるかどうかを確認し、ある場合はそれらをpullRequestTableに書き込みます。

    • 新しいメッセージがあったときにリクエストを返す

    • コンシューマーの要求を一時停止します。つまり、データを切断したり返したりしません。

    • 消費者のオフセットを使用し、

10. RocketMQはどのように負荷分散を行いますか?

トピックを通じて複数のブローカーで分散ストレージを実現します。

プロデューサーエンド

送信者は、メッセージキューを指定して、メッセージを対応するブローカーに送信し、書き込み時に負荷分散を実現します。

  • 書き込みスループットを向上させます。複数のプロデューサーが同時にブローカーにデータを書き込むと、パフォーマンスが低下します。

  • メッセージは、負荷消費に備えるために複数のブローカーに分散されます

デフォルトの戦略はランダムに選択することです:

  • プロデューサーはインデックスを維持します

  • ノードが取得されるたびに、ノードは自動的に増加します

  • インデックスはすべてのブローカーの残りを取ります

  • 組み込みのフォールトトレランス戦略

その他の実装:

  • SelectMessageQueueByHash

    • ハッシュは着信引数です

  • SelectMessageQueueByRandom

  • SelectMessageQueueByMachineRoomは実装されていません

MessageQueueSelectorインターフェースでselectメソッドをカスタマイズすることもできます

MessageQueue select(final List<MessageQueue> mqs, final Message msg, final Object arg);

消費者

負荷分散には、平均分散アルゴリズムが使用されます。

その他の負荷分散アルゴリズム

平均配布戦略(デフォルト)(AllocateMessageQueueAveragely)循環配布戦略(AllocateMessageQueueAveragelyByCircle)手動構成配布戦略(AllocateMessageQueueByConfig)コンピュータールーム配布戦略(AllocateMessageQueueByMachineRoom)コンシステントハッシュ配布戦略(AllocateMessageQueueConsistentHash)コンピュータールームに近い戦略(AllocateMessageQueueByMachineRoom)

フォローアップ:コンシューマーロードバランサーとキューが等しくない場合はどうなりますか?

コンシューマーとキューは最初に均等に割り当てられます。コンシューマーの数がキューの数より少ない場合、一部のコンシューマーは複数のキューを消費します。コンシューマーの数がキューの数と等しい場合、1つのコンシューマーが1つのキューを消費します。コンシューマーの数がキューの数よりも多い場合、一部のコンシューマーは節約され、無駄になります。

11.メッセージの繰り返し消費

メッセージの通常の送信と消費に影響与える重要な理由は、ネットワークの不確実性です。

繰り返し消費の原因

  • ACK

通常の状況では、コンシューマーが実際にメッセージを消費した後、メッセージが正常に消費されたことをブローカーに通知するackを送信し、キューから削除する必要があります。

ネットワーク上の理由でackをブローカーに送信できない場合、ブローカーはエントリーメッセージが消費されていないと見なし、メッセージ再送信メカニズムがアクティブ化されて、メッセージがコンシューマーに再度配信されます。

  • 消費パターン

クラスタリングモードでは、メッセージはブローカー内で同じグループのコンシューマーによって一度消費されることが保証されていますが、異なるグループのコンシューマーは複数回プッシュされます

解決

  • データベーステーブル

メッセージを処理する前に、メッセージの主キーを使用して、テーブルの制約付きフィールドに挿入します

  • 地図

マップConcurrentHashMap-  > putIfAbsentguavaキャッシュをスタンドアロンモードで使用でき ます

  • Redis

分散ロックがアップしています。

12.RocketMQにメッセージの順次消費を保証させる方法

オンラインビジネスでメッセージミドルウェアを使用する場合、メッセージの順序を確認する必要がありますか?

メッセージの順序を保証する必要がない場合は、どうしてですか?メッセージの順序を保証したいシナリオがある場合、どのように保証する必要がありますか?

まず、複数のキューは単一のキュー内の順序のみを保証できます。キューは一般的なFIFOの自然な順序です。複数のキューを同時に使用しても、メッセージの順序を完全に保証することはできません。したがって、要約は次のとおりです。

同じトピック、同じQUEUE、1つのスレッドはメッセージの送信時にメッセージを送信し、1つのスレッドは消費時にキュー内のメッセージを消費します。

フォローアップ:メッセージが同じキューに送信されるようにするにはどうすればよいですか?

Rocket MQはMessageQueueSelectorインターフェースを提供します。インターフェースを内部で書き直して、独自のアルゴリズムを実装できます。最も簡単な例を示すと、judgeしi % 2 == 0てからqueue1に入れ、それ以外の場合はqueue2に入れます。

for (int i = 0; i < 5; i++) {
    Message message = new Message("orderTopic", ("hello!" + i).getBytes());
    producer.send(
        // 要发的那条消息
        message,
        // queue 选择器 ,向 topic中的哪个queue去写消息
        new MessageQueueSelector() {
            // 手动 选择一个queue
            @Override
            public MessageQueue select(
                // 当前topic 里面包含的所有queue
                List<MessageQueue> mqs,
                // 具体要发的那条消息
                Message msg,
                // 对应到 send() 里的 args,也就是2000前面的那个0
                Object arg) {
                // 向固定的一个queue里写消息,比如这里就是向第一个queue里写消息
                if (Integer.parseInt(arg.toString()) % 2 == 0) {
                    return mqs.get(0);
                } else {
                    return mqs.get(1);
                }
            }
        },
        // 自定义参数:0
        // 2000代表2000毫秒超时时间
        i, 2000);
}

13. RocketMQは、メッセージが失われないようにするにはどうすればよいですか?

まず、次の3つの部分でメッセージが失われる可能性があります。

  • プロデューサーエンド

  • ブローカー側

  • 消費者

13.1プロデューサー側でメッセージが失われないようにする方法

  • send()を使用してメッセージを同期的に送信すると、送信結果は同期的に認識されます。

  • 送信に失敗した後、再試行して再試行回数を設定できます。デフォルトは3回です。

producer.setRetryTimesWhenSendFailed(10);

  • たとえば、クラスターのデプロイメントは、送信に失敗した理由として、現在のブローカーがダウンしていることが原因である可能性があり、再試行すると他のブローカーに送信されます。

13.2ブローカーは、メッセージが失われないようにするにはどうすればよいですか?

  • ブラッシング戦略を同期ブラッシングに変更します。デフォルトでは、非同期フラッシュです。

flushDiskType = SYNC_FLUSH

  • クラスター展開、マスタースレーブモード、高可用性。

13.3。コンシューマーエンドは、メッセージが失われないようにするにはどうすればよいですか?

  • 完全に消費された後、手動で確認応答が実行されます。

14.rocketMQのメッセージ蓄積に対処する方法

ダウンストリームのコンシューマーシステムがダウンし、メッセージミドルウェアに数百万のメッセージのバックログが発生した場合、現時点で何をすべきですか?

オンラインニュースのバックログで制作の失敗に遭遇したことがありますか?それが発生していない場合、どのように対処するかを検討しますか?

まず、メッセージの蓄積の原因を特定することです。これは、プロデューサーが多すぎる、コンシューマーが少なすぎる、またはその他の状況が原因であるかどうかです。つまり、最初に問題を特定します。

次に、メッセージの消費率が正常かどうかを確認します。正常な場合は、オンラインでより多くの消費者を立ち上げることで、メッセージの蓄積の問題を一時的に解決できます。

フォローアップ:コンシューマーとキューが等しくなく、複数のデバイスがオンラインであるが、蓄積されたメッセージを短時間で消費できない場合はどうすればよいですか?

  • 一時的なトピックを準備する

  • キューの数は累積の数倍です

  • キューは複数のブローカーに配布されます

  • コンシューマーをメッセージポーターとして起動し、元のトピックのメッセージを新しいトピックに移動します。ビジネスロジック処理は行わず、移動するだけです。

  • N消費者はオンラインであり、同時に一時的なトピックのデータを消費します

  • バグを修正

  • 元のコンシューマーを復元し、前のトピックを引き続き消費します

フォローアップ:蓄積時間が長すぎてメッセージがタイムアウトしましたか?

RocketMQのメッセージは、commitLogが削除された場合にのみ消え、タイムアウトしません。つまり、消費されていないメッセージは時間の経過とともに削除されません。

フォローアップ:蓄積されたメッセージはデッドレターキューに入りますか?

いいえ、消費が失敗した後、メッセージは再試行キュー(%RETRY%+ ConsumerGroup)に18回入ります(デフォルトは18回、インターネット上のすべての記事は例外なく16回と言います。しかし、なぜ16であるのかわかりません。次に、デッドレターキュー(%DLQ%+ ConsumerGroup)に入る前に18時間ではありませんか?

ソースコードは次のとおりです。

public class MessageStoreConfig {
    // 每隔如下时间会进行重试,到最后一次时间重试失败的话就进入死信队列了。
 private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h";
}

15. RocketMQの分散トランザクションサポートメカニズムの基本原則は?

RocketMQを使用していますか?RocketMQの優れた機能は、分散トランザクションのサポートです。分散トランザクションでこのメカニズムをサポートする基本的な原則について教えてください。

分散システムのトランザクションは、TCC(Try、Confirm、Cancel)、2pcを使用して、分散システムのメッセージの原子性を解決できます。

RocketMQ 4.3+は、RocketMQトランザクションメッセージを介して分散トランザクション機能を提供し、分散トランザクションの最終的な一貫性を実現できます。

RocketMQの実装方法:

**メッセージの半分:**メッセージを前処理します。ブローカーがそのようなメッセージを受信すると、RMQ_SYS_TRANS_HALF_TOPICのメッセージ消費キューに保存されます。

**トランザクションステータスを確認します。**ブローカーは、RMQ_SYS_TRANS_HALF_TOPICキュー内のメッセージを消費するために、時間指定タスクを開始します。タスクが実行されるたびに、トランザクション実行ステータス(コミット、ロールバック、不明)がメッセージ送信者に確認されます。不明な場合、ブローカーは定期的にコールバックに移動し、再チェックします。

**タイムアウト:**チェックバックの数を超えると、メッセージはデフォルトでロールバックされます。

つまり、彼は実際にはトピックキューに入らず、一時キューを使用していわゆるハーフメッセージを配置し、トランザクションが送信された後、ハーフメッセージは実際にトピックの下のキューに転送されました。

16.分散メッセージングミドルウェアの実装を求められた場合、アーキテクチャ全体をどのように設計および実装しますか?

私は個人的に次の点から答えると思います。

  • クラスターを迅速に拡張して自然にサポートする機能を検討する必要があります

  • しつこい姿勢

  • 高可用性

  • データ0の損失に関する考慮事項

  • サーバー側での展開とクライアント側での使用が簡単

17. RocketMQのソースコードを読みましたか?読んだことがあるなら、RocketMQソースコードについての理解を教えてください。

本当に教えてほしいのなら文句を言いますまず第一にコメントはありませんアリババが以前に中国語のコメントを書いたのかもしれませんそれをapacheに寄付した後、apacheは中国語のコメントを保持できないと感じ、私は英語のコメントを書くのが面倒なので、全部あげました。削除しました。より一般的なデザインパターンは、シングルトン、ファクトリ、ストラテジー、およびファサードパターンです。シングルトンファクトリはいたるところにあり、戦略は印象的です。たとえば、メッセージを送信および消費する場合、キューの負荷分散は、ランダム、ハッシュなどを含むNの戦略アルゴリズムタイプです。これは、迅速に実行できるようにするために必要な理由の1つでもあります。自然なサポートクラスターを展開します。永続性も比較的完全であり、CommitLogを使用してディスクを同期的および非同期的に配置します。

18.高スループットでプロデューサーとコンシューマーのパフォーマンスを最適化するにはどうすればよいですか?

開発

  • 同じグループでのマルチマシン展開と並列消費

  • 単一のコンシューマーはコンシューマースレッドの数を増やします

  • 大量消費

    • メッセージバッチプル

    • ビジネスロジックのバッチ処理

運用・保守

  • ネットワークカードのチューニング

  • jvmチューニング

  • マルチスレッドとCPUチューニング

  • キャッシュページ

19.RocketMQがデータの高いフォールトトレランスをどのように保証するかについてお話ししましょう。

  • フォールトトレランスが有効になっていない場合は、キューをポーリングして送信します。失敗した場合は、再試行時に失敗したブローカーをフィルタリングします。

  • フォールトトレランス戦略が有効になっている場合、RocketMQの予測メカニズムを使用して、ブローカーが利用可能かどうかを予測します。

  • 前回失敗したブローカーが利用可能な場合、ブローカーのキューは引き続き選択されます

  • 上記の状況が失敗した場合は、送信するものをランダムに選択してください

  • メッセージを送信するとき、それは呼び出しの時間とエラーが報告されるかどうかを記録し、時間に基づいてブローカーの利用可能な時間を予測します

実際、メッセージを送信するときのキューの選択です。ソースコードは次のとおりです。

org.apache.rocketmq.client.latency.MQFaultStrategy#selectOneMessageQueue()

20.ブローカーが突然ダウンした場合はどうすればよいですか?

ブローカーのマスタースレーブアーキテクチャとマルチコピー戦略。マスターはメッセージを受信した後、それをスレーブに同期するため、複数のメッセージがあり、マスターがダウンしてスレーブ内のメッセージが使用可能になり、MQの信頼性と高可用性が保証されます。また、Rocket MQ4.5.0は、いかだに基づいて最初からDlegderモードをサポートし、HAの本当の感覚を実現しています。

21.ブローカーはどのネームサーバーに情報を登録しますか?

ブローカーは、1つではなく、すべてのネームサーバーに独自の情報を登録するため、これを尋ねることは明らかにあなたを悩ませます!

おすすめ

転載: blog.csdn.net/My_SweetXue/article/details/107381108