好的,我来为您提供一个完整的示例代码。这个代码集成了之前讨论的优化方案,包括 Nginx 配置和 PHP 后端代码。
首先是 Nginx 配置文件 nginx.conf:
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Gzip 压缩
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# 缓存配置
location ~* \.(jpg|jpeg|png|gif)$ {
root /var/www/html/cache;
try_files $uri @fetch_remote;
expires 30d;
access_log off;
add_header Cache-Control "public";
}
location @fetch_remote {
rewrite ^(.*)$ /index.php?resource=$1 last;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP 配置
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
}
接下来是 PHP 代码 index.php:
<?php
// index.php
// 设置 Curl 选项
$curl_options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 60,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_FORBID_REUSE => false, // 保持连接不断开
);
// 获取请求的资源路径
$resource = isset($_GET['resource']) ? $_GET['resource'] : null;
if ($resource !== null) {
$cache_file = 'cache/' . md5($resource) . '.' . pathinfo($resource, PATHINFO_EXTENSION);
// 检查缓存文件是否存在
if (file_exists($cache_file)) {
// 返回缓存的图片资源
$content_type = pathinfo($cache_file, PATHINFO_EXTENSION);
header("Content-Type: image/$content_type");
readfile($cache_file);
exit;
} else {
// 从远程服务器获取资源并缓存
$ch = curl_init();
curl_setopt_array($ch, $curl_options);
curl_setopt($ch, CURLOPT_URL, 'http://remote_server' . $resource);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($response !== false && $http_code === 200) {
// 将资源缓存到本地
$dir = dirname($cache_file);
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
file_put_contents($cache_file, $response);
// 设置响应头并输出内容
$content_type = pathinfo($cache_file, PATHINFO_EXTENSION);
header("Content-Type: image/$content_type");
echo $response;
exit;
} else {
http_response_code($http_code);
echo 'Error fetching resource';
exit;
}
}
}
// 处理其他类型的请求
$request_uri = $_SERVER['REQUEST_URI'];
$ch = curl_init();
curl_setopt_array($ch, $curl_options);
curl_setopt($ch, CURLOPT_URL, 'http://remote_server' . $request_uri);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($response !== false && $http_code === 200) {
// 设置响应头并输出内容
foreach (curl_getinfo($ch) as $key => $value) {
if (is_string($key) && strpos($key, 'content_') === 0) {
header($key . ': ' . $value);
}
}
echo $response;
} else {
http_response_code($http_code);
echo 'Error fetching resource';
}
curl_close($ch);
这个例子包含了以下优化措施:
- Nginx 配置中启用了 Gzip 压缩,可以减小响应内容的大小。
- 图片资源的缓存策略已经设置,包括缓存目录、缓存文件名生成、缓存时间等。
- PHP 代码中增加了对缓存的检查和更新逻辑,提高了响应速度。
- 对于非图片资源的请求,仍然会转发到远程服务器并返回响应内容。
您可以根据实际需求进行进一步的调整和优化。如果有任何其他问题,欢迎继续提出。