分散セッションを理解する

皆さんこんにちは。私は再びCRUD エンジニアです。最近、同僚の 1 人が突然分散Seesionイシューに注目し、その後二人で議論しました。今日はSession分散ナレッジ ポイントを整理したいと思います。

多くのシステムでは、ユーザーのログイン機能がSession実装されています。クライアントはユーザー名とパスワードを入力してリクエストを送信します。サーバーはリクエストを受信すると、現在対応するものを作成Sessionして返します。ブラウザはそれを保存します。クライアントは、他のメソッドを呼び出してサーバーにリクエストを送信するときにそれを実行します。サーバーはリクエストを受信すると、そのリクエストが存在するかどうかを確認し、ユーザーがログインしているかどうかを判断します。SessionJessionIdcookieJessionIdSession

分散環境では、Sessionサーバーが 2 つのサーバー A と B にデプロイされている場合に問題が発生します。

ユーザーがログインすると、リクエストはサーバー A に送信されます。サーバー A はリクエストを作成してSession返しますJessionId

ユーザーが個人情報を取得すると、リクエストはサーバー B に送信されますが、リクエストに含まれる対応する情報はJesssionIdサーバー B では見つかりませSessionん。

このとき、サーバー B はクライアントに例外リマインダーを返します (ユーザーはログインしていません)。クライアントが戻り値を受け取ると、ユーザーは再びログイン インターフェイスにリダイレクトされたことがわかります。

次に、分散環境でSession一貫性を実現する方法を見てみましょう。

1. クライアントストレージ

Session分散環境では、クライアントからの複数のリクエストが複数のサーバーに到達する可能性があるため、戦略を変更して情報をクライアントに直接保存できますか?
答えはもちろん「はい」です。サーバーはSession情報をサーバーに直接保存するcookieため、Sessionサーバーのcookie一貫性が確保されます。ただし、これはお勧めしません。一部の情報をサーバーに保存することはデータ セキュリティのリスクを引き起こす可能性があるためです。この情報はクライアントに公開されるため、重大なセキュリティ リスクが生じます。

欠点がある

  • システムセキュリティの問題
  • Cookieにはデータ型とデータサイズに制限があります

2. セッションコピー

サーバー A をSessionサーバー B にコピーし、Sessionサーバー B をサーバー A にコピーして、2 つのサーバーのSession整合性を保ちます。他の Web コンテナと同様にtomcat、これらはすべてSessionレプリケーション機能をサポートしており、同じ LAN 内で 1 つのサーバーがSession他のサーバーにブロードキャストします。
ここに画像の説明を挿入します

欠点がある

  • 同じネットワーク セグメント内にサーバーが多すぎる場合、各サーバーがセッションをコピーするため、サーバー メモリが無駄に消費されます。

3. セッションの持続性

サーバーのリバース プロキシを使用してNginxサーバー A とサーバー B をプロキシし、ip_hash負荷戦略を使用してクライアントとサーバーをバインドします。つまり、クライアント A は初めてサーバー B にアクセスするため、2 回目のアクセスはサーバー B にも送信される必要があるため、不整合の問題は発生しませんSession

ここに画像の説明を挿入します
欠点がある

  • サーバー A がダウンすると、クライアント A とクライアント B がSession失われ、クライアント A とクライアント B からのリクエストはすべて失敗します。

4. セッションの一元管理

この方法はすべてのサーバーをSession均一に管理するもので、redis他の高性能サーバーを使用して一元管理することもできSession、Spring ではspirng-sessionこの方法で処理されるSession一貫性の問題を公式に提供しています。これは、現在多くの企業で使用されている分散Sessionソリューションでもあります。

ここに画像の説明を挿入します

春季セッション実戦

SpringSession配布に対処するためのソリューションを提供しますSpring SessionSpring Sessionユーザーセッションを管理するための API と実装を提供します。

Spring Sessionredis、 、などの一般的に使用されるリポジトリのサポートが提供されmongodb、との透過的な統合が提供されます。つまり、開発者は、サポートされている実装を使用して実装を切り替えることができますmysqlSpring SessionHttpSessionSpring SessionHttpSession

インターネット上でSpring Session実装フローチャートを見つけて、パッケージングのリクエストとレスポンスを変更するためのフィルター
ここに画像の説明を挿入します
Spring Sessionを追加しましたSessionRepositoryFilter。パッケージ化されたリクエストは、メソッドSessionRepositoryRequestWrapperを呼び出すgetSession()ときに実際にSpring Session実装されますSession

Spring Session使い方は非常に簡単で、関連する依存関係を追加した後は、HttpSession直接操作するだけで効果を得ることができます。

pom.xml

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>

yml

spring:
  session:
  	# session 失效时间(分钟)
    timeout: 86400
    # session 使用redis存储  
    store-type: redis
    # redis 配置
  redis:
  	# redis 端口号
    port: 6379
    # redis 服务器地址
    host: localhost
    # redis库
    database: 0
    # redis 密码
    password: 123456

セッションを使用する

public String test( HttpServletRequest request){
    
    
    HttpSession session = request.getSession();
    session.setAttribute("key_big_handsome","value:it is me");
    return session.getAttribute("key_big_handsome").toString();
}

このメソッドを実行した後、redis を確認します。
ここに画像の説明を挿入します

  • 最初のものは、SessionRedis で有効期限を表すために使用されます。この kv には有用なデータは保存されず、Session有効期限を表すために設定されているだけです。このキーRedisの有効期限がSession有効期限間隔になります。
  • SessionこのIDを格納する 2 番目のものは、Set一種のRedisデータ構造です。このキーの最後の 1681633260000 値は、次の 1 分にロールされたセッション有効期限の瞬間に基づいて計算されたタイムスタンプです。
  • 3 番目は、有効期限間隔、最新アクセス時刻などSessionの詳細情報を保存するために使用されます。Sessionattributes

Spring Sessionspring:session:expirations:その中にはスケジュールされたタスクがあり、対応する整数タイムスタンプの有効期限を 1 分ごとにクエリしSessionId、これに再度アクセスしてSessionId、キーの有効期限イベント、spring:session:sessions:expires:SessionIdつまり有効期限イベントRedisを生成できるようにします。タイムリーに。Session

おすすめ

転載: blog.csdn.net/qq_43649799/article/details/130169056