検索
ホームページバックエンド開発PHPチュートリアルPHPで実装されたmemcachedキュークラス

  1. /*
  2. * memcache キュークラス
  3. * 複数プロセスの同時書き込みと読み取りをサポート
  4. * 書き込み中の読み取り、AB 側ローテーション置換
  5. * @author guoyu
  6. * @create on 9:25 2014 -9-28
  7. * @qq テクノロジー産業交流グループ: 136112330
  8. *
  9. * @example:
  10. * $obj = new memcacheQueue('duilie')
  11. * $obj->add('1asdf'); $obj->getQueueLength();
  12. * $obj->read(11);
  13. */
  14. class memcacheQueue{
  15. public static $client;クライアント接続
  16. public $access; //キューを更新できるかどうか
  17. private $currentSide; //現在のローテーションのキューサイド: A/B
  18. private $lastSide; //前のローテーションのキューサイド: A/ B
  19. private $sideAHead; // サイド A
  20. の最初の値 private $sideATail; // サイド A
  21. の最初の値 private $sideBTail;サイド B の
  22. private $ currentHead; // チームの現在の先頭の値
  23. private $currentTail; // チームの現在の末尾の値
  24. private $; lastTail; // チームの最後のラウンドの最後の値
  25. private $expire // 有効期限、秒、つまり 30 日以内 0 は有効期限が切れないことを意味します
  26. private $sleepTime;ロック解除, マイクロ秒
  27. private $queueName; // キュー名、一意の値
  28. private $retryNum; // 再試行数 = 10 * 理論上の同時実行数
  29. const MAXNUM = 2000; // (片面) キューの最大数推奨される上限は 10K です
  30. const HEAD_KEY = '_lkkQueueHead_' // キューのヘッド
  31. const TAIL_KEY = '_lkkQueueTail_' // キューの末尾のキー
  32. const VALU_KEY = '_lkkQueueValu_' // キューの値のキー
  33. LOCK_KEY = ' _lkkQueueLock_'; // キューのロック キー
  34. const SIDE_KEY = '_lkkQueueSide_'; // ローテーション サイド キー
  35. /*
  36. * コンストラクター
  37. * @param [config] 配列 memcache サーバー パラメーター
  38. * @param [queueName] 文字列キュー名
  39. * @param [expire] 文字列の有効期限
  40. * @return NULL
  41. */
  42. public function __construct($queueName = '',$expire='',$config =''){
  43. if(empty($config)) {
  44. self::$client = memcache_pconnect('localhost',11211);
  45. }elseif(is_array($config )){//array('host'=>'127.0.0.1','port'=> '11211')
  46. self::$client = memcache_pconnect($config['host'],$config[' port']);
  47. }elseif(is_string($config)){//"127.0.0.1:11211"
  48. $tmp =explode(':',$config);
  49. $conf['host'] = isset( $tmp[0]) $tmp[0] : '127.0.0.1'; '] = isset($tmp[1]) ? $tmp[1] : '11211'; :$client = memcache_pconnect($conf['host'],$conf['port']);
  50. if(!self::$client) return false;
  51. ignore_user_abort(TRUE);//クライアント切断時 接続を開いて継続実行を許可
  52. set_time_limit(0);//スクリプト実行遅延の上限を解除
  53. $this->access = false;
  54. $this->sleepTime = 1000;
  55. $expire = (empty($expire) && $expire!=0) : (int)$expire; >expire = $expire;
  56. $this->queueName = $queueName;
  57. $side = memcache_add(self::$client, $queueName, ' A',false, $expire);
  58. $this->getHeadNTail($queueName);
  59. if(!isset($this ->sideAHead) || empty($this->sideAHead)) $this-> ;sideAHead = 0;
  60. if(!isset($this->sideATail) || empty($this->sideATail) ) $this->sideATail = 0;
  61. if(!isset($this-> SideBHead) || empty($this->sideBHead)) $this->sideBHead = 0;
  62. if(!isset( $this->sideBHead) || empty($this->sideBHead) ->sideBHead = 0;
  63. /*
  64. * 获取队列首尾值
  65. * @param [queueName] string 队列名
  66. * @return NULL
  67. */
  68. private function getHeadNTail($queueName){
  69. $this->sideAHead = (int)memcache_get( self::$client, $queueName.'A'.self::HEAD_KEY);
  70. $this->sideATail = (int)memcache_get(self::$client, $queueName.'A'. self::TAIL_KEY);
  71. $this->sideBHead = (int)memcache_get(self::$client, $queueName.'B'.self::HEAD_KEY);
  72. $this->sideBTail = (int)memcache_get(self::$client, $queueName.'B'.self::TAIL_KEY);
  73. }
  74. /*
  75. * 获取当前轮值の队列面
  76. * @return string 队列面名
  77. */
  78. public function getCurrentSide(){
  79. $currentSide = memcache_get(self::$client, $this->queueName .self::SIDE_KEY);
  80. if($currentSide == 'A'){
  81. $this->currentSide = 'A';
  82. $this->lastSide = 'B';
  83. $this->currentHead = $this->sideAHead;
  84. $this->currentTail = $this->sideATail;
  85. $this->lastHead = $this->sideBHead;
  86. $this->lastTail = $this->sideBTail;
  87. }else{
  88. $this->currentSide = 'B';
  89. $this->lastSide = 'A';
  90. $this->currentHead = $this->sideBHead;
  91. $this->currentTail = $this->sideBTail;
  92. $this->lastHead = $this->sideAHead;
  93. $this->lastTail = $this->sideATail;
  94. }
  95. return $this->currentSide;
  96. }
  97. /*
  98. * 队列加锁
  99. * @return boolean
  100. */
  101. private function getLock(){
  102. if($this->access === false){
  103. while(!memcache_add(self:: $client, $this->queueName .self::LOCK_KEY, 1, false, $this->expire) ){
  104. usleep($this->sleepTime);
  105. @$i++;
  106. if($i > $this->retryNum){//尝试等待ちN次
  107. return false;
  108. 休憩;
  109. }
  110. }
  111. return $this->access = true;
  112. }
  113. false を返します。
  114. }
  115. /*
  116. * 队列解锁
  117. * @return NULL
  118. */
  119. private function unLock(){
  120. memcache_delete(self::$client, $this->queueName .self::LOCK_KEY);
  121. $this->access = false;
  122. }
  123. /*
  124. * 追加データ
  125. * @param [data] 要存储的值
  126. * @return boolean
  127. */
  128. public function add($data){
  129. $result = false;
  130. if(!$this->getLock()){
  131. return $result;
  132. }
  133. $this->getHeadNTail($this->queueName);
  134. $this->getCurrentSide();
  135. if($this->isFull()){
  136. $this->unLock();
  137. false を返します。
  138. }
  139. if($this->currentTail $value_key = $this->queueName .$this->currentSide 。 self::VALU_KEY 。 $this->currentTail;
  140. if(memcache_add(self::$client, $value_key, $data, false, $this->expire)){
  141. $this->changeTail();
  142. $result = true;
  143. }
  144. }else{//当前队列已满,更换轮值面
  145. $this->unLock();
  146. $this->changeCurrentSide();
  147. return $this->add($data);
  148. }
  149. $this->unLock();
  150. $result を返す;
  151. }
  152. /*
  153. * 取出データデータ
  154. * @param [length] int データの長さ
  155. * @return array
  156. */
  157. public function get($length=0){
  158. if(!is_numeric($length)) false を返します。
  159. if(empty($length)) $length = self::MAXNUM * 2;//默认读取すべて
  160. if(!$this->getLock()) return false;
  161. if($this->isEmpty()){
  162. $this->unLock();
  163. false を返します。
  164. }
  165. $keyArray = $this->getKeyArray($length);
  166. $lastKey = $keyArray['lastKey'];
  167. $currentKey = $keyArray['currentKey'];
  168. $keys = $keyArray['keys'];
  169. $this->changeHead($this->lastSide,$lastKey);
  170. $this->changeHead($this->currentSide,$currentKey);
  171. $data = @memcache_get(self::$client, $keys);
  172. foreach($keys as $v){//取出之後删除
  173. @memcache_delete(self::$client, $v, 0);
  174. }
  175. $this->unLock();
  176. $data を返します。
  177. }
  178. /*
  179. * 读取数据
  180. * @param [length] int データの長さ
  181. * @return array
  182. */
  183. public function read($length=0){
  184. if(!is_numeric($length) ) false を返します。
  185. if(empty($length)) $length = self::MAXNUM * 2;//默认读取すべて
  186. $keyArray = $this->getKeyArray($length);
  187. $data = @memcache_get(self::$client, $keyArray['keys']);
  188. $data を返します。
  189. }
  190. /*
  191. * 获取队列の特定の段数のキー数组
  192. * @param [length] int 队列长度
  193. * @return array
  194. */
  195. private function getKeyArray($length){
  196. $result = array('キー'=>array()、'lastKey'=>array()、'currentKey'=>array());
  197. $this->getHeadNTail($this->queueName);
  198. $this->getCurrentSide();
  199. if(empty($length)) $result を返します。
  200. //先取上一面のキー
  201. $i = $result['lastKey'] = 0;
  202. for($i=0;$i $result['lastKey'] = $this->lastHead + $i;
  203. if($result['lastKey'] >= $this->lastTail) Break;
  204. $result['keys'][] = $this->queueName .$this->lastSide 。 self::VALU_KEY 。 $result['lastKey'];
  205. }
  206. //再取得当前のキー
  207. $j = $length - $i;
  208. $k = $result['currentKey'] = 0;
  209. for($k=0;$k $result['currentKey'] = $this->currentHead + $k;
  210. if($result['currentKey'] >= $this->currentTail) Break;
  211. $result['keys'][] = $this->queueName .$this->currentSide 。 self::VALU_KEY 。 $result['currentKey'];
  212. }
  213. $result を返します。
  214. }
  215. /*
  216. * 当前轮值面队列尾の值
  217. * @return NULL
  218. */
  219. private function changeTail(){
  220. $tail_key = $this->queueName .$this->currentSide 。自分::TAIL_KEY;
  221. memcache_add(self::$client, $tail_key, 0,false, $this->expire);//如果没有,则插入;有则false;
  222. //memcache_increment(self::$client, $tail_key, 1);//队列尾+1
  223. $v = memcache_get(self::$client, $tail_key) +1;
  224. memcache_set(self::$client, $tail_key,$v,false,$this->expire);
  225. }
  226. /*
  227. * 更新队列首の值
  228. * @param [side] string 要更新的面
  229. * @param [headValue] int 队列首の值
  230. * @return NULL
  231. */
  232. private function changeHead( $side,$headValue){
  233. if($headValue $head_key = $this->queueName .$side 。自分::HEAD_KEY;
  234. $tail_key = $this->queueName .$side 。自分::TAIL_KEY;
  235. $sideTail = memcache_get(self::$client, $tail_key);
  236. if($headValue memcache_set(self::$client, $head_key,$headValue+1,false,$this->expire);
  237. }elseif($headValue >= $sideTail){
  238. $this->resetSide($side);
  239. }
  240. }
  241. /*
  242. * 重置队列面、即将该队列面の队首、队尾值置は0
  243. * @param [side] string 要重置面
  244. * @return NULL
  245. */
  246. プライベート関数resetSide($side){
  247. $head_key = $this->queueName .$side .自分::HEAD_KEY;
  248. $tail_key = $this->queueName .$side 。自分自身::TAIL_KEY;
  249. memcache_set(self::$client, $head_key,0,false,$this->expire);
  250. memcache_set(self::$client, $tail_key,0,false,$this->expire);
  251. }
  252. /*
  253. * 改变当前轮值队列面
  254. * @return string
  255. */
  256. private function changeCurrentSide(){
  257. $currentSide = memcache_get(self::$client, $this->queueName . self::SIDE_KEY) ;
  258. if($currentSide == 'A'){
  259. memcache_set(self::$client, $this->queueName . self::SIDE_KEY,'B',false,$this->expire);
  260. $this->currentSide = 'B';
  261. }else{
  262. memcache_set(self::$client, $this->queueName . self::SIDE_KEY,'A',false,$this->expire);
  263. $this->currentSide = 'A';
  264. }
  265. return $this->currentSide;
  266. }
  267. /*
  268. * 检查当前队列否否已满
  269. * @return boolean
  270. */
  271. public function isFull(){
  272. $result = false;
  273. if($this->sideATail == self::MAXNUM && $this->sideBTail == self::MAXNUM){
  274. $result = true;
  275. }
  276. $result を返します。
  277. }
  278. /*
  279. * 检查当前队列否か空
  280. * @return boolean
  281. */
  282. public function isEmpty(){
  283. $result = true;
  284. if($this->sideATail > 0 || $this->sideBTail > 0){
  285. $result = false;
  286. }
  287. $result を返します。
  288. }
  289. /*
  290. * 取当前队列の長さ
  291. * この長さは理论長さです、特定の要素は期限切れによる損失、真实長さはこの長さ以下です
  292. * @return int
  293. */
  294. パブリック関数 getQueueLength( ){
  295. $this->getHeadNTail($this->queueName);
  296. $this->getCurrentSide();
  297. $sideALength = $this->sideATail - $this->sideAHead;
  298. $sideBLength = $this->sideBTail - $this->sideBHead;
  299. $result = $sideALength + $sideBLength;
  300. $result を返す;
  301. }
  302. /*
  303. * 清空当前队列データ、仅保持HEAD_KEY、TAIL_KEY、SIDE_KEY三个key
  304. * @return boolean
  305. */
  306. public function clear(){
  307. if(!$this->getLock() ) false を返します。
  308. for($i=0;$i<:maxnum> @memcache_delete(self::$client, $this->queueName.'A'. self::VALU_KEY .$i, 0 );
  309. @memcache_delete(self::$client, $this->queueName.'B'. self::VALU_KEY .$i, 0);
  310. }
  311. $this->unLock();
  312. $this->resetSide('A');
  313. $this->resetSide('B');
  314. true を返します。
  315. }
  316. /*
  317. * 清除すべてmemcache缓存数据
  318. * @return NULL
  319. */
  320. public function memFlush(){
  321. memcache_flush(self::$client);
  322. }
  323. }
复制代

php、memcached


声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
絶対的なセッションタイムアウトとアイドルセッションのタイムアウトの違いは何ですか?絶対的なセッションタイムアウトとアイドルセッションのタイムアウトの違いは何ですか?May 03, 2025 am 12:21 AM

絶対セッションのタイムアウトはセッションの作成時に開始され、アイドルセッションタイムアウトはユーザーの操作なしに開始されます。絶対セッションタイムアウトは、金融アプリケーションなど、セッションライフサイクルの厳格な制御が必要なシナリオに適しています。アイドルセッションタイムアウトは、ソーシャルメディアなど、ユーザーが長い間セッションをアクティブに保つことを望んでいるアプリケーションに適しています。

セッションがサーバーで機能していない場合、どのような措置を講じますか?セッションがサーバーで機能していない場合、どのような措置を講じますか?May 03, 2025 am 12:19 AM

サーバーセッションの障害は、手順に従って解決できます。1。セッションが正しく設定されていることを確認するために、サーバーの構成を確認します。 2.クライアントCookieを確認し、ブラウザがそれをサポートしていることを確認し、正しく送信します。 3. Redisなどのセッションストレージサービスを確認して、それらが正常に動作していることを確認します。 4.アプリケーションコードを確認して、正しいセッションロジックを確認します。これらの手順を通じて、会話の問題を効果的に診断および修復し、ユーザーエクスペリエンスを改善することができます。

session_start()関数の重要性は何ですか?session_start()関数の重要性は何ですか?May 03, 2025 am 12:18 AM

session_start()iscrucialinphpformangingusersions.1)itInitiateSanewsessionifnoneExists、2)resumesanexistingsession、および3)SetSessionCookieforcontinuityAcrossRequests、ApplicationslicationSliviseSlikeUserauthicationAnticatent。

セッションクッキーにHTTPonlyフラグを設定することの重要性は何ですか?セッションクッキーにHTTPonlyフラグを設定することの重要性は何ですか?May 03, 2025 am 12:10 AM

HTTPonlyフラグを設定することは、XSS攻撃を効果的に防止し、ユーザーセッション情報を保護することができるため、セッションCookieにとって重要です。具体的には、1)HTTPONLYフラグは、JavaScriptがCookieにアクセスするのを防ぎます。2)Flagは、PHPとFlaskのSetCookiesとMake_Responseを介して設定できます。

PHPセッションはWeb開発でどのような問題を解決しますか?PHPセッションはWeb開発でどのような問題を解決しますか?May 03, 2025 am 12:02 AM

phpsessionssolvetheprobrof of maintainsea crossmultiplehttprequestsbyStoringdataontaonsociatingitiTauniquesessionid.1)それらは、通常はヨーロッパの側面、および一般的には、測定されている

どのデータをPHPセッションに保存できますか?どのデータをPHPセッションに保存できますか?May 02, 2025 am 12:17 AM

phpssionscanStorestrings、numbers、arrays、andobjects.1.strings:textdatalikeusernames.2.numbers:integersorfloatsforcounters.3.arrays:listslikeshoppingcarts.4.objects:complextructuresthataresialized。

どのようにPHPセッションを開始しますか?どのようにPHPセッションを開始しますか?May 02, 2025 am 12:16 AM

tostartaphpsession、outsession_start()atthescript'sbeginning.1)placeitbe foreanyouttosetthesscookie.2)usesionsionsionsionserdatalikelogintatussorshoppingcarts.3)再生セッションインドストップレベントフィックスアタック

セッションの再生とは何ですか?また、セキュリティをどのように改善しますか?セッションの再生とは何ですか?また、セキュリティをどのように改善しますか?May 02, 2025 am 12:15 AM

セッション再生とは、新しいセッションIDを生成し、セッション固定攻撃の場合にユーザーが機密操作を実行するときに古いIDを無効にすることを指します。実装の手順には次のものが含まれます。1。感度操作を検出、2。新しいセッションIDを生成する、3。古いセッションIDを破壊し、4。ユーザー側のセッション情報を更新します。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター