ホームページ  >  記事  >  データベース  >  Redis がインターフェイスの冪等性を処理するための 2 つのソリューションについて簡単に説明します。

Redis がインターフェイスの冪等性を処理するための 2 つのソリューションについて簡単に説明します。

WBOY
WBOY転載
2022-08-18 17:57:112453ブラウズ

推奨される学習: Redis ビデオ チュートリアル

前書き: インターフェイス冪等性問題、開発者向け言語とは関係のない公的問題。ユーザーリクエストによっては、リクエストが繰り返し送信される場合があります。クエリ操作であれば問題ありませんが、書き込み操作を伴うものもあります。繰り返し送信されると、トランザクションなどの重大な結果につながる可能性があります。インターフェースが繰り返し要求される場合、繰り返し注文が行われる可能性があります。インターフェイスの冪等性とは、同じ操作に対してユーザーが開始した 1 つまたは複数のリクエストの結果に一貫性があり、複数のクリックによって引き起こされる副作用がないことを意味します。

1. インターフェース冪等性

1.1. インターフェース冪等性とは

HTTP/1.1 では冪等性が定義されています。これは、リソースに対する 1 つまたは複数のリクエストがリソース自体に対して同じ結果をもたらす必要があること、つまり、最初のリクエストはリソースに副作用をもたらしますが、後続のリクエストはリソースに副作用を及ぼさないことを説明します。ここでの副作用によって結果が損なわれたり、予測不可能な結果が生じることはありません。つまり、複数の実行はリソース自体に 1 回の実行と同じ影響を与えます。

このタイプの問題は、インターフェイス

  • insert 操作でよく発生します。この場合、複数のリクエストにより重複データが生成される可能性があります。
  • update 操作では、データを更新するだけの場合 (例: update user set status=1 where id=1)、問題はありません。計算がまだ残っている場合 (例: update user set status=status 1 where id=1)、この場合複数のリクエストによりデータ エラーが発生する可能性があります。

1.2. 冪等性を達成する必要がある理由

インターフェイスが呼び出されたとき、情報は通常どおり返され、繰り返し送信されることはありません。 、次のような状況が発生した場合に問題が発生する可能性があります。

  • フロントエンドでフォームの繰り返し送信: 一部のフォームに入力すると、ユーザーは送信を完了しますが、応答に失敗することがよくあります。ネットワークの変動により、ユーザーに送信が間に合わず、ユーザーは送信が失敗したと思い込んで送信ボタンをクリックし続けるため、フォームリクエストの送信が繰り返されることになります。
  • ユーザーが悪意を持って詐欺を行う: たとえば、ユーザー投票機能を実装する場合、ユーザーが繰り返し投票を送信すると、インターフェースはユーザーが繰り返し送信した投票情報を受信することになります。投票結果に影響を与える。事実と著しく矛盾する。
  • インターフェイスのタイムアウトと繰り返しの送信: 多くの HTTP クライアント ツールでは、特にサードパーティがインターフェイスを呼び出す場合に、デフォルトでタイムアウト再試行メカニズムが有効になっています。ネットワークの変動やタイムアウトなどによるリクエストの失敗を防ぐために、再試行メカニズムが追加されるため、リクエストが複数回送信されることになります。
  • メッセージの繰り返し消費: MQ メッセージ ミドルウェアを使用する場合、メッセージ ミドルウェアでエラーが発生し、消費情報が時間内に送信されない場合、繰り返し消費が発生します。

この記事では、サーバー側でこのインターフェイスの冪等性状況をエレガントかつ均一に処理する方法について説明します。ユーザーが繰り返しクリックすることやその他のクライアント側の操作を禁止する方法については、この説明の範囲外です。

1.3. 冪等性の導入後のシステムへの影響

冪等性はクライアント ロジックの処理を簡素化し、繰り返し送信などの操作を配置できますが、冪等性は増加します。

  • 並列実行機能を逐次実行に変更すると、実行効率が低下します。
  • 冪等性を制御するビジネス ロジックが追加され、ビジネス機能が複雑になります;

したがって、実際のビジネス シナリオに応じて、冪等性を使用する際に導入するかどうかを検討する必要があります。具体的な分析により、次のことがわかります。特別なビジネス要件を除いて、一般にインターフェイスの冪等性を導入する必要はありません。

2.冪等性の設計方法

インポテンスとは、リクエストの一意性を意味します。べき等を設計するためにどのソリューションを選択する場合でも、このリクエストを一意としてマークするには、グローバルに一意の ID が必要です。

  • 一意のインデックスを使用して冪等性を制御する場合、一意のインデックスは一意になります。
  • データベースの主キーを使用して冪等性を制御する場合、主キーは一意になります
  • 悲観的ロックを使用する場合、基になるタグは引き続きグローバルに一意の ID

2.1. グローバルに一意の ID

グローバルに一意の ID、方法私たちがそれを生成しますか?考えてみてください。データベースの主キー ID はどのように生成されるのでしょうか?

はい、UUID を使用できますが、UUID の欠点は明らかです。文字列が多くのスペースを占有し、生成される ID はランダムすぎ、可読性が低く、インクリメント。

Snowflake アルゴリズム (Snowflake) を使用して一意の ID を生成することもできます。

Snowflake アルゴリズムは、分散されたグローバルに固有の ID を生成するアルゴリズムであり、生成された ID は Snowflake ID と呼ばれます。このアルゴリズムは Twitter によって作成され、ツイート ID に使用されます。

Snowflake ID は 64 ビットです。

  • ビット 1: Java の long の最上位ビットは、正と負を表す符号ビットです。正の数は 0、負の数は 1 です。一般に、生成される ID は正の値です。数値なので、デフォルトは 0 です。
  • 次の 41 ビットはタイムスタンプで、選択したエポックからのミリ秒数を表します。
  • 次の 10 桁は、競合を防ぐためのコンピューター ID を表します。
  • 残りの 12 ビットは、各マシンで生成される ID のシリアル番号を表します。これにより、同じミリ秒内に複数の Snowflake ID を作成できます。

もちろん、グローバルに一意な ID の場合は、Baidu の Uidgenerator または Meituan の Leaf を使用することもできます。

2.2. べき等設計の基本プロセス

べき等処理のプロセスは、最終的には、受信したリクエストをフィルタリングすることです。リクエストには グローバルに一意な ID タグ ha が必要です。では、リクエストが以前に受信されたかどうかを確認するにはどうすればよいでしょうか。リクエストを保存します。リクエストを受信したら、まず保存レコードを確認します。レコードが存在する場合は、最後の結果が返されます。レコードが存在しない場合は、リクエストが処理されます。

一般的なべき等処理は次のようになります:

3. インターフェース冪等に対する一般的な解決策

3.1 、一意のリクエスト番号をダウンストリームに渡す

リクエストに一意のリクエスト番号がある限り、一意のリクエスト番号が存在する限り、Redis を使用してこの重複排除を実行できるということを考えるかもしれません。 Redis では、処理されると重複とみなされます。

プログラムの説明:

いわゆる一意のリクエスト シーケンス番号とは、実際には、サーバーに対してリクエストが行われるたびに、一意で反復しないシーケンス番号が付加されることを意味します。短い期間です。シーケンス番号は、順序付けられたシーケンス番号にすることができます。ID は、通常、ダウンストリームによって生成される順序番号にすることもできます。アップストリーム サーバー インターフェイスを呼び出すときに、認証に使用されるシリアル番号と ID が追加されます。 。

上流サーバーはリクエスト情報を受信すると、シリアル番号と下流認証 ID を組み合わせて Redis を操作するためのキーを形成し、Redis にクエリを実行して、対応するキーと値のペアがあるかどうかを確認します。 Key. 結果によると:

  • それが存在する場合、シーケンス番号に対するダウンストリーム リクエストが処理されたことを意味します。このとき、繰り返されたリクエストのエラー メッセージに直接応答できます。 。
  • 存在しない場合は、キーを Redis のキーとして使用し、ダウンストリームのキー情報を保存された値 (ダウンストリーム プロバイダーによって渡されたビジネス ロジック情報など) として使用し、キーと値のペアを保存します。 Redis で、対応するビジネス ロジックを通常どおり実行します。

該当する操作:

  • 挿入操作
  • 更新操作
  • 削除操作

使用制限:

  • サードパーティに一意のシリアル番号を渡す必要があります;
  • データ検証にサードパーティ コンポーネント Redis を使用する必要があります;

メイン プロセス:

主な手順:

  • ダウンストリーム サービスは、分散 ID をシリアル番号として生成し、アップストリーム インターフェイスを呼び出すリクエストを実行します。 「固有のシリアル番号」と要求された「認証資格情報 ID」を使用します。
  • 上流サービスはセキュリティ検証を実行し、下流に渡されたパラメータに「シリアル番号」と「資格情報 ID」があるかどうかを検出します。
  • 上流サービスは、Redis 内に対応する「シリアル番号」と「認証 ID」で構成される Key が存在するかどうかを検出し、存在する場合は、繰り返し実行例外メッセージをスローし、対応する下流サービスに応答します。エラーメッセージ。存在しない場合は、「シリアル番号」と「認証ID」の組み合わせをKey、下流のキー情報をValueとしてRedisに格納し、以降のビジネスロジックを実行します。正常に実行されます。

上記の手順では、Redis にデータを挿入するときに、有効期限を設定する必要があります。これにより、この時間範囲内でインターフェイスが繰り返し呼び出された場合でも、判断と識別を行うことができます。有効期限が設定されていない場合、無制限の量のデータが Redis に保存され、Redis が適切に動作しなくなる可能性があります。

3.2. 重複防止トークン

プログラムの説明:

クライアントの連続クリックまたは呼び出し側のタイムアウト再試行に応答して、たとえば、オーダーはトークンメカニズムを使用して、繰り返しの送信を防ぐことができます。簡単に言うと、呼び出し元は、インターフェイスを呼び出すときに、最初にバックエンドからグローバル ID (トークン) を要求します。要求するとき、このグローバル ID を一緒に運びます (トークンをヘッダーに置くのが最善です)。バックエンドは、このTokenをKeyとして、ユーザー情報をValueとしてRedisに送信し、Key値の内容検証を行い、Keyが存在し、Valueが一致する場合には削除コマンドが実行され、以降のビジネスロジックが正常に実行されます。対応するキーがない場合、または値が一致しない場合は、冪等な操作を保証するためにエラー メッセージが繰り返し返されます。

使用制限:

  • グローバルに一意のトークン文字列を生成する必要があります;
  • データ検証にサードパーティ コンポーネント Redis を使用する必要があります;

メインプロセス:

  • サーバーはトークンを取得するためのインターフェースを提供します。トークンはシリアル番号、分散 ID、または UUID 文字列です。

  • クライアントはトークンを取得するためにインターフェイスを呼び出しますが、このときサーバーはトークン文字列を生成します。

  • 次に、トークンを Redis キーとして使用して、文字列を Redis データベースに保存します (有効期限に注意してください)。

  • トークンをクライアントに返します。クライアントがトークンを取得したら、フォームの非表示フィールドに保存する必要があります。

  • クライアントがフォームを実行して送信すると、トークンがヘッダーに保存され、ビジネス リクエストの実行時にヘッダーが一緒に送信されます。

  • リクエストを受信した後、サーバーはヘッダーからトークンを取得し、そのトークンを使用してキーが Redis に存在するかどうかを確認します。

  • サーバーは、Redis にキーが存在するかどうかを判断し、存在する場合はキーを削除し、ビジネス ロジックを通常どおり実行します。存在しない場合は、例外がスローされ、繰り返し送信されるとエラー メッセージが返されます。

同時実行条件では、Redis データの検索と削除を実行するときにアトミック性を保証する必要があります。そうしないと、同時実行下で冪等性が保証されない可能性があることに注意してください。その実装では、分散ロックを使用したり、Lua 式を使用してクエリをログアウトしたり、操作を削除したりできます。

推奨される学習: Redis ビデオ チュートリアル

以上がRedis がインターフェイスの冪等性を処理するための 2 つのソリューションについて簡単に説明します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjb51.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。