問題の根本的な理由は、Java EE が別の方法で動作するように設計されていることです。サービス スレッドをブロック/待機しようとすることは、重要な禁止事項の 1 つです。最初にその理由を説明し、その後で問題を解決する方法を説明します。
Java EE (Web 層と EJB 層の両方) は、非常に大きなサイズ (クラスター内の数百台のコンピューター) に拡張できるように設計されています。ただし、それを行うために、設計者は次の仮定を行う必要がありました。これは、コーディング方法に関する特定の制限です。
これらのルールに従えば、Java EE コンテナーは、ノードのシャットダウン、新しいノードの開始、ユーザー セッションの移行など、特定の開発者コードなしでクラスターを正常に管理できます。開発者は、グラフィカル インターフェイスとビジネス ロジックを記述します。すべての「配管」は、構成可能なコンテナ機能によって管理されます。
また、実行時に Java EE コンテナーを監視および管理することもできます。このソフトウェアは、稼働中のシステムでアプリケーションのパフォーマンスと動作の問題を追跡できます。
<スナーク>まあ、それが理論でした。実際には、AOSP やコード インジェクション手法につながる重要な制限が見逃されていることが示唆されていますが、それは別の話です < /snark >
[これについては、ネット上で多くの議論があります。EJB に焦点を当てたものは次のとおりです: Java EE コンテナーでのスレッドの生成はなぜ推奨されないのですか? Tomcat などの Web コンテナーについてもまったく同じことが言えます]
エッセイで申し訳ありませんが、これはあなたの問題にとって重要です。スレッドの制限により、別の後のリクエストを待機している Web リクエストをブロックしないでください。
現在の設計のもう 1 つの問題は、ユーザーがネットワークから切断された場合、電力が不足した場合、または単にあきらめることを決定した場合にどうなるかということです。おそらくタイムアウトしますが、どれくらい後ですか?おそらく、一部の顧客にとっては早すぎて、満足度の問題が発生する可能性があります。タイムアウトが長すぎると、Tomcat のすべてのワーカー スレッドがブロックされ、サーバーがフリーズする可能性があります。これにより、組織はサービス拒否攻撃を受けやすくなります。
編集:アルゴリズムのより詳細な説明が公開された後、改善された提案。
Web ワーカー スレッドをブロックすることの悪い習慣とサービス拒否の可能性に関する上記の説明にもかかわらず、Android フォンの通知に対応するための短い時間枠がユーザーに提示されることは明らかです。セキュリティを強化するために、適度に小さく保ってください。この時間枠は、応答に対する Tomcat のタイムアウトよりも低く抑えることもできます。そのため、スレッド ブロッキング アプローチを使用できます。
この問題を解決するには、次の 2 つの方法があります。
- ソリューションの焦点をクライアント エンドに変更する- ブラウザで Javascript を使用してサーバーをポーリングする
- クラスター内のノード間の通信により、Android アプリから承認応答を受信するノードが、サーブレットの応答をブロックしているノードのブロックを解除できるようになります。
アプローチ 1 の場合、ブラウザーは Javascript を介してサーバーをポーリングし、Tomcat 上の Web サービスへの AJAX 呼び出しを行います。True
Android アプリが認証されると、AJAX 呼び出しが返されます。利点: クライアント側、サーバーでの最小限の実装、サーバーでのスレッドのブロックなし。短所: 待機中は、頻繁に呼び出しを行う必要があります (おそらく 1 秒に 1 回 - ユーザーはこの待ち時間に気付かないでしょう)。これにより、大量の呼び出しが発生し、サーバーに追加の負荷がかかります。
アプローチ 2 の場合も、選択肢があります。
Object.wait()
オプションでノード ID、IP、またはその他の識別子を共有データ ストアに保存してスレッドをブロックします。その場合、Android アプリの承認を受け取るノードは次のことを行う必要があります。
- 現在ブロックしているノードを見つけるか、クラスタ内のすべてのノードにブロードキャストします
上記の 1. のノードごとに、ブロックを解除するユーザー セッションを識別するメッセージを送信します。メッセージは次の方法で送信できます。
- 各ノードに内部専用のサーブレットを配置します。これは、Android アプリの承認を実行するサーブレットによって呼び出されます。内部サーブレットは
Object.notify
正しいスレッドで呼び出します
- JMS pub-sub メッセージ キューを使用して、クラスターのすべてのメンバーにブロードキャストします。各ノードはサブスクライバーであり、通知を受信すると
Object.notify()
正しいスレッドを呼び出します。
スレッドの続行が承認されるまでデータ ストアをポーリングする: この場合、Android アプリが行う必要があるのは、状態を SQL DB に保存することだけです。