推奨される学習: Redis ビデオ チュートリアル
前書き: インターフェイス冪等性
問題、開発者向け言語とは関係のない公的問題。ユーザーリクエストによっては、リクエストが繰り返し送信される場合があります。クエリ操作であれば問題ありませんが、書き込み操作を伴うものもあります。繰り返し送信されると、トランザクションなどの重大な結果につながる可能性があります。インターフェースが繰り返し要求される場合、繰り返し注文が行われる可能性があります。インターフェイスの冪等性とは、同じ操作に対してユーザーが開始した 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
)、この場合複数のリクエストによりデータ エラーが発生する可能性があります。 インターフェイスが呼び出されたとき、情報は通常どおり返され、繰り返し送信されることはありません。 、次のような状況が発生した場合に問題が発生する可能性があります。
この記事では、サーバー側でこのインターフェイスの冪等性状況をエレガントかつ均一に処理する方法について説明します。ユーザーが繰り返しクリックすることやその他のクライアント側の操作を禁止する方法については、この説明の範囲外です。
冪等性はクライアント ロジックの処理を簡素化し、繰り返し送信などの操作を配置できますが、冪等性は増加します。
したがって、実際のビジネス シナリオに応じて、冪等性を使用する際に導入するかどうかを検討する必要があります。具体的な分析により、次のことがわかります。特別なビジネス要件を除いて、一般にインターフェイスの冪等性を導入する必要はありません。
インポテンスとは、リクエストの一意性を意味します。べき等を設計するためにどのソリューションを選択する場合でも、このリクエストを一意としてマークするには、グローバルに一意の ID が必要です。
グローバルに一意の ID、方法私たちがそれを生成しますか?考えてみてください。データベースの主キー ID はどのように生成されるのでしょうか?
はい、UUID
を使用できますが、UUID の欠点は明らかです。文字列が多くのスペースを占有し、生成される ID はランダムすぎ、可読性が低く、インクリメント。
Snowflake アルゴリズム (Snowflake)
を使用して一意の ID を生成することもできます。
Snowflake アルゴリズムは、分散されたグローバルに固有の ID を生成するアルゴリズムであり、生成された ID は Snowflake ID
と呼ばれます。このアルゴリズムは Twitter によって作成され、ツイート ID に使用されます。
Snowflake ID は 64 ビットです。
もちろん、グローバルに一意な ID の場合は、Baidu の Uidgenerator
または Meituan の Leaf
を使用することもできます。
べき等処理のプロセスは、最終的には、受信したリクエストをフィルタリングすることです。リクエストには グローバルに一意な ID タグ
ha が必要です。では、リクエストが以前に受信されたかどうかを確認するにはどうすればよいでしょうか。リクエストを保存します。リクエストを受信したら、まず保存レコードを確認します。レコードが存在する場合は、最後の結果が返されます。レコードが存在しない場合は、リクエストが処理されます。
一般的なべき等処理は次のようになります:
リクエストに一意のリクエスト番号がある限り、一意のリクエスト番号が存在する限り、Redis を使用してこの重複排除を実行できるということを考えるかもしれません。 Redis では、処理されると重複とみなされます。
プログラムの説明:
いわゆる一意のリクエスト シーケンス番号とは、実際には、サーバーに対してリクエストが行われるたびに、一意で反復しないシーケンス番号が付加されることを意味します。短い期間です。シーケンス番号は、順序付けられたシーケンス番号にすることができます。ID は、通常、ダウンストリームによって生成される順序番号にすることもできます。アップストリーム サーバー インターフェイスを呼び出すときに、認証に使用されるシリアル番号と ID が追加されます。 。
上流サーバーはリクエスト情報を受信すると、シリアル番号と下流認証 ID を組み合わせて Redis を操作するためのキーを形成し、Redis にクエリを実行して、対応するキーと値のペアがあるかどうかを確認します。 Key. 結果によると:
該当する操作:
使用制限:
メイン プロセス:
主な手順:
上記の手順では、Redis にデータを挿入するときに、有効期限を設定する必要があります。これにより、この時間範囲内でインターフェイスが繰り返し呼び出された場合でも、判断と識別を行うことができます。有効期限が設定されていない場合、無制限の量のデータが Redis に保存され、Redis が適切に動作しなくなる可能性があります。
プログラムの説明:
クライアントの連続クリックまたは呼び出し側のタイムアウト再試行に応答して、たとえば、オーダーはトークンメカニズムを使用して、繰り返しの送信を防ぐことができます。簡単に言うと、呼び出し元は、インターフェイスを呼び出すときに、最初にバックエンドからグローバル ID (トークン) を要求します。要求するとき、このグローバル ID を一緒に運びます (トークンをヘッダーに置くのが最善です)。バックエンドは、このTokenをKeyとして、ユーザー情報をValueとしてRedisに送信し、Key値の内容検証を行い、Keyが存在し、Valueが一致する場合には削除コマンドが実行され、以降のビジネスロジックが正常に実行されます。対応するキーがない場合、または値が一致しない場合は、冪等な操作を保証するためにエラー メッセージが繰り返し返されます。
使用制限:
メインプロセス:
サーバーはトークンを取得するためのインターフェースを提供します。トークンはシリアル番号、分散 ID、または UUID 文字列です。
クライアントはトークンを取得するためにインターフェイスを呼び出しますが、このときサーバーはトークン文字列を生成します。
次に、トークンを Redis キーとして使用して、文字列を Redis データベースに保存します (有効期限に注意してください)。
トークンをクライアントに返します。クライアントがトークンを取得したら、フォームの非表示フィールドに保存する必要があります。
クライアントがフォームを実行して送信すると、トークンがヘッダーに保存され、ビジネス リクエストの実行時にヘッダーが一緒に送信されます。
リクエストを受信した後、サーバーはヘッダーからトークンを取得し、そのトークンを使用してキーが Redis に存在するかどうかを確認します。
サーバーは、Redis にキーが存在するかどうかを判断し、存在する場合はキーを削除し、ビジネス ロジックを通常どおり実行します。存在しない場合は、例外がスローされ、繰り返し送信されるとエラー メッセージが返されます。
同時実行条件では、Redis データの検索と削除を実行するときにアトミック性を保証する必要があります。そうしないと、同時実行下で冪等性が保証されない可能性があることに注意してください。その実装では、分散ロックを使用したり、Lua 式を使用してクエリをログアウトしたり、操作を削除したりできます。
推奨される学習: Redis ビデオ チュートリアル
以上がRedis がインターフェイスの冪等性を処理するための 2 つのソリューションについて簡単に説明します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。