Contents
  1. 1. apache安装配置X-Sendfile过程如下:
    1. 1.1. a. 安装
    2. 1.2. b.配置
    3. 1.3. c. 使用 X-Sendfile 功能
  2. 2. nginx 安装配置 X-Sendfile 过程如下:
    1. 2.1. a. 配置
    2. 2.2. b. 使用 X-Sendfile 功能
  3. 3. 使用和未使用X-Sendfile的对比:

为了对文件下载进行控制,例如:计费、统计、权限控制等,通常由PHP提供文件的下载,即下载是通过 类似 download.php?id=xxx的方式进行,而不是在 document root 下直接 文件的下载地址。但是由PHP处理文件的下载,没有WEB服务器直接负责静态文件的下载来得高效。如果权限控制、计费等附加功能由PHP处理,而文件下载过程则交由WEB服务器直接处理,速度就可以得到很大的提升。

X-Sendfile机制可实现在PHP文件中把文件的下载功能转交给WEB服务器处理的功能。apache, nginx均支持此种机制,apache中由第三方模块 mod_xsendfile 模块提供该功能,nginx中则自带X-Sendfile支持

apache安装配置X-Sendfile过程如下:

a. 安装

1
2
3
4
5
wget https://tn123.org/mod_xsendfile/mod_xsendfile-0.12.tar.bz2 # 下载模块源代码
tar xvf mod_xsendfile-0.12.tar.bz2 # 解压代码
cd mod_xsendfile-0.12
apxs -cia mod_xsendfile.c # 编译代码,编译完成后会自动往
# httpd.conf 中加入 LoadModule xsendfile_module .... 语句

b.配置

在 httpd.conf 中添加配置:

1
2
3
<IfModule xsendfile_module>
XSendFile on
</IfModule>

在VirtualHost 里添加 XSendPath 指令,例如:

1
2
3
4
<VirtualHost *>
ServerName someserver
XSendFilePath /var/www/protected
</VirtualHost>

/var/www/protected 为需要支持 X-Sendfile下载的目录

c. 使用 X-Sendfile 功能

在需要用到 X-Sendfile的PHP文件里,添加如下语句:
header('X-Sendfile: /file/download/path');
/file/download/path 替换成实际要下载的文件的上级目录的绝对路径

nginx 安装配置 X-Sendfile 过程如下:

a. 配置

nginx.conf 的 Server{} 里添加如下配置项:

1
2
3
4
location /protected {
internal;
alias /file/download/pat;
}

/protected 只要跟 document root 中的文件目录不相同,可任意更改
/file/download/path 替换成实际要下载的文件的上级目录的绝对路径

b. 使用 X-Sendfile 功能

在需要用到的PHP文件里,添加:
header('X-Accel-Redirect: /protected/filename');
/protected/filename 的 filename

以下是同时支持 apache、nginx两种WEB服务器的X-Sendfile下载代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
$ua = $_SERVER["HTTP_USER_AGENT"];
if (preg_match('/MSIE/', $ua)) {
header('Content-Disposition: attachment; filename="' .
rawurlencode($filename) . '"');
} elseif (preg_match("/Firefox/", $ua)) {
header('Content-Disposition: attachment; filename*="utf8\'\'' .
$filename . '"');
} else {
header('Content-Disposition: attachment; filename="' .
$filename . '"');
}
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($filePath));
if (strpos($_SERVER["SERVER_SOFTWARE"], 'Apache') !== false) {
header('X-Sendfile: ' . $filePath);
} elseif (strpos($_SERVER["SERVER_SOFTWARE"], 'nginx') !== false) {
// 使用 nginx 服务器时,则把 文件下载交给 nginx 处理,这样效率高些
header('X-Accel-Redirect: '. '/protected/' . $filename);
} else {
set_time_limit(300); // 避免下载超时
ob_end_clean(); // 避免大文件导致超过 memory_limit 限制
readfile($filePath);
}
?>

使用和未使用X-Sendfile的对比:

下载速度比较 (使用 wget,在 /dev/shm/ 目录中,下载494M的视频文件)

  • apache

    • 未使用X-Sendfile: 44.9MB/s in 11s
    • 使用X-Sendfile: 90.0MB/s in 6.1s
  • nginx

    • 未使用X-Sendfile: 96.9MB/s in 5.1s
    • 使用X-Sendfile: 1235MB/s in 0.4s

由上测试结果可知,使用X-Sendfile可以大大地提高php下文件的下载速度

Contents
  1. 1. apache安装配置X-Sendfile过程如下:
    1. 1.1. a. 安装
    2. 1.2. b.配置
    3. 1.3. c. 使用 X-Sendfile 功能
  2. 2. nginx 安装配置 X-Sendfile 过程如下:
    1. 2.1. a. 配置
    2. 2.2. b. 使用 X-Sendfile 功能
  3. 3. 使用和未使用X-Sendfile的对比: