避免SESSION锁阻塞请求

Share on:

这篇文章是对我上一篇文章的深入研究php-fpm-slow.log慢日志频繁出现session_start(),也是对阻挡的效果的体会。

问题的开始是fpm-slow-log出现很多session_start(),单纯的认为是硬盘读写问题是错误的,只怪当时太年轻。

翻到了这两篇文章
http://konrness.com/php5/how-to-prevent-blocking-php-requests/
http://www.leaseweblabs.com/2014/08/session-locking-non-blocking-read-sessions-php/

介绍了什么是session lock,怎么工作,为什么需要,如何避免阻塞。

决定自己动手体验下。

准备两段测试代码。

test.html

<img src="https://ifunbox.top/demo/session_start_test/test.php?v=1">
<img src="https://ifunbox.top/demo/session_start_test/test.php?v=2">
<img src="https://ifunbox.top/demo/session_start_test/test.php?v=3">
<img src="https://ifunbox.top/demo/session_start_test/test.php?v=4">
<img src="https://ifunbox.top/demo/session_start_test/test.php?v=5">
<img src="https://ifunbox.top/demo/session_start_test/test.php?v=6">
<img src="https://ifunbox.top/demo/session_start_test/test.php?v=7">
<img src="https://ifunbox.top/demo/session_start_test/test.php?v=8">
<img src="https://ifunbox.top/demo/session_start_test/test.php?v=9">
<img src="https://ifunbox.top/demo/session_start_test/test.php?v=10">

test.php

<?php
	session_start();
	$_SESSION['latestRequestTime'] = time();
	session_write_close();
	sleep(2);
	$twitterId = $_SESSION['latestRequestTime'];
	echo json_encode($twitterId);
?>

1.我们先在火狐上访问test.html,里面有10个php请求到test.php。
效果如下图,因为火狐默认6个并发连接,所以前6个请求是木有阻隔的,但是由于session lock的原因,每个请求时间都比上一个晚2S,必须等上一个请求释放session lock。第7个请求就被阻隔了2S,因为要等第一个请求被释放嘛,O(∩_∩)O~

2.然后去除test.php中session_write_close();前面的注释
再用火狐上访问test.html,效果如下图。发现前面6个请求,不需要等待上一个请求结束,已经并行了,是因为session_write_close()释放了session lock的原因。

3.我们下载火狐附加组件Tweak network修改并行连接数为10,

然后注释掉之前去除注释的代码访问test.html。效果如下。阻隔条消失,所以网络上有一些浏览器优化配置其实就是调大的并发连接数来加速网页js,php,图片的加载。

到这里对session lock阻塞就大致明白了。

回过头解决问题了,我回想了自己项目的应用场景好多ajax加载界面甚至有ajax定时刷新,难道这个是罪魁祸首!

于是乎就把涉及到的ajax接口不需要用session的就不session_start(),不需要写入session的就在session_start()后直接加入session_write_close(),需要写入session的,写入session后加入session_write_close()。

优化了下全部请求下来总时长快了1S,我tm惊呆了~

闽ICP备12003472号-7