网站首页php

高并发下session_start超时导致的访问失败问题

发布时间:2015-11-10 22:53:48编辑:阅读(7341)

        在开发微信平台功能时,微信菜单设置为链接时,如:
    https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appid.'&redirect_uri=http://xxx.com/xxx&response_type=code&scope=snsapi_base&state=1234#wechat_redirect

    链接被附加code后,跳转回redirect_uri。此时页面需要做微信远程code验证,获取openid,从而自动登陆。

    如下代码所示:

    $code  =$_GET['code'];
    while(true){
        //获取openid
        $url_op='https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$appid.'&secret='.$appsecret.'&code='.$code
                .'&grant_type=authorization_code';//将code参数整合到此链接中
        $ope=json_decode(curlGet($url_op),true);
        if( $ope['errcode']>0 || empty($ope['openid']) ){    
            continue;    
        }else{
            $openid=$ope['openid'];
            break;
        }
    }
    function curlGet($url){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $temp = curl_exec($ch);
        curl_close($ch);
        return $temp;
    }


        当访问量小时, 似乎正常。然而,当访问量上升时,便出现了nginx服务器的502报错,curlGet取不到值,结果使程序进入死循环。

    开始以为是服务器的问题,提高了php-fpm的进程数和linux内核打开文件数量,却发现问题依旧。

    于是将openid存于session,不在频繁去获取,似乎可以缓解这种症状。


    if( empty($_SESSION['openid']) ){
        //获取openid
        $url_op='https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$appid.'&secret='.$appsecret.'&code='.$code
               .'&grant_type=authorization_code';//将code参数整合到此链接中
        $ope=json_decode(curlGet($url_op),true);
        if( $ope['errcode']>0 || empty($ope['openid']) ){
            echo '<script>';
            echo 'window.location.replace("https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appid
                .'&redirect_uri=http://xxx.com/xxx&response_type=code&scope=snsapi_base&state=1234#wechat_redirect")';
            echo '</script>'; 
            exit;
        }
        $openid=$ope['openid'];
        $_SESSION['openid']=$openid;
    }else{
        $openid=$_SESSION['openid'];
    }

    ----------------------------------问题终结线------------------------------------------

    后期查询nginx慢日志时,发现大量session_start()记录,继续追踪原因。

    网站使用了Yar远程调用框架,后来将接口服务器端并入了thinkPHP的控制器中, 远程调用时会自动启动session。

    这样, 如果一个页面未执行完毕,session会被锁死, 后面的接口调用一直处于阻塞状态。结果就是网站好慢,页面打不开了。


    最后的解决方案:在接口的入口处关闭session.

    session_write_close();


评论