• 首页自动生成静态化html


     由于平台老是出现间歇性502。排查发现,php死进程过多耗费大量系统资源。

    除了优化代码之外,静态化可以减少php进程。缓解一下服务器压力。

    把首页生成html后,出现问题频率下降。所以需要做首页静态化,并自动按规定时间更新。

    1,在模板引入生成脚本,k的值随便定,只是为了防止没参数时,直接访问脚本static.php的触发。

     <script type="text/javascript" src="/static.php?k=XXXXXX"></script>
    

    2,脚本

    $k = trim($_GET['k']);
    if (!is_string($k) || strlen($k) < 32 || $k !== md5("XXXXX")) {
        return false;
    }
    //首页1分钟更新一次
    if (!file_exists("index.html") || time() - filemtime("index.html") > 60) {
        create_html();
    }
    
    //生成静态
    function create_html()
    {
    //开启output buffer 缓冲区,如果php已经开启,则不需要。
    // php.ini 中,output_buffering = 4096
    //    if (!ini_get('output_buffering')) {
            ob_start();
    //    }
    //调用模板组织成页面
        require "index.php";
    //获取缓冲区中的页面,并清除缓冲区
        $content = ob_get_clean();
            //将页面保存成为静态文件
        $s=file_put_contents("index.html", $content);
        if($s){
            echo $s;
        }else{
            echo 0;
        }
    }
    

     如果写入失败,考虑写入权限问题   chmod -R 777 XXX 

    出现问题:

    1,因为首页上面有登陆后,出现欢迎你,XXX的,东西,会出现,登陆用户如果更新缓存会把这些字符给抓下来,写入index.html

    屏蔽ob缓存,采用file_get_content或者curl,或者用了ob之后phpquery来处理文档也可以。

    2,超时问题

    如果本身由于各种问题,index.php访问过慢。有可能会写入失败或者不完整。做了3套方案。

    并且做了超时,和内容长度判断

    以下是修改后代码

    <?php
    /**
     * 静态化
     * User: lee 
     * Date: 2015/12/7
     * Time: 17:40
     */
    //自定义验证 $k = trim($_GET['k']); if (!is_string($k) || strlen($k) < 32 || $k !== md5("XXX")) { die('{"status":0,"info":"k is error"}'); } //首页1分钟更新一次 if (!file_exists("index.html") || time() - filemtime("index.html") > 60) {
      //刷新缓存
    ob_flush(); flush(); $obj = new StaticPage(); $obj->create_html(); } else { die('{"status":0,"info":"file exists"}'); } //静态类 class StaticPage { //生成静态 public function create_html() { $ob = json_decode($this->P(1), 1);//优先ob缓存 if ($ob['status'] == 0) { $file_get_content = json_decode($this->P(2), 1); //失败,采用http if ($file_get_content['status'] == 0) {
              //采用curl
    $curl = json_decode($this->P(3), 1); if ($curl['status'] == 0) { die('{"status":0,"info":"server error"}'); } else { echo json_encode($curl); } } else { echo json_encode($file_get_content); } } else { echo json_encode($ob); } } /** * http get请求 * @param string $url * @param mixed $param * @param int $time * @return mixed */ private function httpGet($url, $param = null, $time = 1000) { $ch = curl_init(); // set URL and other appropriate options curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//不验证证书 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);//不验证host curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 500);//设置时间 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); curl_setopt($ch, CURLOPT_NOSIGNAL, 1); //注意,毫秒超时一定要设置这个 curl_setopt($ch, CURLOPT_TIMEOUT_MS, $time); //curl_setopt($ch, CURLOPT_TIMEOUT, $time);//设置时间 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//不直接输出 // grab URL and pass it to the browser $result = curl_exec($ch); if (curl_errno($ch)) { //echo 'Errno2'.curl_error($ch);//捕抓异常 return false; } // close cURL resource, and free up system resources curl_close($ch); return $result; } /** * 获取页面 */ private function P($type = 1) { $url = "http://" . $_SERVER['HTTP_HOST'] . "/index.php"; //ob缓存 if ($type == 1) { //由于首页有登陆状态,使用ob缓存会记录登陆者名字进入缓存文件。 // if (!ini_get('output_buffering')) { ob_start(); // } require "index.php"; $content = ob_get_clean(); //把登陆欢迎信息替换,不能缓存用户名,phpQuery是一个dom处理的类,详细可以看我另外的文章 http://www.cnblogs.com/findgor/p/4955321.html require "../App/Common/phpQuery.php"; phpQuery::newDocument($content); $str = <<<STR <a href="http://{$_SERVER['HTTP_HOST']}/XXXXX" rel="nofollow">立即登录</a> <a href="http://{$_SERVER['HTTP_HOST']}/XXXXX" style="background:#A3A3A3;font-size:16px;font-weight:bold;color:#fff;" rel="nofollow">免费注册</a> <a href="http://{$_SERVER['HTTP_HOST']}/XXXX/" style="color:#cccccc">帮助中心</a>| <a href="http://{$_SERVER['HTTP_HOST']}/XXXX/" style="color:#cccccc" rel="nofollow">关于我们</a>| <a href="XXXXX" style="color:#cccccc" rel="nofollow">VIP中心</a> STR; pq("#head #head_nav .right")->html($str); $dom = pq()->html(); return $this->W($dom, 1); } //file_get_contents if ($type == 2) { $opts = array( 'http' => array( 'method' => "GET", 'timeout' => 1, //设置超时 ) ); $context = stream_context_create($opts); $content = @file_get_contents($url, false, $context); return $this->W($content, 2); } //curl if ($type == 3) { $content = $this->httpGet($url); return $this->W($content, 3); } } /** * 写入 * @param null $content 数据 * @param int $type 类型 * @return json */ private function W($content = null, $type = 1) { //大于1W字符写入 if (strlen($content) > 10000) { $index = @file_put_contents("index.html", $content); if ($index) { return json_encode(array("status" => 1, "data" => $index, "info" => "write ok!", "type" => $type)); } else { return json_encode(array("status" => 0, "data" => $index, "info" => "write false!", "type" => $type)); } } else { return json_encode(array("data" => 0, "info" => "<10000", "type" => $type)); } } } ?>

    ===================

    考虑到其他页面的静态化。有2种想法

    1,同样在这个static.php脚本里面触发,增加批量检测更新

    2,后台按钮手动触发。

    这两种方式那种最好。待我测试之后再行更新此文章。

    补充:

    过了2年了,再看这篇文章,技术显然不太符合现在的开发规范。目前采用的是redis缓存,所有首页数据都存到redis里面,定时cron更新

    目标都是减少数据库开销,而redis是基于内存的,比磁盘读写速度要快,比较符合当前的开发概念。

    参考:http://blog.csdn.net/jetxt/article/details/44563145#0-tsina-1-16123-397232819ff9a47a7b7e80a40613cfe1

  • 相关阅读:
    acm常见错误-持续更新
    学习之旅
    快速幂
    写个管理自我的小工具
    Tree构建
    Sql server学习
    asp.net webAPI学习
    AngularJS数据双向绑定
    虚拟机学习
    wps学习
  • 原文地址:https://www.cnblogs.com/findgor/p/5028662.html
Copyright © 2020-2023  润新知