页面加载”慢”问题
我们访问一个网站的时候,有时会一连串打开多个页面,然后在一个一个浏览。这时我们的浏览器上
会多出来自同一域的a,b,c 3标签页面,而往往是a加载完然后b再加载完,顺序为a->b->c。
我们假如a需要执行5s,b和c都只需要1s。往往同时加载完3个页面会大于5s。
why?
先说答案
session锁
寻找过程比较曲折,最开始认为是浏览器6个socket限制问题。利用谷歌浏览器chrome://net-internals/#sockets查看了,连接并没超过6个。后来靠猜是session问题,下面主要是验证是不是session锁的问题
准备工作
1. 部署模拟线上环境(LNMP)
2. 配置host,test.dev
3. 设置php-fpm.ini,max_children,start_servers为2(主要是保证2个php-fpm进程),重启
验证
编写sleep.php脚本
<?php $s = 5; if(isset($_GET['s']) && $_GET['s']){ $s = $_GET['s']; } sleep($s); echo json_encode(array("data"=>$s));
编辑test.html,分别请求5s和10s脚本
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="http://cdn.bootcss.com/jquery/2.2.0/jquery.min.js"></script> </head> <body> <script type="text/javascript"> function test(s) { $.ajax({ url: "http://test.dev/?s="+s, type: "get", success: function(json){ console.log(json); }, }); } test(10); test(5); </script> </body> </html>
打开chrome调试NetWork,访问http://test.dev/test.html,可以看到两个脚本分别按指定时间返回
修改下sleep.php脚本,增加session_start();
<?php session_start(); $s = 5; if(isset($_GET['s']) && $_GET['s']){ $s = $_GET['s']; } sleep($s); echo json_encode(array("data"=>$s));
再次访问http://test.dev/test.html,前面的为10s返回,而后面的等待了15s
显然跟session有关,我们利用strace命令看看究竟发生了什么
先用ps aux|grep php-fpm 查看fpm的进程,分别是5386和5387
然后打开2个shell窗口,分别执行strace -p 5386和strace -p 5387监听2个脚本
再访问http://test.dev/test.html,我们可以看到10秒的进程拿到session文件的时候加了锁,导致5秒的进程拿不到session,一直在等待锁的释放
#### 解决办法
session_write_close()在你不需要写session的地方加上,释放session锁,让其他进程使用
修改下sleep.php脚本,增加session_write_close();
<?php session_start(); session_write_close(); $s = 5; if(isset($_GET['s']) && $_GET['s']){ $s = $_GET['s']; } sleep($s); echo json_encode(array("data"=>$s));
访问OK了