由于平台老是出现间歇性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

最新文章

  1. javaweb之框架标签(day1 框架标签的使用)
  2. SAP 增强-出口选找方法-全部
  3. 异步task处理
  4. 简谈HTML5与APP技术应用
  5. HDOJ 1042 N! -- 大数运算
  6. android 复杂的json数据解析
  7. c3p0写连接池 Demo
  8. 通达OA 新旧两种数据库连接方式
  9. S2_SQL_第五章
  10. Spring框架基础解析
  11. Gym 101981K - Kangaroo Puzzle - [玄学][2018-2019 ACM-ICPC Asia Nanjing Regional Contest Problem K]
  12. nginx的https代理http配置
  13. arcgis二次开发遇到System.Runtime.InteropServices.COMException (0x80040228) :异常来自HRESULT:0x80040228
  14. MySQL 8.0.11 报错[ERROR] [MY-011087] Different lower_case_table_names settings for server (&#39;1&#39;)
  15. stm32 启动文件 C和汇编交叉嵌入
  16. 风控3—iv算法详细解释
  17. Linux下字符集的安装
  18. Java Session 会话技术
  19. 内核升极2.6.18 升级到 2.6.32 装systemtap 原创
  20. ASP.NET常用的指令

热门文章

  1. setAlpha与View Layer关系
  2. swift跳转到Appstore
  3. Comparable和Comparator的区别
  4. 笔记汇总.md
  5. Program.cs
  6. stm32 cubemx hal 工程中 微秒延迟 delay_us
  7. Reportng报告替代testng
  8. 21-React的学习
  9. redis3.0.6安装(linux和windows)
  10. 通过sharedpreferences实现记住密码功能