php session在高并发时可能存在的问题。
如果同一个客户端并发发送多个请求,而每个请求都使用了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锁定问题就不会出现。
实例讲解:
PHP默认的会话处理器是session.save_handler = files(即文件)。如果同一个客户端同时并发发送多个请求(如ajax在页面同时发送多个请求),且脚本执行时间较长,就会导致session文件阻塞,影响性能。因为对于每个请求,PHP执行session_start(),就会取得文件独占锁,只有在该请求处理结束后,才会释放独占锁。这样,同时多个请求就会引起阻塞。
session阻塞简单演示
创建2个php文件:session_a.php,session_b.php。
- <?php
- // session_a.php
- session_start();
- $_SESSION['a'] = date('H:i:s');
- // session_write_close();
- sleep(5);
- echo $_SESSION['a'];
- <?php
- // session_b.php
- session_start();
- $_SESSION['b'] = date('H:i:s');
- // session_write_close();
- sleep(5);
- echo $_SESSION['b'];
同时访问这2个脚本,你会发现,其中一个脚本比另一个延迟了5秒。而当我们将文件中的session_write_close()函数注释取消掉后,再来同时访问发现2个脚本可以同时执行了。
session锁定处理机制
顺便提一下,session_commit()是session_write_close()的别名,即也可以使用前者替代后者。
当session_start()调用时,session处理机制默认会打开或创建一个seesion文件,且会立即给这个文件上了一个锁定状态(locked)。当session_commit()调用时或脚本执行完成后该文件会被解锁(unlocked)。
锁定状态有个重要的影响:同时请求使用了session的PHP脚本,并非并列执行的,而是分离的。如果当用户发起了一个请求,同时发起另一个请求便会被阻塞,直至前一个请求完全完成。
Session锁定的好处
请不要勿以为这所谓的阻塞现象是PHP的BUG,当然不是,相反有些时候分离执行才是正确的做法。考虑一下购物车案例:
用户发起A请求,脚本读取用来显示购物车物品的session数据;
在A请求完成之前,用户便点击了“加入购物车”按钮,发送了个B请求;
B等待A请求完成,然后向session中新增数据;
如果没有对session进行锁定会发生什么?
B没有等待A完成,读取并写入session数据;
A请求完成并写入之前读取的session数据,覆盖了上述B写入的数据;
所以,我们在使用session时应当考虑当前实际环境。
php session在高并发时可能存在的问题。的更多相关文章
- 关于sphinx+PHP在高并发时响应性能低下的解决办法
经过多次压力测试,发现sphinx在高并发时出现负载突然提升,并且响应速度明显下降.经过多方面的排查,发现是由于PHP与sphinx自带的 searchd进行socket的连接之后,系统内存有大量的T ...
- [转]你如何面对—LNMP高并发时502
From : http://www.topthink.com/topic/5683.html 之前php-fpm配置: 单个php-fpm实例,使用socket方式,内存8G 静态方式,启动php-f ...
- j2ee高并发时使用全局变量需要注意的问题
原文:https://blog.csdn.net/jston_learn/article/details/21617311 开发中,全局变量的使用很频繁,但对于多线程的访问,使用全局变量需要注意的地方 ...
- 优秀开源项目之三:高性能、高并发、高扩展性和可读性的网络服务器架构State Threads
译文在后面. State Threads for Internet Applications Introduction State Threads is an application library ...
- 在CentOS上使用Nginx和Tomcat搭建高可用高并发网站
目录 目录 前言 创建CentOS虚拟机 安装Nginx 安装Tomcat 安装lvs和keepalived 反向代理 部署网站 搭建数据库 编写网站项目 解决session一致性 注意 参考资料 前 ...
- asp.net解决高并发的方案.[转]
最近几天一直在读代震军的博客,他是Discuz!NT的设计者,读了他的一系列关于Discuz!NT的架构设计文章,大呼过瘾,特别是Discuz!NT在解决高访问高并发时所设计的一系列方案,本人尤其感兴 ...
- [转]asp.net解决高并发的方案.
本文转自:http://www.cnblogs.com/qq75077027/archive/2012/11/27/2791703.html 最近几天一直在读代震军的博客,他是Discuz!NT的设计 ...
- 高并发应用中客户端等待、响应时间的推算,及RT/QPS概念辨析
高并发应用中客户端等待.响应时间的推算,及RT/QPS概念辨析 对于一个网站,已知服务端的服务线程数和处理单个请求所需的时间时,该如何算出高并发时用户从点击链接到收到响应的时间?注意这个时间并不等于服 ...
- asp.net解决高并发的方案.
asp.net解决高并发的方案. Posted on 2012-11-27 22:31 75077027 阅读(3964) 评论(1) 编辑 收藏 最近几天一直在读代震军的博客,他是 Discuz!N ...
随机推荐
- 开启无线WLAN方式
1.以管理员身份运行命令提示符 因为下面的步骤必须在管理员权限下运行,因此我们从开始菜单找到"命令提示符",或直接键入cmd快速搜索,右键单击它,选择"以管理员身份运行& ...
- 日志体系——loging
import loggingclass log: def __init__(self): # 文件的命名 self.logname=os.path.join(os.path.abspath(os.pa ...
- rabbitmq的发布确认和事务
摘要: 介绍confirm的工作机制.使用spring-amqp介绍事务以及发布确认的使用方式.因为事务以及发布确认是针对channel来讲,所以在一个连接中两个channel,一个channel可以 ...
- No module named bz2
yum install bzip* python2.6 import bz2 python2.7 import bz2 error 解决:sudo cp /usr/lib64/python2.6/li ...
- Go语言学习之数据类型以及类型转换(The way to go)
生命不止,继续go go go 介绍来go中的变量和常量,今天介绍一下go中的基本类型. 可以分为四大类,现在一点点道来. Boolean Types 布尔类型,不用过多介绍来吧,就是true和fal ...
- javascript日期格式处理
一. 服务端返回的日期和时间之间有T Asp.net MVC中 action返回前台的日期类型数据 是带有 T的,如: 2015-07-07T10:15:01. 这样的数据在Chrome浏览器,会自动 ...
- 数字组合问题:Combination,CombinationSum,CombinationSum2,CombinationSum3
Combination问题描述:给定n和k,找出1-n之间所有k个数的组合,例如:n=3,k=2,返回 [[1,2] [1,3] [2,3]] 算法分析:利用递归.递归边界就是curr.size( ...
- TiDB 在摩拜单车的深度实践及应用
一.业务场景 摩拜单车 2017 年开始将 TiDB 尝试应用到实际业务当中,根据业务的不断发展,TiDB 版本快速迭代,我们将 TiDB 在摩拜单车的使用场景逐渐分为了三个等级: P0 级核心业务: ...
- LeetCode第[34]题(Java):Search for a Range
题目:搜索目标范围 难度:Medium 题目内容: Given an array of integers nums sorted in ascending order, find the starti ...
- ubuntu16.04 添加中文ibus输入法
ubuntu版本 16.04 在terminal 输入命令 sudo apt-get install ibus-pinyin sudo apt-get ibus-setup 设置 选择拼音,添加选择 ...