本文目录导读:

我来详细介绍PHP如何使用Varnish作为缓存层。
Varnish基础配置
安装Varnish
# Ubuntu/Debian sudo apt-get install varnish # CentOS/RHEL sudo yum install varnish
配置Varnish端口
# /etc/varnish/default.vcl
vcl 4.0;
backend default {
.host = "127.0.0.1";
.port = "8080"; # PHP-FPM/Nginx端口
}
# 监听80端口
# /etc/varnish/varnish.params
VARNISH_LISTEN_PORT=80
VARNISH_LISTEN_ADDRESS=0.0.0.0
VCL配置文件示例
# /etc/varnish/default.vcl
vcl 4.0;
backend default {
.host = "127.0.0.1";
.port = "8080";
}
# ACL允许清除缓存
acl purge {
"localhost";
"127.0.0.1";
}
sub vcl_recv {
# 只缓存GET和HEAD请求
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
# 不缓存登录页面
if (req.url ~ "^/login" || req.url ~ "^/admin") {
return (pass);
}
# 设置模拟客户端IP
if (req.restarts == 0) {
if (req.http.X-Forwarded-For) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
# 缓存GET请求
if (req.method == "GET") {
return (hash);
}
return (pass);
}
sub vcl_backend_response {
# 缓存后端响应
if (beresp.status == 200) {
# 根据URL设置不同的缓存时间
if (bereq.url ~ "^/products") {
set beresp.ttl = 1h;
} elseif (bereq.url ~ "^/blog") {
set beresp.ttl = 15m;
} else {
set beresp.ttl = 5m;
}
# 不缓存包含Set-Cookie的响应
if (beresp.http.Set-Cookie) {
set beresp.ttl = 0s;
return (deliver);
}
}
return (deliver);
}
sub vcl_deliver {
# 添加缓存状态头
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
# 不显示缓存命中数给客户
# unset resp.http.X-Varnish;
}
sub vcl_purge {
return (synth(200, "Purged"));
}
PHP代码配合Varnish
设置缓存头
<?php
// 设置缓存头,让Varnish知道缓存策略
function set_cache_headers($ttl = 300) {
// 不缓存页面
header("Cache-Control: no-cache, no-store, must-revalidate");
// 如果用户已登录,不缓存
if (isset($_SESSION['user_id'])) {
header("Cache-Control: no-cache, no-store");
header("Pragma: no-cache");
return false;
}
// 设置缓存头
header("Cache-Control: public, max-age=" . $ttl);
header("Pragma: cache");
return true;
}
// 使用示例
if (set_cache_headers(600)) {
// 页面内容将被缓存
echo generate_dynamic_content();
} else {
// 动态内容,不缓存
echo generate_personalized_content();
}
?>
缓存清除(PURGE请求)
<?php
class VarnishCacheManager {
private $varnishHosts = ['127.0.0.1'];
private $varnishPort = 80;
public function purgeCache($url) {
foreach ($this->varnishHosts as $host) {
$this->sendPurgeRequest($host, $url);
}
}
private function sendPurgeRequest($host, $url) {
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "http://{$host}:{$this->varnishPort}" . $url,
CURLOPT_CUSTOMREQUEST => "PURGE",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-Purge-Key: secret_key",
"Host: " . $_SERVER['HTTP_HOST']
]
]);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
return $httpCode == 200;
}
}
// 使用示例
$cacheManager = new VarnishCacheManager();
$cacheManager->purgeCache('/products');
?>
高级特性
使用BAN正则批量清理
sub vcl_recv {
if (req.method == "BAN") {
# 验证BAN密钥
if (req.http.Ban-Key != "your-secret-key") {
return (synth(403, "Forbidden"));
}
ban("req.url ~ " + req.http.Ban-Url);
return (synth(200, "Banned"));
}
}
// PHP批量清理
class VarnishBanner {
public function ban($pattern) {
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "http://127.0.0.1/",
CURLOPT_CUSTOMREQUEST => "BAN",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Ban-Key: your-secret-key",
"Ban-Url: " . $pattern
]
]);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
return $httpCode == 200;
}
}
// 清理所有商品页面缓存
$banner = new VarnishBanner();
$banner->ban("^/products/");
集成框架缓存
Laravel/Lumen
// 在中间件或控制器中
public function index(Request $request) {
// 设置缓存头
header('Cache-Control: public, max-age=300');
// 使用Varnish缓存
$cacheKey = 'products_page_' . $request->page;
return Cache::remember($cacheKey, 300, function () {
return Product::paginate(10);
});
}
// 缓存清理
public function update(Product $product) {
// 更新产品逻辑...
// 清除相关缓存
$this->purgeCache("/products/" . $product->id);
$this->purgeCache("/products");
}
Symfony框架
// 配置文件 config/packages/cache.yaml
framework:
cache:
app: cache.adapter.redis
// 控制器中使用
public function index(ProductRepository $products) {
$response = new JsonResponse($products->findAll());
$response->setPublic();
$response->setMaxAge(300);
return $response;
}
Varnish监控
# 查看缓存命中率 varnishstat # 实时监控 varnishlog # 查看缓存内容 varnishadm # 检查配置 varnishd -C -f /etc/varnish/default.vcl
最佳实践
- 精确控制缓存时间类型设置不同的TTL
- 处理动态内容:对登录用户、个性化内容不缓存
- 缓存策略:使用
Cache-Control头与Varnish配合 - 监控和统计:关注缓存命中率,优化缓存策略
- 备份默认后端:配置多个后端服务器提高可用性
- 安全考虑:使用密钥保护清理操作
- 测试:在开发环境充分测试缓存配置
常见问题解决
# 检查Varnish是否运行 systemctl status varnish # 查看日志 tail -f /var/log/varnish.log # 检查端口监听 netstat -tulpn | grep 80 netstat -tulpn | grep 8080 # 清除所有缓存 varnishadm "ban req.url ~ /"
通过合理使用Varnish,可以显著提升PHP应用的性能和响应速度,特别适合高流量的内容型网站。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播