要件:
まず、あるシステム検証の例を示します: (A チャネル システム、業務 B システム、外部メーカー C システム)
(1) 業務システム B はチャネル システム A を呼び出し、着信した携帯電話、ID カード、名前が一致しているかどうかを確認します。
(2) 次に、チャネル A システムが外部メーカー C システムを呼び出します。
(3)A チャネル システムは結果を B 業務システムに返します。
これら 3 つのプロセスのうち、(2) 外部メーカーを呼び出すプロセスには課金が必要です。
B ビジネス システムの同時実行性が非常に高い場合、同一の 3 要素検証が 100 件ありますが、これらは同じ 3 要素であるため、A チャネルはメーカーに 1 回電話するだけで結果を知ることができます。あるリクエストがまだ応答していない間に他のリクエストが外部システムを呼び出すのを防ぐために、この時点でロックが必要です。
分散ロックの特徴
●● アトミック性: 同時に、1 つのマシンの 1 つのスレッドだけがロックを取得できます;
#● 再入可能: 同じオブジェクト (スレッド、クラスなど) は、死なずにロックを繰り返し再帰的に呼び出すことができます。## ブロック可能: ロックが取得される前に、ロックはブロックされ、ロックが取得されるまで待機することしかできません。
##● 高可用性: プログラムの障害やマシンの損傷が発生した場合でも、ロックはブロックされます。## 高パフォーマンス: ロックの取得と解放の操作は低コストです。
実現するには: ロック、ロック削減、ロック タイムアウト
実装方法は次のとおりです: データベース mc redis システム ファイルzookeeper
現在、100 がチャネル システムになっています。最初のリクエストを最初にロックする必要があり、次に外部ベンダー システムにリクエストします。応答を待った後、別のキーを挿入してロックを削除します。
他のリクエストは、最初に下位のロックを取得します。ロックがすでに存在する場合は、順番に待機します。ロックが存在しない場合は、結果を直接クエリします。
最初のリクエストが失敗し、結果が所定の位置に挿入されない場合は、引き続きロックの取得と外部システムへのクエリを実行します。
ロックの取得:
$redis->set('lock:手机号&身份证&姓名', 1, ['nx', 'ex'=>10]);
ロックの解除:
キーを直接削除してください
ロックのタイムアウト:
ロック キーhas timed out Time
新しいバージョンの redis set コマンドは分散ロックを実装でき、存在しない場合に限り set と timeout を同時に実装できます。
4b7f0a7304beadcaaaaa0874072c18ecconnect("127.0.0.1",6379); //高并发时防止重复请求 //渠道系统传递过来的key $lockKey='lock:18806767777&37781991111629092&taoshihan'; $resultKey='res:18806767777&37781991111629092&taoshihan'; //如果已经查询过值,可以直接返回 $info=$redis->get($resultKey); if($info){ exit($info); } //如果没有值的,获取锁 $lock=$redis->set($lockKey, 1, ['nx', 'ex'=>10]); if($lock){ //请求外部系统获取结果,比如响应结果比较慢 sleep(8); $info='{"name":"taoshihan"}'; $ret=$redis->set($resultKey,$info); if($ret){ //删除锁 $redis->del($lockKey); exit($info); } } echo "请稍后重试!";推奨学習:
PHP チュートリアル
以上がPHP が Redis 分散ロックに基づく高い同時実行性と反復リクエストを防ぐ方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。