学习是最好的投资!
個人的には、すべてのソフトウェアのタイミングはポーリングによって行われ、そのようなタスクを実行するために特別にスレッドを開くと、次のソリューションの方がパフォーマンスが向上する可能性があると感じています。
0. まず、5分ごとにブロードキャストを送信する「スケジュールされたブロードキャスト」が必要です。1. ユーザーが登録するときに、「スケジュールされたブロードキャスト」を聞くためのリスナーを登録します。2. ユーザーがアクティベーションアドレスをクリックすると、メールボックスに追加し、以前に登録したリスナーを閉じます3. リスナーが 2 回目にブロードキャストを受信すると、タスクが実行され、リスニングがキャンセルされます
2 回目のブロードキャスト受信時にタスクを実行する必要があるのは、5 ~ 10 分後にタスクを実行できるようにするためです。もちろん、これでは正確なタイミングが保証されるわけではありません。タイミングの精度を向上させる必要がある場合は、1 分に 1 回、または 1 秒に 1 回ブロードキャストすることもできますが、このシナリオは必要ありません。
スケジュールされたブロードキャストを実装するには、quartz などのツールを使用するか、メッセージ キューを使用してこのビジネスを分離することもできます。
お役に立てば幸いです。不適切な部分や間違っている部分があれば、お気軽にコメントしてください
データベースを使用してポーリングし、クリックされると、対応するレコードを削除します
Spring のタイマーを使用してサービス層で完了します。登録時にデータベースに 0 のフィールドがあります。登録後、5 分後に Spring のタイマーを呼び出してデータベース内のこのフィールドをスキャンし、検証コードを生成します。ユーザーがメールボックス内のアドレスをクリックしてタイマーを停止しました。スプリング タイマーのドキュメントとコードを提供します。
jdkのネイティブタイマーとトリガーのセクションを貼り付けます。タイマーがスケジュールを呼び出すときにリスナーを登録するか、その他のメソッドで呼び出します。詳しくは、JDKの開発ドキュメントを参照してください。ドキュメントの指示に従ってください。私のこの小さなデモはタスクをキャンセルしませんでした。 リーリー
この種のワンタイムタイマーを実装するには、メッセージキューを使用するのがより適しています。実装は比較的簡単で、Java で最も不可欠なものはホイールです。メッセージキュー: RabbitMQ、ActiveMQ、RocketMQ
デザインに何か問題があります:
設計によれば、各ユーザーの登録はスケジュールされたタスクを開始する必要があるため、多数のユーザーが登録した場合はどうなるでしょうか?スケジュールされたタスクは実際にはスレッドです。多数のスレッドを開始すると、CPU リソースが過剰に消費されます。
ユーザーは電子メール アドレスをクリックしてアドレスをアクティブにし、その後それを破棄します。スケジュールされたタスクを JVM に保存すると、登録およびアクティブ化中にユーザーが同じ JVM インスタンスにアクセスすることを保証できないため、クラスターのデプロイ中に失敗する可能性があります。
スケジュールされたタスクは、ユーザーがアクティブ化されていないことを検出し、確認コードを再生成します。ユーザーが次にクリックして電子メールを送信する前に、なぜこの情報を生成する必要があるのでしょうか?
より良いデザインは次のようにあるべきだと思います:
ユーザー登録、ユーザー有効化ステータス = いいえ
ユーザーが [アクティベーションメールを送信] をクリックすると、アクティベーション URL がバックグラウンドで生成され、この UUID はユーザー名に関連付けられ、保存されます (uuid、ユーザー名、有効期限)。その後、メールが送信されます
ユーザーはメール内のアクティベーション URL をクリックしてアプリケーションにアクセスします
アプリケーションは URL 内の uuid を取得して、それがデータベースに存在し、有効期限が切れていないかどうかを確認します。 「はい」の場合は、関連付けられたユーザー名を取得し、ユーザーのアクティブ化ステータス = true を更新し、「いいえ」の場合は uuid を削除します。
uuid ストレージ:
これはデータベースに保存できますが、期限切れのデータをクリーンアップするには、別の (1 つだけ) スレッドを開いて 1 分ごとに実行し、データベース内の期限切れの UUID を削除します。
Redis に保存することもできます。Redis にはデータの ttl を指定できる機能があり、期限切れになると自動的に削除されるため、期限切れの uuid をクリーンアップするために別のスレッドを開く必要はありません。
個人的には、すべてのソフトウェアのタイミングはポーリングによって行われ、そのようなタスクを実行するために特別にスレッドを開くと、次のソリューションの方がパフォーマンスが向上する可能性があると感じています。
0. まず、5分ごとにブロードキャストを送信する「スケジュールされたブロードキャスト」が必要です。
1. ユーザーが登録するときに、「スケジュールされたブロードキャスト」を聞くためのリスナーを登録します。
2. ユーザーがアクティベーションアドレスをクリックすると、メールボックスに追加し、以前に登録したリスナーを閉じます
3. リスナーが 2 回目にブロードキャストを受信すると、タスクが実行され、リスニングがキャンセルされます
2 回目のブロードキャスト受信時にタスクを実行する必要があるのは、5 ~ 10 分後にタスクを実行できるようにするためです。もちろん、これでは正確なタイミングが保証されるわけではありません。タイミングの精度を向上させる必要がある場合は、1 分に 1 回、または 1 秒に 1 回ブロードキャストすることもできますが、このシナリオは必要ありません。
スケジュールされたブロードキャストを実装するには、quartz などのツールを使用するか、メッセージ キューを使用してこのビジネスを分離することもできます。
お役に立てば幸いです。不適切な部分や間違っている部分があれば、お気軽にコメントしてください
データベースを使用してポーリングし、クリックされると、対応するレコードを削除します
Spring のタイマーを使用してサービス層で完了します。登録時にデータベースに 0 のフィールドがあります。登録後、5 分後に Spring のタイマーを呼び出してデータベース内のこのフィールドをスキャンし、検証コードを生成します。ユーザーがメールボックス内のアドレスをクリックしてタイマーを停止しました。スプリング タイマーのドキュメントとコードを提供します。
jdkのネイティブタイマーとトリガーのセクションを貼り付けます。タイマーがスケジュールを呼び出すときにリスナーを登録するか、その他のメソッドで呼び出します。詳しくは、JDKの開発ドキュメントを参照してください。ドキュメントの指示に従ってください。私のこの小さなデモはタスクをキャンセルしませんでした。 リーリー
この種のワンタイムタイマーを実装するには、メッセージキューを使用するのがより適しています。実装は比較的簡単で、Java で最も不可欠なものはホイールです。メッセージキュー: RabbitMQ、ActiveMQ、RocketMQ
デザインに何か問題があります:
設計によれば、各ユーザーの登録はスケジュールされたタスクを開始する必要があるため、多数のユーザーが登録した場合はどうなるでしょうか?スケジュールされたタスクは実際にはスレッドです。多数のスレッドを開始すると、CPU リソースが過剰に消費されます。
ユーザーは電子メール アドレスをクリックしてアドレスをアクティブにし、その後それを破棄します。スケジュールされたタスクを JVM に保存すると、登録およびアクティブ化中にユーザーが同じ JVM インスタンスにアクセスすることを保証できないため、クラスターのデプロイ中に失敗する可能性があります。
スケジュールされたタスクは、ユーザーがアクティブ化されていないことを検出し、確認コードを再生成します。ユーザーが次にクリックして電子メールを送信する前に、なぜこの情報を生成する必要があるのでしょうか?
より良いデザインは次のようにあるべきだと思います:
ユーザー登録、ユーザー有効化ステータス = いいえ
ユーザーが [アクティベーションメールを送信] をクリックすると、アクティベーション URL がバックグラウンドで生成され、この UUID はユーザー名に関連付けられ、保存されます (uuid、ユーザー名、有効期限)。その後、メールが送信されます
ユーザーはメール内のアクティベーション URL をクリックしてアプリケーションにアクセスします
アプリケーションは URL 内の uuid を取得して、それがデータベースに存在し、有効期限が切れていないかどうかを確認します。 「はい」の場合は、関連付けられたユーザー名を取得し、ユーザーのアクティブ化ステータス = true を更新し、「いいえ」の場合は uuid を削除します。
uuid ストレージ:
これはデータベースに保存できますが、期限切れのデータをクリーンアップするには、別の (1 つだけ) スレッドを開いて 1 分ごとに実行し、データベース内の期限切れの UUID を削除します。
Redis に保存することもできます。Redis にはデータの ttl を指定できる機能があり、期限切れになると自動的に削除されるため、期限切れの uuid をクリーンアップするために別のスレッドを開く必要はありません。