事故現場分析:
革新的なビジネス製品の発売により、オペレーティング製品は、登録招待メカニズムを使用してポイント関連のアクティビティを取得し、いくつかのアクティビティを通じてユーザーを刺激したいと考えています。将来ポイントを配布する他の可能なアクティビティがある可能性があることを考慮して、設計時にmqメッセージモードを使用してポイントを発行し、非同期デカップリングを行い、データの最終的な整合性を確保できます。
ユーザーポイントの計算に同時操作が存在する可能性があることを考慮して、2つのソリューションが考えられます:1.ユーザーポイントの計算に分散ロック方式が使用され、同じユーザー操作が同期され
ます。2.キュー、FIFOを使用することの固有の利点同じユーザーのポイントが同じキューに配置されている限り、ユーザーポイントの計算が確実に同期されるように、キューを順番に使用できます。
考えて選別した後、最終的にRocketMQキューFIFOを使用してポイントを計算することにしたので、無意識のうちに泥沼に陥りました。会社がパッケージ化したMQメッセージ処理は、メッセージの順次送信とそれに関連するメッセージのカプセル化を行わなかったため、ユーザーの一意のIDハッシュを使用して送信する残りの選択肢を選択し、会社のパブリックメソッドで順次送信メソッドのレイヤーを再カプセル化しました。キュー。同じユーザーのクレジットメッセージを同じキューに送信できることを確認し、MQがメッセージSUCCESS
を消費した後にMQがメッセージを消費し、他のキューメッセージを消費すると想定します。そのため、開発が完了してからテストが完了し、コンカレントテストで結果テストを行うと、ユーザーポイントの計算は、実際に発行されるポイント数よりも常に少なくなります。それで、熟考に陥り始めました......
トラブルシューティング:
だから私は自分のコードの問題を疑い始めました、それをチェックして、チェックしてください...ロジックに問題はありません。それで推測し始めました:
1. 难道是消息发送丢失?或者发送的时候不在同一个队列?
メッセージ送信ログを乱暴に印刷するログを確認すると、メッセージの送信と消費はすべて正常であることがわかります。また、ハッシュアルゴリズムによると、同じ人物が同じキューにいますが、なぜ同時コンピューティングがあるのですか?
2. 消息消费的时候是并发消费的?
RocketMqの以前の習熟度では十分ではないMessageListenerOrderly
ため、メッセージの順次消費を保証するために、このリッスン消費を使用する方法で元の順次消費も保証する必要があるかどうかは明らかではありませんDefaultMessageListener
。ブローカーはメッセージの消費順序を完全に保証するのではなく、送信されるメッセージの順序のみを保証できます。、それが順次送信され、スレッドがキュー上のメッセージのみを消費することを確認する限り、彼は注文されます。
解決策:
同社のMQメソッドのカプセル化では、ユーザーの一意のID Hashcode
残余選択キューを使用して2番目のカプセル化を行い、MessageListenerOrderly
メッセージの監視と消費を使用してメッセージの消費順序を確認しました。テストは同時計算によって解決され、積分計算の問題は完全に正しかった。