页面加载”慢”问题

页面加载”慢”问题

我们访问一个网站的时候,有时会一连串打开多个页面,然后在一个一个浏览。这时我们的浏览器上
会多出来自同一域的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 5386strace -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));

再次访问http://test.dev/test.html

访问OK了

Comments are closed.