仕事を始めて以来、毎日さまざまな技術用語に出会います。コンピュータ専門の学位を持っていないため、多くの用語が理解できません。そこで、ブログを見て整理することにしました。長い間続けているうちに、すべてを理解できるようになりました。
仕事を始めて以来、毎日さまざまな技術用語に出会います。コンピュータ専門の学位を持っていないため、多くの用語が理解できません。そこで、ブログを見て整理することにしました。長い間続けているうちに、すべてを理解できるようになりました。
token,session,cookie について#
-
まず、彼の意味を説明します:
-
Token の導入:Token は、クライアントがサーバーに頻繁にデータを要求し、サーバーが頻繁にデータベースでユーザー名とパスワードを照合し、ユーザー名とパスワードが正しいかどうかを判断し、適切なメッセージを表示するという背景の中で、Token が生まれました。
-
Token の定義:Token は、サーバーが生成する一連の文字列で、クライアントがリクエストを行うためのトークンです。初回ログイン後、サーバーは Token を生成し、この Token をクライアントに返します。その後、クライアントはこの Token を持ってデータを要求するだけで、再度ユーザー名とパスワードを持参する必要はありません。
-
Token を使用する目的:Token の目的は、サーバーの負荷を軽減し、頻繁なデータベースクエリを減らし、サーバーをより堅牢にすることです。
Token の意味を理解した後、なぜそれを使用するのかがより明確になります。
2. Token の使用方法は?
これはこの記事の重要なポイントで、ここでは一般的な2つの方法を紹介します。
- デバイス番号 / デバイス MAC アドレスを Token として使用する(推奨)
クライアント:クライアントはログイン時にデバイスのデバイス番号/MAC アドレスを取得し、それをパラメータとしてサーバーに渡します。
サーバー:サーバーはそのパラメータを受け取った後、変数に格納し、同時にそれを Token としてデータベースに保存し、その Token をセッションに設定します。クライアントがリクエストするたびに、クライアントが渡した Token とサーバーのセッション内の Token を比較し、一致すれば許可し、一致しなければ拒否します。
分析:この時、クライアントとサーバーは一意の識別子 Token を統一し、各デバイスが一意のセッションを持つことを保証します。この方法の欠点は、クライアントがデバイス番号 / MAC アドレスをパラメータとして渡す必要があり、サーバー側でも保存する必要があることです。利点は、クライアントが再ログインする必要がなく、一度ログインすればずっと使用できることです。タイムアウトの問題はサーバー側で処理されます。どう処理するか?サーバーの Token がタイムアウトした場合、サーバーはクライアントが渡した Token をデータベースで照会し、変数 Token に値を割り当てるだけで、Token のタイムアウトが再びカウントされます。
- セッション値を Token として使用する
クライアント:クライアントはユーザー名とパスワードを持ってログインするだけです。
クライアント:クライアントはユーザー名とパスワードを受け取り、正しい場合はローカルで取得した sessionID を Token としてクライアントに返します。クライアントはその後、データを要求する際にそれを持参するだけです。
分析:この方法の利点は便利で、データを保存する必要がないことですが、欠点はセッションが期限切れになると、クライアントは再度ログインしなければデータにアクセスできないことです。
3. 使用中に発生する問題と解決策は?
先ほど、Token の 2 つの使用方法を簡単に紹介しましたが、使用中にさまざまな問題が発生しました。Token の最初の方法では、ネットワークが不良であったり、同時リクエストが発生した場合に、データが複数回重複して送信される問題を隠していました。
この問題の解決策:セッションと Token を組み合わせることで解決できます。どう組み合わせるかは、以下の説明をご覧ください:
セッションは、単一のオペレーターが全体の操作プロセスでサーバーと通信を維持するための唯一の識別情報です。同じオペレーターの複数のリクエストの間、セッションは常に同じオブジェクトであり、複数のオブジェクトではありません。ロックをかけることができます。同じオペレーターの複数のリクエストが入ると、セッションを通じて一方向の通行のみを制限できます。この記事では、セッションを使用し、セッション内に Token を追加して、同じオペレーターが同時に重複したリクエストを行ったかどうかを検証します。最後のリクエストが到着したとき、セッション内の Token を使用してリクエスト内の Token が一致するかどうかを検証します。一致しない場合、重複送信と見なされ、通過を許可されません。
これが重複送信を解決するための方法です。
- セッション、Token、Cookie
セッション認証とは何ですか?
HTTP プロトコルはステートレスプロトコルであるため、ユーザーがバックエンドアプリケーションにユーザー名とパスワードを提供して認証を行った場合、次回のリクエストでもユーザーはユーザー名とパスワードを持参する必要があります。バックエンドアプリケーションがどのユーザーからのリクエストであるかを識別できるようにするためには、バックエンドサーバーにユーザーのログイン情報のコピーを保存する必要があります。この情報は、フロントエンドのリクエストに応じてブラウザに返され(フロントエンド)、フロントエンドはそれを Cookie として保存します。次回のリクエスト時にフロントエンドがバックエンドアプリケーションに送信すると、バックエンドアプリケーションはこのリクエストがどのユーザーからのものであるかを識別できます。これが従来のセッション認証です。
セッション認証のプロセスはどのようなものですか?
ブラウザが初めてサーバーにアクセスすると、サーバーはセッションを作成し、同時にそのセッションに対して一意のセッションキー、すなわち sessionid を生成します。そして、sessionid と対応するセッションをそれぞれキーと値としてキャッシュに保存し、データベースに永続化することもできます。その後、サーバーは sessionid を Cookie の形式でクライアントに送信します。こうして、ブラウザが次回アクセスする際には、Cookie 内の sessionid を持参します。サーバーは sessionid に基づいて対応するセッションを見つけてマッチングを行います。
もう一つの方法は、ブラウザが Cookie を無効にしたり、Cookie をサポートしていない場合で、URL 書き換えの方法でサーバーに送信することができます。
Token 認証とは何ですか?
Token の意味は「トークン」で、サーバーが生成する一連の文字列で、クライアントがリクエストを行うための識別子です。
ユーザーが初めてログインすると、サーバーは Token を生成し、この Token をクライアントに返します。その後、クライアントはこの Token を持参してデータを要求するだけで、再度ユーザー名とパスワードを持参する必要はありません。
Token 認証とセッション認証の違いは何ですか?
Token とセッションは、実際にはどちらも認証のためのもので、セッションは一般的に「会話」と訳され、Token はより多くの場合「トークン」と訳されます。
セッションはサーバーに一部を保存し、キャッシュ、ファイル、データベースに保存される可能性があります。同様に、セッションと Token には有効期限があり、有効期限を管理する必要があります。
実際には、Token とセッションの問題は、時間と空間の競争の問題です。セッションは空間を時間に変え、Token は時間を空間に変えます。どちらを選択するかは具体的な状況によります。
確かに「クライアントが記録し、毎回アクセス時に持参する」という点では共通していますが、Token は自己完結型に設計されることが容易です。つまり、バックエンドは何も記録する必要がなく、毎回無状態のリクエストを行い、毎回解読して検証し、合法 / 違法の結論をその場で得ることができます。このすべての判断基準は、CS の両端に固化されたロジックを除いて、全体の情報は自己完結型です。これが本当の無状態です。
一方、sessionid は一般的にランダムな文字列で、バックエンドで ID の有効性を検証する必要があります。万が一サーバーが再起動してメモリ内のセッションが消えた場合はどうなりますか?万が一 Redis サーバーがダウンした場合はどうなりますか?
プラン A:私はあなたに身分証明書を渡しますが、ただの身分証明書番号が書かれた紙切れです。あなたが毎回手続きを行うとき、私はバックエンドであなたの ID が有効かどうかを確認します。
プラン B:私はあなたに暗号化された身分証明書を渡します。以後、あなたがこのカードを提示するだけで、私はあなたが確実に自分の人間であることを知っています。
これが違いです。
2 つの認証方法は、HTTP プロトコルの状態保持の問題を解決するためのものです。HTTP プロトコルは無状態プロトコルだからです。
Rest サービス#
rest は以下の条件を満たすべきです:
クライアント / サーバーモデルを使用する(略して C/S 構造、これはネットワークアーキテクチャで、クライアント (Client) とサーバー (Server) を区別します。各クライアントソフトウェアのインスタンスは、サーバーまたはアプリケーションサーバーにリクエストを送信できます。)
例えば、フロントエンドとバックエンドが分離されており、ページとサービスが同じサーバー上で動作していない場合。
階層化されたシステム
例えば、親システムの下に複数の子モジュールがあり、各モジュールは独立したサービスです。
無状態
サーバーはクライアントに関する状態を保存しません。つまり、バックエンドサービスを利用するには、Token を持参する必要があります。
キャッシュ可能
例えば、サーバーが Token を通じてログイン済みのユーザー情報をキャッシュし、クライアントのリクエストが Token を持参すると、バックエンドサービスは持参された Token を使用してキャッシュからユーザー情報を取得し、効率を向上させます。
統一されたインターフェース
例えば、プロジェクトのすべてのモジュールが統合され、オールインワンでパッケージ化され、複数のサービスが 1 つのポートに統合されます。
もしシステムが上記の 5 つの制約を満たしているなら、そのシステムは RESTful と呼ばれます(これはソフトウェアアーキテクチャスタイル、設計スタイルであり、標準ではなく、設計原則と制約を提供するものです。主にクライアントとサーバーが相互作用するソフトウェアに使用されます。このスタイルに基づいて設計されたソフトウェアは、よりシンプルで、より階層的で、キャッシュなどのメカニズムを実装しやすくなります。)
Eureka#
- Eureka の概要
Eureka は Netflix が開発した_サービス発見フレームワーク_で、REST ベースのサービスです。主に AWS ドメインで実行されている中間層サービスを特定し、負荷分散と中間層サービスのフェイルオーバーを実現するために使用されます。SpringCloud は、SpringCloud のサービス発見機能を実現するために、子プロジェクト spring-cloud-netflix に統合しています。
1. Eureka コンポーネント
Eureka は、Eureka Server と Eureka Client の 2 つのコンポーネントで構成されています。
1.1 Eureka Server
Eureka Server はサービス登録サービスを提供します。各ノードが起動すると、Eureka Server に登録され、Eureka Server のサービス登録表にはすべての利用可能なサービスノードの情報が保存されます。サービスノードの情報は、インターフェースで直感的に見ることができます。
Eureka Server 自体もサービスであり、デフォルトでは自動的に Eureka 登録センターに登録されます。
単一の Eureka Server 登録センターを構築する場合は、Eureka Server の自動登録ロジックを無効にする必要があります。現在のサービスが現在のサービスを代表する登録センターに登録されるのは理にかなっていません。
Eureka Server は Register、Get、Renew などのインターフェースを通じてサービスの登録、発見、ハートビート検出などのサービスを提供します。
2.1 Eureka Client
Eureka Client は Java クライアントで、Eureka Server とのインタラクションを簡素化します。クライアントは、内蔵のラウンドロビン負荷アルゴリズムを使用する負荷分散器も備えています。アプリケーションが起動すると、Eureka Server にハートビートを送信します。デフォルトの周期は 30 秒で、Eureka Server が複数のハートビート周期内に特定のノードからのハートビートを受信しない場合、Eureka Server はサービス登録表からそのサービスノードを削除します(デフォルトは 90 秒)。
Eureka Client は、Application Service(サービスプロバイダー)と Application Client(サービスコンシューマー)の 2 つの役割に分かれます。
2.1.1 Application Service
サービス提供者で、Eureka Server に登録されているサービスです。
2.1.2 Application Client
サービス消費者で、Eureka Server を通じてサービスを発見し、消費します。
ここで、Application Service と Application Client は絶対的な定義ではありません。なぜなら、プロバイダーはサービスを提供しながら、他のプロバイダーが提供するサービスを消費することもできます。コンシューマーはサービスを消費しながら、外部サービスを提供することもできます。
SpringMVC Spring boot Spring Cloud#
Spring Boot は単なる設定ツール、統合ツール、補助ツールです。
SpringMVC はフレームワークで、プロジェクト内で実際に実行されるコードです。
Spring フレームワークは家族のようなもので、boot、security、jpa などの多くの派生製品があります。しかし、彼らの基盤は Spring の IOC と AOP です。IOC は依存性注入のコンテナを提供し、AOP は横断的なプログラミングを解決します。そして、この 2 つの基盤の上に他の派生製品の高度な機能が実現されています。
Spring MVC は、Web アプリケーションを開発するための軽度に結合された方法を提供します。これは Spring のモジュールであり、Web フレームワークです。Dispatcher Servlet、ModelAndView、View Resolver を通じて、Web アプリケーションの開発が非常に簡単になります。解決する問題領域は、ウェブアプリケーションまたはサービス開発 —URL ルーティング、セッション、テンプレートエンジン、静的 Web リソースなどです。
Spring Boot は自動設定を実現し、プロジェクト構築の複雑さを軽減します。これは、Spring フレームワークを使用する際に多くの設定が必要で面倒な問題を解決するためのもので、Spring の解決策を置き換えるものではなく、Spring フレームワークと密接に結合して Spring 開発者の体験を向上させるためのツールです。同時に、Jackson、JDBC、Mongo、Redis、Mail などの多くの一般的なサードパーティライブラリの設定を統合しており、Spring Boot アプリケーションではこれらのサードパーティライブラリがほぼゼロ設定で即座に使用できます。
Spring Boot は単なるホストであり、プロジェクト構築プロセスを簡素化するための補助です。もしホストが WEB プロジェクトであれば、Spring MVC を MVC フレームワークとして使用する場合、作業フローは上記の説明と完全に同じです。なぜなら、この部分の作業は Spring MVC が行うものであり、Spring Boot ではないからです。
利用者にとって、Spring Boot に切り替えると、プロジェクトの初期化方法が変わり、設定ファイルが変わり、さらに Tomcat のようなコンテナサーバーを別途インストールする必要がなくなります。Maven で jar パッケージをビルドして直接実行すれば、それがウェブサイトになりますが、最も重要なビジネスロジックの実装やビジネスプロセスの実装には何の変化もありません。
まとめ:Spring は最初に「ファクトリーパターン」(DI)と「プロキシパターン」(AOP)を利用してアプリケーションコンポーネントを疎結合にしました。皆さんはそれが非常に便利だと感じたので、このパターンに従って MVC フレームワーク(Spring で疎結合にしたコンポーネントのいくつか)を作成し、Web アプリケーションを開発しました(SpringMVC)。その後、開発のたびに多くのボイラープレートコードを書くことがわかり、作業フローを簡素化するために「怠け者統合パッケージ」(starter)を開発しました。これが Spring Boot です。
したがって、最も簡潔な言葉で要約すると:
Spring は「エンジン」です;
Spring MVC は Spring に基づく MVC フレームワークです;
Spring Boot は Spring4 に基づく条件付き登録のための迅速な開発統合パッケージです。
SpringCloud は現在の完全なマイクロサービスフレームワークであり、一連のフレームワークの秩序ある集合です。これは、現在各社が開発した比較的成熟し、実際のテストに耐えられるサービスフレームワークを組み合わせ、SpringBoot スタイルで再パッケージ化し、複雑な設定や実装原理を隠蔽し、最終的に開発者にとって理解しやすく、展開しやすく、メンテナンスしやすい分散システム開発ツールキットを提供します。これは、Spring Boot の開発の便利さを利用して、サービス発見登録、設定センター、メッセージバス、負荷分散、サーキットブレーカー、データ監視などの分散システム基盤の開発を巧妙に簡素化し、ワンクリックで起動および展開できるようにします。
Token とは何か
Spring 基礎知識の詳細
Eureka の紹介
Feign 設計原理
Spring Boot と Spring Cloud
HTTP はこんなに簡単
メッセージキューの紹介
動的プロキシの詳細分析
CAS#
CAS は Compare And Swap の略で、文字通り理解すると比較して更新することを意味します。簡単に言えば:特定のメモリから値 V を取得し、予想値 A と比較します。もしメモリ値 V と予想値 A の結果が等しいなら、新しい値 B をメモリに更新します。もし等しくなければ、成功するまで上記の操作を繰り返します。CAS は楽観的ロックの一種であり、synchronized は悲観的ロックです。
IO 多路復用#
余談ですが、I/O 多路復用メカニズムについて詳しく説明する必要があります。この言葉はあまりにも一般的で、一般の人には意味がわからないことが多いです。ブロガーは例え話をします:小曲は S 城で宅配便の店を開き、同じ都市内の迅速配送サービスを担当しています。資金の制約から、小曲は一部の配達員を雇いましたが、資金が足りなくなり、宅配便を送るために車を 1 台購入するだけの資金しかありませんでした。
経営方式一
顧客が宅配便を持参するたびに、小曲は 1 人の配達員を見張らせ、その配達員が車を運転して宅配便を届けます。徐々に小曲はこの経営方式に以下の問題があることに気づきました。数十人の配達員がほとんどの時間を車を奪い合うことに費やし、大部分の配達員が待機状態にあり、誰が車を奪ったかによって宅配便を届けることができるようになります。宅配便が増えるにつれて、配達員も増え、小曲は宅配便店がますます混雑し、新しい配達員を雇うことができなくなりました。配達員同士の調整に多くの時間がかかります。これらの欠点を総合的に考慮し、小曲は次の経営方式を提案しました。
経営方式二
小曲は 1 人の配達員だけを雇います。そして、顧客が持参した宅配便を、届け先に応じてマークし、順番に一か所に置きます。最後に、その配達員が順番に宅配便を取りに行き、1 つずつ持って行き、車を運転して宅配便を届け、届け終わったら戻って次の宅配便を取りに行きます。
比較
上記の 2 つの経営方式を比較すると、明らかに 2 番目の方が効率が高く、より良いと感じませんか?上記の比喩において:
各配達員 ——————> 各スレッド
各宅配便 ——————–> 各ソケット(I/O ストリーム)
宅配便の届け先 ————–> ソケットの異なる状態
顧客の宅配便リクエスト ————–> クライアントからのリクエスト
小曲の経営方式 ————–> サーバーで実行されるコード
1 台の車 ———————-> CPU のコア数
したがって、以下の結論が得られます。
- 経営方式一は従来の並行モデルであり、各 I/O ストリーム(宅配便)には新しいスレッド(配達員)が管理します。
- 経営方式二は I/O 多路復用です。単一のスレッド(1 人の配達員)が、各 I/O ストリームの状態(各宅配便の届け先)を追跡して、複数の I/O ストリームを管理します。