下载端部署方案
注
由于服务端使用 Flask 这个同步框架,所以在线程数有限的情况下,默认的部署方案根本无法满足多用户同时下载的需求。以下是一些部署方案的建议,供有需要的用户参考。
单机方案
NGINX X-Accel-Redirect
nginx 是著名的高性能 HTTP 服务器,支持反向代理、负载均衡等功能。通过使用 X-Accel-Redirect 功能,可以让服务端返回一个特殊的响应头,指示 nginx 直接从指定路径提供文件,这种方式可以大大提高下载性能和并发能力。顺带,这里也将其它请求交给 nginx 代理。
将请求全部由 nginx 代理,则需要它监听 80 端口,服务端需要换一个端口以防冲突。如果你需要配置 SSL 证书,请参考 nginx 的相关文档,并换为 443 等端口。
class Config:
HOST = '0.0.0.0'
PORT = 81
# USE_CORS = True
USE_PROXY_FIX = True
# DEPLOY_MODE = 'waitress'
DOWNLOAD_LINK_PREFIX = '' # http(s)://host(:port)/download/
BUNDLE_DOWNLOAD_LINK_PREFIX = '' # http(s)://host(:port)/bundle_download/
DOWNLOAD_USE_NGINX_X_ACCEL_REDIRECT = True
NGINX_X_ACCEL_REDIRECT_PREFIX = '/nginx_download/'
BUNDLE_NGINX_X_ACCEL_REDIRECT_PREFIX = '/nginx_bundle_download/'提示
以上配置项中,如果你开启了 USE_PROXY_FIX,并对 nginx 进行了相应配置,则 DOWNLOAD_LINK_PREFIX 和 BUNDLE_DOWNLOAD_LINK_PREFIX 无需配置,可自动获取地址和端口,否则请手动配置。
非常建议使用 DEPLOY_MODE 开启部署模式,以获得更好的性能。
上面是服务端的配置,接下来是 nginx 的配置示例,以 Windows 为例:
server {
listen 80;
server_name _;
location / {
proxy_pass http://127.0.0.1:81;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Prefix /;
}
location /nginx_download/ {
internal;
alias "E:/arcaea_server/database/songs/"; # change to your actual path
# NOTE: slash at the end of alias is important
}
location /nginx_bundle_download/ {
internal;
alias "E:/arcaea_server/database/bundle/"; # change to your actual path
# NOTE: slash at the end of alias is important
}
}提示
以上配置示例中,alias 的路径需要改为你实际的路径,并且路径末尾必须有一个斜杠 /。因为 alias 的作用是将请求路径 /nginx_download/ 替换为下面的值。
远程方案
远程方案指的是主服务器与下载服务器并不是同一台机器,这种方案适用于需要分担下载压力或者主服务器带宽不足的情况。目前让客户端请求远程链接的方式是 302 重定向,是否拥有很好的兼容性并不清楚。
NGINX secure_link
nginx 是著名的高性能 HTTP 服务器,支持反向代理、负载均衡等功能。通过使用 secure_link 功能,可以让服务端生成一个带有加密签名的下载链接,使用 302 重定向的方式将用户引导到 nginx 进行下载。这种方式既可以远程部署,也可以单机部署。你可以参考 ngx_http_secure_link_module 文档 来了解更多。
主服务器上的服务端配置文件如下,你需要根据下载服务器实际的地址和端口来修改 download_link_host 和 bundle_download_link_host 这两项:
class Config:
HOST = '0.0.0.0'
PORT = 81
# USE_CORS = True
# USE_PROXY_FIX = True
DEPLOY_MODE = 'waitress'
REMOTE_DOWNLOAD_MODE = 'nginx'
REMOTE_DOWNLOAD_OPTIONS = {
'nginx': {
# nginx secure_link
'download_link_host': 'http(s)://<host>:<port>', # change to your actual address
'download_link_prefix': '/arcaea_server_download',
'bundle_download_link_host': 'http(s)://<host>:<port>', # change to your actual address
'bundle_download_link_prefix': '/arcaea_server_bundle_download',
'secret_key': 'nginx_secure_link_md5_secret_key',
}
}尽管这种方式不需要在主服务器上部署 nginx,我们仍然推荐这么做。此处省略主服务器的 nginx 部署配置示例,以下是下载服务器的 nginx 配置示例:
server {
listen 80;
server_name _;
# ......
location /arcaea_server_download/ {
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$secure_link_expires|$uri nginx_secure_link_md5_secret_key";
if ($secure_link = "") { return 403; }
if ($secure_link = "0") { return 410; }
alias "E:/arcaea_server/v0.updating/database/songs/"; # change to your actual path
# NOTE: slash at the end of alias is important
}
location /arcaea_server_bundle_download/ {
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$secure_link_expires|$uri nginx_secure_link_md5_secret_key";
if ($secure_link = "") { return 403; }
if ($secure_link = "0") { return 410; }
alias "E:/arcaea_server/v0.updating/database/bundle/"; # change to your actual path
# NOTE: slash at the end of alias is important
}
}提示
以上配置示例中,alias 的路径需要改为你实际的路径,并且路径末尾必须有一个斜杠 /。因为 alias 的作用是将请求路径 /arcaea_server_download/ 替换为下面的值。
基于安全考虑,在生产环境下,建议修改 secret_key 的值为一个随机且足够复杂的字符串,并且将这个值同步到下载服务器的 nginx 配置中的 nginx_secure_link_md5_secret_key 位置,以确保生成的下载链接能够被正确验证。