因为这个缘故,CDN的 x-Cache总是MISS TCP_MISS,导致要回源。
查了半个小时,终于找到原因了。
来自session.c:
Authors: Sascha Schumann <sascha@schumann.cx> Andrei Zmievski <andrei@php.net> // ... CACHE_LIMITER_FUNC(private) { ADD_HEADER("Expires: Thu, 19 Nov 1981 08:52:00 GMT"); CACHE_LIMITER(private_no_expire)(TSRMLS_C); }
见:http://php.net/manual/en/function.session-cache-limiter.php
在session_start() 之前添加session_cache_limiter(’public’)以启用缓存。
如果你用的是框架,我建议放在入口index.php里,以ThinkPHP为例的话是这样:
<?php /**追加部分 **/ header("Content-type:text/html;charset=utf-8"); header("Pragma: public"); header("Expires: ".strtotime("+1 days")." GMT"); session_cache_limiter("public"); /**追加部分 **/ header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); error_reporting(E_ALL & ~E_NOTICE); define('THINK_PATH', '../ThinkPHP/'); define('APP_NAME', 'Home'); define('APP_PATH', '../Application/Home/'); define('__HOME__',__DIR__); //define('MODE_NAME', 'rest'); // 采用rest模式运行 define('APP_DEBUG', true);//开发环境开启调试模式 define('RUNTIME_ALLINONE', false); require THINK_PATH.'ThinkPHP.php';
ThinkPHP还要修改配置config.php 增加HTTP_CACHE_CONTROL=public(见ThinkPHP/Lib/Core/View.class.php Line 92 render()方法)。
说个题外话,Pragma: no-cache可以应用到http 1.0 和http 1.1,而Cache-Control: no-cache只能应用于http 1.1.<html>默认是1.0好像,但是CDN才不管你http协议是什么,用2个参数做全等判断的。如果要CDN产生MEM HIT,你可以:
删除header里的Cache-Control和Pragma,或只用一种,取决于你网页头部的<html>协议用的是几
Pragma和Cache-Control的值应该保持一致,否则网页本身可能出问题(表单方面,尤其是用了令牌的表单)