(1) 仮想マシンの構成の問題
リモート接続をテストして Redis 接続が確立されているかどうかを確認するとき成功すると、コンソールに次のエラーが報告される場合があります。
以下に示すように:
#コンソールに赤いテキストが表示されるたびに頭が痛くなります。 。 。
コンソールの表示は、接続タイムアウトが失敗の原因であることを意味していると考えられます。
接続失敗の理由は次の 3 つです。
Linux のファイアウォールが閉じられていないため、失敗が発生します。
redis を開く必要があります。
redis.conf のbind 127.0.01 をコメントアウトしてから、保護モードを変更する必要があります。
今後上記の問題が発生した場合は、ご自身で調べてください。
(2) Redis 接続成功時の高同時実行時のタイムアウトをシミュレートします
図に示すように:
MySQL で jdbc を使用すると接続タイムアウトの問題が発生する場合があるため、druid、c3p0 などのデータベース接続プールを使用して問題を解決します。同様に、redis でデータベース接続プールを使用することもできます。
redis サービスへの各接続によって発生する消費量を保存し、接続されたインスタンスを再利用します。
パラメータを使用して接続動作を管理する
メモ帳のコードに直接移動します。
リンク プール パラメーター:
MaxTotal: pool.getResource() を通じてプールに割り当てることができる jedis インスタンスの数を制御します。 ; 値が -1 の場合、制限がないことを意味します。プールに MaxTotal jedis インスタンスが割り当てられている場合、この時点でのプールのステータスは枯渇しています。
maxIdle: プール内のアイドル状態の jedis インスタンスの最大数を制御します;
MaxWaitMillis: jedis インスタンスを借用するとき、待機する最大ミリ秒数。待機時間を超過すると、JedisConnectionException が直接スローされます。
testOnBorrow: jedis インスタンスを取得するときに接続の可用性を確認する (ping()) かどうか。 if true の場合、取得された jedis インスタンスはすべて利用可能です;
高同時実行シナリオでは、複数のスレッドが発生します。在庫を同時に更新すると、マイナスの在庫状況が発生します。
写真を見て想像してください:
上の図:
//增加乐观锁 jedis.watch(qtkey); //3.判断库存 String qtkeystr = jedis.get(qtkey); if(qtkeystr==null || "".equals(qtkeystr.trim())) { System.out.println("未初始化库存"); jedis.close(); return false ; } int qt = Integer.parseInt(qtkeystr); if(qt<=0) { System.err.println("已经秒光"); jedis.close(); return false; } //增加事务 Transaction multi = jedis.multi(); //4.减少库存 //jedis.decr(qtkey); multi.decr(qtkey); //5.加人 //jedis.sadd(usrkey, uid); multi.sadd(usrkey, uid); //执行事务 List<Object> list = multi.exec(); //判断事务提交是否失败 if(list==null || list.size()==0) { System.out.println("秒杀失败"); jedis.close(); return false; } System.err.println("秒杀成功"); jedis.close();##スキームの原理:
(1) ユーザーが購入する際には、監視を通じて在庫を監視しますが、監視後に在庫が変化した場合、例外がキャッチされ、在庫を 1 つ減らす操作は諦められます。
(2) 在庫に変化が監視されておらず、数量が 1 より大きい場合、在庫は 1 つ減らされ、タスクが実行されます。
欠点
商品の在庫が正しいことを確認することが非常に重要です, しかし、単に WATCH のようなメカニズムを使用するとサーバーに過度の負荷がかかります
また、setnx には分散ロックの高度な機能がいくつかないため、依然として手動でビルドに渡します。
ロックの機能これは、ランダムに生成された 128 ビット UUID をビット キーの値に設定して、他のプロセスによってロックが取得されるのを防ぐことです。
条件を満たしている(uuid値を判断する) delete, rs.delete(lockname)でredis内で削除するだけです
また、他のユーザーが同じロックを保持している場合、uuidが異なるため、他の人のロックは解除されません
従来のロックでは、ロックを保持した後にプロセスが突然クラッシュしてロックが解除できなくなり、他のプロセスがロックを保持できなくなり、ロックが解除されなくなるなどの問題もありました。この問題を解決するには、ロックを取得するときにロック タイムアウト機能を追加できます。
以上がRedis のフラッシュセールシナリオにおけるタイムアウトと売られすぎの問題を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。