0

0

Web提速:避免php session拖慢运行速度

php中文网

php中文网

发布时间:2016-06-23 13:58:31

|

1471人浏览过

|

来源于php中文网

原创

Web提速:避免php session拖慢运行速度

 

一、WHAT--并发访问,阻塞执行
1.1 不使用session

文件index.php:

Skybox AI
Skybox AI

一键将涂鸦转为360°无缝环境贴图的AI神器

下载

立即学习PHP免费学习笔记(深入)”;

<script type="text/javascript" src="http://code.jquery.com/jquery-2.0.3.min.js"></script><script type="text/javascript">$(document).ready(function(){$.ajax({url:"/ajax.php"});$.ajax({url:"/ajax2.php"});$.ajax({url:"/ajax3.php"});});</script>


立即学习PHP免费学习笔记(深入)”;

文件ajax.php、ajax2.php、ajax3.php的内容都是

立即学习PHP免费学习笔记(深入)”;

<?phpsleep(1);echo "php script run";


立即学习PHP免费学习笔记(深入)”;

  每个请求都sleep 1s,jq的ajax请求是异步的,也就是说这三个请求基本上是同时发出的,理论上最好的情况是浏览器等待1s,3个接口全部返回。

访问http://localhost,在chrome下查看测试结果:

立即学习PHP免费学习笔记(深入)”;

图 1.1 不使用session测试结果

  测试结果基本上跟理论一致

1.2 使用session

现在我们把文件ajax.php、ajax2.php、ajax3.php都改为

立即学习PHP免费学习笔记(深入)”;

立即学习PHP免费学习笔记(深入)”;

立即学习PHP免费学习笔记(深入)”;

<?phpsession_start();sleep(1);echo "php script run";


立即学习PHP免费学习笔记(深入)”;


这样做会什么有什么区别吗?我们直接看测试结果:

立即学习PHP免费学习笔记(深入)”;

图 1.2 使用session测试结果

不是每个请求只执行1s钟吗?为什么ajax2.php消耗了2s,ajax3.php消耗3s?

二、WHO -- Session锁

session锁的官方定义:

        Session data is usually stored after your script terminated without the need to call session_write_close(), but as session data is locked to prevent concurrent writes only one script may operate on a session at any time.

  大致的意思是: 从调用session_start()开始,直到显示调用session_write_close()或脚本结束,session的数据都会被锁起来,届时同一个SESSIONID用户的请求会被阻塞。

从图1.2的测试结果看到,ajax2.php与ajax3.php分别多执行了1s和2s,很明显session_start()操作造成了阻塞。

  当index.php同时访问ajax.php、ajax2.php、ajax3.php,ajax.php首先执行,此时ajax2.php与ajax3.php都在等在ajax.php释放session锁,都消耗1s。

  当ajax.php执行完成,释放了session锁,ajax2.php与ajax3.php再次竞争session锁,同理ajax3.php又等待了1s钟。所以我们得到的结果:

  ajax.php 消耗1s

  ajax2.php 消耗2s

  ajax3.php 消耗3s

三、WHEN -- 什么时候会触发Session锁

  在章节二中,session锁定义为session_start()开始即会触发session锁,所以对于现有大部分php框架(使用原生php session的情况下)存在session锁造成的用户请求阻塞的问题。试想,有2个请求,其中请求A需要3s钟才能返回结果,另外请求B仅需要10ms即能返回,前端同时请求这两个接口,假如后台先处理了A请求,那么B请求就要等待3s后再执行10ms才能返回结果。但是最优的情况是,同时发起请求,10ms后收到B请求返回,3s后收到A请求返回。

四、WHY -- Session内部执行机制

  默认情况下php session采用文件为服务端存储介质。在php session模块的源码中,有一个比较重要的结构体:

立即学习PHP免费学习笔记(深入)”;


图4.1 php session模块结构体 ps_module_struct

  该结构体里面的几个函数指针分别对应了session操作的open、close、read、write、destory、gc回收等功能。看到这6个函数,是否想起了php的SessionHandlerInterface接口(版本>=php5.4)?

立即学习PHP免费学习笔记(深入)”;

图4.2 php SessionHandlerInterface接口

  用这个接口配合session_set_save_handler可以重写session的这几个关键操作。于是我们可以使用以下代码来探探php session在一个请求的生命周期中的运行顺序:

立即学习PHP免费学习笔记(深入)”;

图4.3 session运行顺序测试代码

测试结果:

立即学习PHP免费学习笔记(深入)”;

  由测试结果可知一般的session执行顺序,在session_start()调用时,php回去调用open和read操作,脚本执行结束后(输出了php script run),再会调用write和close操作。

现在我们不妨做一个大胆的猜想,php 在 session的open或者read操作时,开启了session锁,并write或close后释放session锁。这样的猜想也符合我们在章节1的测试结果。

  为了验证我们的猜想,就需要去php的源码探个究竟了。在php源码文件/ ext / session / mod_files.c中可以看到默认session的6个重要操作的部分实现。在156行(点击打开链接),看到open操作有一个打开文件操作:flock(data->fd, LOCK_EX);该操作以互斥锁定的方式打开文件。在110行关掉文件close(data->fd);。

  看到这里,我们应该得到的结论是:

在默认情况下,所谓的php session锁其实就是文件锁

  所以,当我们使用session_set_save_handler来自定session操作,改用memcache或其他介质时,只要我们在SessionHandlerInterface的接口中没有锁的逻辑,那么session锁自然也不会存在。作者私下也做了这样的实验,实践证明也的确如此。

五、HOW -- 如何避免Session锁带来的阻塞现象

  首先,session锁不一定是坏事情,在一种情况下就非常好用,例如某接口对与同一个用户的请求默认同一时刻只能执行一次。这种时候,就可以用seesion_start()和session_write_close()把要阻塞的代码括起来。非常简单暴力实用。

  但是大部分时候我们还是要避免这种锁的存在,解决方案:

1、在用完session的时候就马上session_write_close()掉,释放session锁

2、采用没有锁的session操作,如章节4中所说的用session_set_save_handler来自定义一个没有锁的session操作。

3、再使用默认php session时,个人比较中意的一个方案:大部分情况下,我们对session的操作基本上都是读操作,写操作一般都比较少。这种时候,我们可以自己写一个session类。

构造函数:将session读入cache,关闭session锁

写操作:打开session锁,写入值,关闭session锁

读操作:直接读cache

部分代码如下:

立即学习PHP免费学习笔记(深入)”;

//将session读入全局变量$_SEESIONstatic private function init(){if(self::$not_init){ session_start(); session_write_close(); self::$not_init = false;}}


立即学习PHP免费学习笔记(深入)”;

立即学习PHP免费学习笔记(深入)”;

//读sessionstatic public function get($name){self::init();return $_SESSION[$name];}


立即学习PHP免费学习笔记(深入)”;

立即学习PHP免费学习笔记(深入)”;

//写sessionstatic public function set($name, $val){session_start();$_SESSION[$name] = $val;session_write_close();}


立即学习PHP免费学习笔记(深入)”;

注意:如果是写操作频繁的操作,就不适合使用该方法。

 

 


相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

616

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

194

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

91

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

20

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

54

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

29

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

15

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

598

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

56

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
CSS3 教程
CSS3 教程

共18课时 | 5.8万人学习

Git 教程
Git 教程

共21课时 | 3.7万人学习

Go 教程
Go 教程

共32课时 | 5.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号