ネイティブRabbitMQに基づくVivoの高可用性アーキテクチャプラクティス

1.背景説明

Vivoは、メッセージングミドルウェアサービスをビジネスに提供するために、オープンソースのRabbitMQ拡張に基づいて2016年にRabbitMQを導入しました。

2016年から2018年にかけて、すべての企業がクラスターを使用していました。事業規模が拡大するにつれて、クラスターの負荷が重くなり、クラスターの障害が頻繁に発生しました。

2019年、RabbitMQは高可用性の構築段階に入り、高可用性コンポーネントのMQネームサービスとRabbitMQクラスターの都市内デュアルアクティブ構築を完了しました。

同時に、業務用クラスターの物理的な分割が実行され、業務用クラスターの割り当てと動的調整は、クラスターの負荷とビジネストラフィックに厳密に基づいています。

2019年に高可用性が構築されて以来、ビジネストラフィックは10倍に増加し、クラスターで重大な障害は発生していません。

RabbitMQは、金融システムで生まれたAMQPプロトコルを実装するオープンソースのメッセージブローカーソフトウェアです。

豊富な特徴があります:

  1. メッセージの信頼性の保証:RabbitMQは、確認を送信することによってメッセージ送信の信頼性を保証し、クラスタリング、メッセージの永続性、およびミラーリングキューによってクラスター内のメッセージの信頼性を保証し、消費確認によってメッセージの消費の信頼性を保証します。

  2. RabbitMQは、複数の言語でクライアントを提供します。

  3. さまざまなタイプの交換を提供します。メッセージがクラスターに送信された後、メッセージは交換を介して特定のキューにルーティングされます。

  4. RabbitMQは、完全な管理バックグラウンドと管理APIを提供します。これらは、管理APIを介して自作の監視システムとすばやく統合できます。

特定のプラクティスでRabbitMQによって発見された問題:

  1. 高いビジネス可用性を確保するために、複数のクラスターが物理的な分離に使用され、複数のクラスターには管理用の統合プラットフォームがありません。

  2. ネイティブのRabbitMQクライアントは、クラスターアドレスを使用して接続します。複数のクラスターセットを使用する場合、ビジネスはクラスターアドレスを気にする必要があり、使用法が混乱します。

  3. ネイティブRabbitMQは、単純なユーザー名/パスワードの検証のみを行い、使用されるビジネスアプリケーションパーティを認証しません。さまざまなビジネスの交換/キュー情報を簡単に混在させることができるため、異常なビジネスアプリケーションが発生します。

  4. 多くのビジネスアプリケーションパーティが使用されており、メッセージの送信者と消費者の関連情報を維持するためのプラットフォームがありません。複数のバージョンを繰り返した後、相手を特定することはできません。

  5. クライアントには無制限のフローがあり、突然の異常なトラフィックはクラスターに影響を与えたり、クラスターを破壊したりします。

  6. クライアントには、ユーザーが実装する必要のある例外メッセージの再送信戦略はありません。

  7. クラスタ内のメモリオーバーフローが原因でクラスタがブロックされている場合、他の使用可能なクラスタに迅速かつ自動的に転送することはできません。

  8. ミラーリングされたキューでは、キューのマスターノードは特定のノードに分類されます。クラスターキューの数が多いと、ノードの負荷が不均衡になりがちです。

  9. RabbitMQにはキューの自動バランシング機能がなく、キューが多いとクラスターノードの負荷が不均一になる傾向があります。

第二に、全体的な構造

ネイティブRabbitMQに基づくVivoの高可用性アーキテクチャプラクティス

1.MQ-Portal--アプリケーション使用アプリケーションをサポート

過去にビジネスチームがRabbitMQを使用していた場合、アプリケーションアプリケーションのトラフィックとドッキングされたアプリケーション情報はすべてオフライン形式で記録され、散在していてタイムリーに更新されていませんでした。したがって、ビジネスの現在の実際の使用状況を正確に理解することはできませんでした。したがって、アプリケーションプロセスの視覚化を通じて、プラットフォーム化は、アプリケーションによって使用されるメタデータ情報を確立します。

ネイティブRabbitMQに基づくVivoの高可用性アーキテクチャプラクティス

MQ-Portalの申請プロセス(上図を参照)により、メッセージ送信アプリケーション、コンシューマーアプリケーション、交換/キューの使用、トラフィックの送信、およびその他の情報使用アプリケーションは、送信後に承認のためにinvivo内部作業指示プロセスに入ることが決定されます。

ネイティブRabbitMQに基づくVivoの高可用性アーキテクチャプラクティス

作業指示プロセスが承認されたら、作業指示インターフェイスを介してコールバックし、アプリケーションで使用される特定のクラスターを割り当て、クラスター上に交換/キューバインディング関係を作成します。

正式な環境でサービスの高い可用性を確保するために複数のクラスターが物理的に分離されているため、交換/キュー名だけで使用されているクラスターを見つけることは不可能です。

各交換/キューは、rmq.topic.keyとrmq.secret.keyの一意のペアを介してクラスターに関連付けられているため、SDKの起動プロセス中に使用される特定のクラスターを見つけることができます。

rmq.topic.keyとrmq.secret.keyは、チケットのコールバックインターフェイスに割り当てられます。

ネイティブRabbitMQに基づくVivoの高可用性アーキテクチャプラクティス

2.クライアントSDK機能の概要

クライアントSDKは、spring-messageとspring-rabbitに基づいてカプセル化され、これに基づいて、アプリケーション認証、クラスターアドレス指定、クライアント電流制限、生産と消費のリセット、転送のブロックなどの機能を提供します。

2.1、アプリケーション使用認証

オープンソースのRabbitMQは、ユーザー名とパスワードのみを使用してクラスターへの接続を許可するかどうかを決定しますが、アプリケーションが交換/キューの使用を許可するかどうかは検証されません。

異なるサービスの交換/キューの混合を回避するには、アプリケーションを認証する必要があります。

アプリケーションの認証は、SDKとMQ-NameServerの協力により完了します。

アプリケーションが起動すると、最初にアプリケーション構成のrmq.topic.key情報がMQ-NameServerに報告され、MQ-NameServerは、使用されたアプリケーションが適用されたアプリケーションと整合性があるかどうかを判断し、SDKのメッセージ送信中に2次検証が実行されます。

/**
  * 发送前校验,并且获取真正的发送factory,这样业务可以声明多个,
  * 但是用其中一个bean就可以发送所有的消息,并且不会导致任何异常
  * @param exchange 校验参数
  * @return 发送工厂
*/
public AbstractMessageProducerFactory beforeSend(String exchange) {
    if(closed || stopped){
        //上下文已经关闭抛出异常,阻止继续发送,减少发送临界状态数据
        throw new RmqRuntimeException(String.format("producer sending message to exchange %s has closed, can't send message", this.getExchange()));
    }
    if (exchange.equals(this.exchange)){
        return this;
    }
    if (!VIVO_RMQ_AUTH.isAuth(exchange)){
        throw new VivoRmqUnAuthException(String.format("发送topic校验异常,请勿向无权限exchange %s 发送数据,发送失败", exchange));
    }
    //获取真正的发送的bean,避免发送错误
    return PRODUCERS.get(exchange);
}

2.2、クラスターアドレス指定

前述のように、アプリケーションはRabbitMQを使用して、クラスターの負荷とビジネストラフィックに厳密に従ってクラスターを割り当てます。したがって、特定のアプリケーションで使用される異なる交換/キューが異なるクラスターに割り当てられる場合があります。

ビジネス開発の効率を向上させるには、複数のクラスターがビジネスに与える影響をシールドする必要があります。これにより、アプリケーションによって構成されたrmq.topic.key情報に従ってクラスターが自動的にアドレス指定されます。

2.3、クライアントの現在の制限

ネイティブSDKクライアントは送信トラフィックを制限しません。一部のアプリケーションに異常があり、MQにメッセージを送信し続けると、MQクラスターが圧倒される可能性があります。また、クラスターは複数のアプリケーションによって使用され、単一のアプリケーションによって引き起こされるクラスターへの影響は、異常なクラスターを使用するすべてのアプリケーションに影響します。

したがって、SDKでクライアント側の電流制限機能を提供する必要があり、必要に応じて、クラスターの安定性を確保するために、アプリケーションがクラスターにメッセージを送信することを制限できます。

2.4。生産と消費のリセット

(1)事業規模の拡大に伴い、クラスターの負荷は増大し続けていますが、現時点ではクラスター事業を分割する必要があります。分割プロセス中のビジネスの再開を回避するために、生産と消費のリセット機能が必要です。

(2)クラスターの異常により、消費者がオフラインになる可能性があります。現時点では、生産と消費のリセットにより、ビジネスの消費が急速に増加する可能性があります。

生産と消費のリセットを実現するには、次のプロセスを実現する必要があります。

  • 接続ファクトリ接続パラメータをリセットします

  • 接続をリセット

  • 新しい接続を確立する

  • 生産と消費を再開する
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses(address);
connectionFactory.resetConnection();
rabbitAdmin = new RabbitAdmin(connectionFactory);
rabbitTemplate = new RabbitTemplate(connectionFactory);

同時に、MQ-SDKには異常なメッセージの再送信戦略があり、本番リセットプロセスによって引き起こされる異常なメッセージ送信を回避できます。

2.5、転送のブロック

RabbitMQは、メモリ使用量が40%を超えるか、ディスク使用量が制限を超えると、メッセージの送信をブロックします。

vivoミドルウェアチームはRabbitMQの都市内アクティブ-アクティブの構築を完了したため、クラスターがブロックされたときにブロックの高速転送を完了するために、生産と消費を通じてアクティブ-アクティブクラスターにリセットできます。

2.6、マルチクラスタースケジューリング

アプリケーションの開発により、単一のクラスターはアプリケーションのトラフィック需要を満たすことができなくなり、クラスターキューはすべてミラーリングされたキューになり、クラスターノードを追加するだけではビジネスサポートトラフィックの単一クラスターの水平方向の拡張を実現できなくなります。

したがって、SDKは、マルチクラスタースケジューリング機能をサポートし、トラフィックを複数のクラスターに分散することで大規模なビジネストラフィックのニーズを満たす必要があります。

3.MQ-NameServer--高速フェイルオーバーを実現するためのMQ-SDKのサポート

MQ-NameServerはステートレスサービスであり、クラスター展開を通じて高い可用性を確保できます。主に次の問題を解決するために使用されます。

  • MQ-SDKは認証を開始し、アプリケーションはクラスターポジショニングを使用します。

  • MQ-SDKタイミングインジケーターレポート(送信されたメッセージの数、消費されたメッセージの数)を処理し、現在使用可能なクラスターアドレスを返して、クラスターが異常な場合にSDKが正しいアドレスに従って再接続するようにします。

  • MQ-SDKを制御して、生産と消費をリセットします。

4.MQ-Serverの高可用性展開の実践

ネイティブRabbitMQに基づくVivoの高可用性アーキテクチャプラクティス

RabbitMQクラスターはすべて、同じ都市のアクティブ-アクティブ展開アーキテクチャを採用しており、クラスターの可用性を確保するためにMQ-SDKおよびMQ-NameServerによって提供されるクラスターアドレス指定およびフェイルオーバー機能に依存しています。

4.1。クラスター分割脳問題の処理

RabbitMQは、3つのクラスター分割脳回復戦略を公式に提供します。

(1)無視する

スプリットブレインの問題は無視して対処しないでください。スプリットブレインが発生したときに回復するには、人間の介入が必要です。人間の介入が必要なため、一部のメッセージが失われる可能性があります。これは、ネットワークの信頼性が非常に高い場合に使用できます。

(2)pause_minority

ノードがクラスターノードの半分以上との接続を失うと、クラスターノードの半分以上との通信が再開したことを検出するまで、ノードは自動的に一時停止します。極端な場合、クラスター内のすべてのノードが一時停止され、クラスターが使用できなくなります。

(3)自動修復

マイノリティノードは自動的に再起動します。この戦略は、再起動ノードのメッセージが失われるため、データの信頼性ではなく、主にサービスの可用性を優先するために使用されます。

RabbitMQクラスターはすべて同じ都市に配置されているため、単一クラスターの異常なビジネストラフィックをデュアルアクティブコンピュータールームクラスターに自動的に移行できる場合でも、スプリットブレインの問題を回避するためにpause_minority戦略が選択されます。

2018年、スプリットブレインクラスターはネットワークジッターによって何度も引き起こされました。クラスタースプリットブレイン回復戦略が変更された後、スプリットブレインの問題は発生しなくなりました。

4.2、クラスター高可用性ソリューション

RabbitMQはクラスター展開を採用し、クラスター分割脳回復戦略はpause_minorityモードを採用するため、各クラスターには少なくとも3つのノードが必要です。

可用性の高いクラスターを展開し、クラスターキューの数を制御するには、5つまたは7つのノードを使用することをお勧めします。

クラスターキューはミラーリングされたキューであり、メッセージが確実にバックアップされ、ノードの異常によるメッセージの損失を回避します。

ノードが異常に再起動したときにメッセージが失われないように、Exchange、キュー、およびメッセージはすべて永続的に設定されています。

ノードのメモリ使用量の変動を減らすために、キューはすべてレイジーキューに設定されます。

4.3。同じ都市でのライブアクティブ建設

同等のクラスターがデュアルコンピュータールームに展開され、デュアルクラスターはフェデレーションプラグインを介してアライアンスクラスターに形成されます。

コンピュータルームのアプリケーションマシンは、専用回線のジッターによる異常なアプリケーションの使用を回避するために、コンピュータルームのMQクラスタに優先的に接続されます。

MQ-NameServerハートビートを介して利用可能な最新のクラスター情報を取得し、例外が発生した場合はアクティブ-アクティブクラスターに再接続して、アプリケーション機能の迅速な回復を実現します。

3.将来の課題と展望

現在、RabbitMQの使用は主にMQ-SDK側とMQ-NameServer側で強化されていますが、SDKの実装はより複雑ですが、後でメッセージミドルウェアのプロキシレイヤーを構築して、SDKを簡素化し、ビジネストラフィックをより詳細に管理できるようになることが望まれます。

著者:デレク

おすすめ

転載: blog.51cto.com/14291117/2544083