タイトルにあるように、ログイン システムはありますが、古いプロジェクトにはキャッシュがありません (キャッシュを追加する権限がありません)。ただし、別のサービスは以前の http リクエストのデータを使用する必要があります ( user) を毎回重複しないように保存したいのですが、http リクエストを送信するとリソースが無駄になります。
背景 springmvc
現在、3つの方法を考えています:
1. セッション (HttpSessionListener) 内にスローします。これが最も簡単なはずですが、潜在的な問題がわかりません。
2. スレッドローカル内にスローします (コントローラーは静的なスレッドローカル変数を作成するか、 contextholder)
3.controller ConcurrentHashMap のメンバーを作成し、そこに「ユーザー ID、http リクエストで取得したデータ」に従ってデータを入れますが、これは絶対に不可能で、ヒープ領域で OOF が発生する可能性があります
2 番目のオプションで考えられる問題について話しましょう。
1. インターネット上でメモリ リークの問題の可能性が指摘されており、PermGen で OOF が発生します。元のテキストは ThreadLocal メモリ リークの例の分析に関連付けられています。
2. リクエスト スレッドのデータ文字列は表示されますか? たとえば、リクエスト スレッドは 2 人のユーザー (A と B) のリクエストを同時に処理します。B はリクエスト スレッドに独自のデータを置き、A のデータをカバーします。スレッドサービスAをリクエストしたところ、Bのデータが取得されました。 。
方法 1 は最も単純で最もよく使用されます。ユーザー数が多すぎる場合、または負荷分散が行われる場合は、Session の集中ストレージを実装する必要があります。HttpSession の集中ストレージをサポートできる既製のソリューションが多数あります。 Redis、MongoDB、MySQL など、すべてあります。GitHub で検索してください。
方法 2 では問題は解決されません。主な理由は、ユーザーがログインした後、複数のリクエストが複数のスレッドに分類される可能性があるためです。ご指摘の2点目も理由です。
方法 3 も実装方法です。実際、Tomcat の HttpSession は ConcurrentHashMap を使用して実装されます (キーとして userId の代わりに sessionId を使用するだけです)。ただし、注意すべき点は、Map 内の各 Key-Value を自分で管理する必要があることです。ライフサイクル。たとえば、セッションがタイムアウトした場合は、時間内に削除する必要があります。