国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > PHP > 正文

淺析PHP中Session可能會引起并發問題

2024-05-04 23:38:01
字體:
來源:轉載
供稿:網友

關于PHP session并發問題估計各大程序員都不會想到這個問題,因為一般情況我們不會使用session來做并發操作了,但有時也有可能用到,今天我們就來簡單談談這個略微偏門的問題

在進行Web應用程序開發的時候,人們經常會用Session存儲數據。但可能有人不知道,在PHP中,Session使用不當可能會引起并發問題。印度醫療行業軟件解決方案提供商Plus91 Technologies高級工程師Kishan Gor在個人博客上對這個問題進行了闡釋。

如果同一個客戶端并發發送多個請求,而每個請求都使用了Session,那么PHP Session鎖的存在會導致服務器串行響應這些請求,而不是并行。這是因為在默認情況下,PHP使用文件存儲Session數據。對于每一個新的Session,PHP會創建一個文件,并持續向其中寫入數據。所以,每次調用session_start()方法,就會打開Session文件,并取得文件的獨占鎖。這樣,如果服務器腳本正在處理一個請求,而客戶端又發送了一個同樣需要使用Session的請求,那么后一個請求會阻塞,直至前一個請求處理完成釋放了文件上的獨占鎖。不過,這只限于來自同一個客戶端的多個請求,也就是說,來自一個客戶端的請求并不會阻塞另一個客戶端的請求。

如果腳本很短,這通常沒有問題。但如果腳本運行時間比較長,那就可能會產生問題。在現代Web應用程序開發中,有一個非常常見的情況,就是使用AJAX技術在同一個頁面內發送多個請求獲取數據。如果這些請求都需要使用Session,那么第一個請求到達服務器后會取得Session鎖,其它請求就必須等待,所有請求將串行處理,即使它們彼此之間并沒有依賴關系。這將大大增加頁面的響應時間。

有一個方法可以避免這個問題,就是在使用完Session以后立即調用session_write_close()方法關閉Session。這樣Session鎖就會釋放,即使當前腳本還在等在處理。需要注意的是,調用該方法后,當前腳本就不能進一步操作Session了。

需要特別指出的是,本文所陳述的問題和觀點只適用于使用session_start()方法的PHP默認Session管理模式。比如,有用戶就指出,如果將應用程序托管在AWS EC2上,并正確配置DynamoDB,Session鎖定問題就不會出現。

附上一份實例代碼:

Session.php

 

 
  1. <?php 
  2.  
  3. final class SessionController extends YafController_Abstract 
  4. public function setUserFileAction() 
  5. session_start(); 
  6. $_SESSION['user_name'] = 'xudianyang'
  7. $_SESSION['user_id'] = '123'
  8.  
  9. sleep(3); 
  10. echo json_encode($_SESSION); 
  11. return false; 
  12.  
  13. public function setLoginFileAction() 
  14. session_start(); 
  15. $_SESSION['last_time'] = time(); 
  16.  
  17. echo json_encode($_SESSION); 
  18. return false; 
  19.  
  20. public function indexFileAction() 
  21. // Auto Rend View 
  22.  
  23. public function getSessionFileAction() 
  24. session_start(); 
  25. var_dump($_SESSION); 
  26.  
  27. return false; 
  28.  
  29. public function setUserRedisAction() 
  30. $session = CoreFactory::session(); 
  31. $session->set('user_name''xudianyang'); 
  32. $session->set('user_id''123'); 
  33.  
  34. sleep(3); 
  35. echo json_encode($_SESSION); 
  36. return false; 
  37.  
  38. public function setLoginRedisAction() 
  39. $session = CoreFactory::session(); 
  40. $session->set('last_time', time()); 
  41.  
  42. echo json_encode($_SESSION); 
  43. return false; 
  44.  
  45. public function indexRedisAction() 
  46. // Auto Rend View 
  47.  
  48. public function getSessionRedisAction() 
  49. $session = CoreFactory::session(); 
  50. var_dump($_SESSION); 
  51.  
  52. return false; 
  53.  
  54. indexfile.phtml 
  55.  
  56. <!DOCTYPE html> 
  57. <html> 
  58. <head> 
  59. <title>測試session并發鎖問題</title> 
  60. <meta charset="utf-8"
  61. <script type="text/javascript" src="/assets/js/jquery-1.10.2.min.js"></script> 
  62. <script type="text/javascript"
  63. $.ajax({ 
  64. url: "/session/setUserFile"
  65. type: "get"
  66. dataType: "json"
  67. success: function(response){ 
  68. console.info(response.last_time); 
  69. }); 
  70. setTimeout(function(){ 
  71. $.ajax({ 
  72. url: "/session/setLoginFile"
  73. type: "get"
  74. dataType: "json"
  75. success: function(response){ 
  76. console.info(response.last_time); 
  77. }); 
  78. }, 300); 
  79. </script> 
  80. </head> 
  81. <body> 
  82. 同時發起2兩個ajax請求 
  83. </body> 
  84. </html> 
  85.  
  86. indexredis.phtml 
  87.  
  88. <!DOCTYPE html> 
  89. <html> 
  90. <head> 
  91. <title>測試session并發鎖問題</title> 
  92. <meta charset="utf-8"
  93. <script type="text/javascript" src="/assets/js/jquery-1.10.2.min.js"></script> 
  94. <script type="text/javascript"
  95. $.ajax({ 
  96. url: "/session/setUserRedis"
  97. type: "get"
  98. dataType: "json"
  99. success: function(response){ 
  100. console.info(response.last_time); 
  101. }); 
  102. setTimeout(function(){ 
  103. $.ajax({ 
  104. url: "/session/setLoginRedis"
  105. type: "get"
  106. dataType: "json"
  107. success: function(response){ 
  108. console.info(response.last_time); 
  109. }); 
  110. }, 300); 
  111. </script> 
  112. </head> 
  113. <body> 
  114. 同時發起2兩個ajax請求 
  115. </body> 
  116. </html> 

以上所述就是本文的全部內容了,希望大家能夠喜歡。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 海门市| 潞西市| 红原县| 三都| 汤原县| 辽宁省| 中山市| 五家渠市| 虎林市| 遂昌县| 莒南县| 五常市| 南涧| 宁明县| 孟州市| 玛沁县| 神农架林区| 轮台县| 远安县| 图片| 岢岚县| 商城县| 靖西县| 西乌珠穆沁旗| 宁城县| 临西县| 伊宁县| 吉隆县| 瓦房店市| 从江县| 始兴县| 定远县| 师宗县| 昭觉县| 醴陵市| 江孜县| 石泉县| 伊通| 山阳县| 广宁县| 东兰县|