介绍
DigitalOcean Spaces是一个与S3 API兼容的对象存储服务。 在本教程中,我们将向您展示如何使用Nginx来代理您的空间上的对象的请求。 Nginx会接收来自用户的HTTP(S)请求,并将它们传递给Spaces服务,该服务会通过Nginx将结果发送回去。
您可能希望在Spaces前放置Nginx代理的一些原因是:
- 添加一个自定义域
- 添加您自己的缓存
- 使用您自己的SSL证书
- 使用不同的访问控制机制
- 将数据中心内的资产缓存到离用户更近的数据中心
在本教程中,我们将设置Nginx来回答我们自己域中的请求(可选让我们加密SSL证书),并将这些请求转发给具有公共资产的空间。 然后,我们将添加缓存,以加快对经常访问的对象的后续响应。
先决条件
要完成本教程,您应该拥有以下内容:
- 安装了Nginx的Ubuntu 16.04服务器,如我们在Ubuntu 16.04上安装Nginx的教程中所解释的
- 指向您的服务器的域名,按照如何使用DigitalOcean设置主机名 。 在本教程中,我们将使用assets.example.com
DigitalOcean空间。 您可以通过阅读了解如何创建新的 。
你需要知道你的个人空间的网址。 您可以在DigitalOcean控制面板中找到您的空间。 网址直接位于用户界面中的空间名称下方。 这在下面的屏幕截图中突出显示:
您还需要上传到您的空间的文件来测试。 前面提到的Spaces文章展示了如何使用Spaces web GUI上传文件。 我们将在本教程中使用
example.png
。
设置代理
在Ubuntu上默认安装的Nginx会为所有的请求返回一个Welcome to Nginx的占位符页面。 我们需要添加一些新的配置来告诉Nginx做一些其他的请求到我们的域名。
为此,请在/etc/nginx/sites-available
打开一个新的配置文件:
sudo nano /etc/nginx/sites-available/assets.example.com
这将在nano
文本编辑器中打开一个空白文件。 粘贴到以下配置中,确保使用您自己的域名和Spaces URL替换突出显示的部分:
server {
listen 80;
listen [::]:80;
server_name assets.example.com;
location / {
proxy_pass https://example.nyc3.digitaloceanspaces.com/;
proxy_hide_header Strict-Transport-Security;
}
}
完成后保存文件并退出编辑器。 这是一个标准的Nginx server
模块。 首先我们告诉它在IPv4和IPv6上监听端口80
,并指定Nginx应该响应的server_name
。
接下来我们创建一个location
块。 该块内的任何配置指令(在{
和}
括号之间)仅适用于特定的URL。 在这种情况下,我们指定/
,根URL,所以所有的位置将被这个块匹配。
proxy_pass
指令告诉Nginx将请求传递给指定的服务器。 proxy_hide_header
行在将响应传递回客户端之前proxy_hide_header
Strict-Transport-Security
标头。 空间使用这个头来强制所有连接到HTTPS。 如果您的网站可通过HTTP和HTTPS连接访问,则将此标头传递给用户可能会产生意想不到的后果。
现在我们的配置已经设置好了,我们需要启用它。 这是通过在/etc/nginx/sites-enabled/
目录中创建指向配置文件的链接来完成的:
sudo ln -s /etc/nginx/sites-available/assets.example.com /etc/nginx/sites-enabled/
要检查我们的配置语法,以root身份运行nginx -t
:
sudo nginx -t
Outputnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
最后,重新加载Nginx来获取新的配置:
sudo systemctl reload nginx
使用我们的配置文件设置,让我们测试代理。
测试代理
我们可以在命令行中使用curl
来测试代理连接。 curl -I
将只返回响应的HTTP头。 这足以确定事情运作良好。
首先,使用digitaloceanspaces.com网址直接从您的空间获取对象。 我们将使用我们的example.png
文件:
curl -I https://www.youcl.com/uploads/example.png
OutputHTTP/1.1 200 OK
Content-Length: 81173
Accept-Ranges: bytes
Last-Modified: Tue, 28 Nov 2017 21:19:37 GMT
ETag: "7b2d05a5bd1bfeebcac62990daeafd14"
x-amz-request-id: tx000000000000000002398-005a1edfcd-afba2-nyc3a
Content-Type: image/png
Date: Wed, 29 Nov 2017 16:26:53 GMT
Strict-Transport-Security: max-age=15552000; includeSubDomains; preload
我们可以在输出的第一行看到200 OK
,这是一个成功的请求。 服务器返回了文件的大小( Content-Length
),文件类型( Content-Type
)以及其他与日期和缓存相关的信息。
现在通过代理获取相同的文件:
curl -I https://www.youcl.com/uploads/example.png
OutputHTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Wed, 29 Nov 2017 16:27:24 GMT
Content-Type: image/png
Content-Length: 81173
Connection: keep-alive
Accept-Ranges: bytes
Last-Modified: Tue, 28 Nov 2017 21:19:37 GMT
ETag: "7b2d05a5bd1bfeebcac62990daeafd14"
x-amz-request-id: tx00000000000000000a045-005a1edfec-a89a3-nyc3a
答复大都是一样的。 主要的变化是标识Nginx的Server
头。 如果你的输出是相似的,你的代理工作正常!
下一步,我们将设置缓存来减少代理和Spaces之间的带宽使用,并加快响应时间。
设置缓存
为了缓存响应,Nginx需要一个地方来存储密钥,元数据和实际的响应内容。 我们将在系统的/tmp
目录中设置一个缓存目录。 为此,我们将在/etc/nginx/conf.d/
一个新文件中添加一个配置片段。 立即打开该文件:
sudo nano /etc/nginx/conf.d/example-cache.conf
粘贴在下面一行,然后保存并关闭文件:
proxy_cache_path /tmp/example-cache/ levels=1:2 keys_zone=example-cache:16m max_size=10g inactive=60m use_temp_path=off;
这一行定义了缓存的一些特征。 让我们来看看这些选项:
-
/tmp/example-cache/
是/tmp/example-cache/
的路径。 -
levels=1:2
设置目录的两级层次来存储缓存的内容。 把太多的文件放在一个目录中会导致速度和可靠性问题,所以Nginx会根据这个选项在多个目录之间分割文件。 -
keys_zone=example-cache:16m
命名我们的缓存,并设置16兆字节的内存来存储密钥。这应该是足够的内存来存储超过100,000个密钥的数据。 -
max_size=10g
将高速缓存的大小限制为10千兆字节。 您可以调整以适应您的存储和使用需求。 -
inactive=60m
意味着如果Nginx在60分钟内没有被访问(即使文件仍然有效且未到期),它将删除缓存的文件。 如果你有很多不经常访问的对象,你可能想尝试增加这个。 -
use_temp_path=off
指示Nginx将临时文件写入缓存目录,可能避免在文件系统之间复制文件,这可能会影响性能。
现在我们已经定义了一个缓存,我们需要在我们的服务器块中启用它,并设置一些额外的选项。 再次打开您的网站的配置文件:
sudo nano /etc/nginx/sites-available/assets.example.com
将以下内容添加到location /
块的末尾(在proxy_hide_header
伪指令之后,但是在括号之前):
. . .
proxy_cache example-cache;
proxy_cache_valid 200 60m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_revalidate on;
proxy_cache_lock on;
proxy_ignore_headers Set-Cookie;
add_header X-Cache-Status $upstream_cache_status;
. . .
保存并关闭文件。 让我们一一浏览这些配置选项:
-
proxy_cache
告诉Nginx使用哪个缓存。 在这种情况下,我们指定example-cache
,我们在example-cache.conf
文件中设置。 -
proxy_cache_valid
指示Nginx考虑任何有效时间为60分钟的200
响应。 这意味着,代理成功从Spaces中获取文件后,在接下来的60分钟内,Nginx将使用缓存副本,而不要求空间进行更新。 请注意,如果您的对象具有Cache-Control
标头集,则标头的值将覆盖此配置。 -
proxy_cache_use_stale
允许Nginx在Spaces服务器超时,返回错误或正在更新缓存响应的情况下返回一个陈旧(过期)的响应。 -
proxy_cache_revalidate
使代理能够使用条件GET请求重新验证缓存的文件。 这意味着,当一个缓存的文件到期,并且Nginx需要检查Spaces的变化时,Nginx将使用If-Modified-Since
或者If-None-Match
头部来获取对象,如果它确实发生了变化的话。 如果尚未更新,Spaces将返回304 Not Modified
响应,Nginx会将现有的缓存响应再次标记为有效。 - 当代理已经从后端服务器获取对象时,
proxy_cache_lock
将对后续请求进行保留。 第一个请求完成后,其他请求将从缓存中提供。 -
proxy_ignore_headers Set-Cookie
忽略可能干扰缓存的Cookie。 -
add_header X-Cache-Status...
添加一个包含关于请求是否来自缓存(HIT
)或不包含(MISS
)的信息的头部。 如果请求在缓存中但已过期,您将看到(REVALIDATED
)。
我们现在准备验证我们的配置没有错误,如果成功,请重新加载Nginx:
sudo nginx -t
sudo systemctl reload nginx
随着缓存设置,我们可以再次测试,以确保缓存工作正常。
测试缓存
为了确保缓存正在工作,我们可以再次使用curl
,并查找X-Cache-Status
头:
curl -I https://www.youcl.com/uploads/example.png
OutputHTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Wed, 29 Nov 2017 18:40:28 GMT
Content-Type: image/png
Content-Length: 81173
Connection: keep-alive
Last-Modified: Tue, 28 Nov 2017 21:19:37 GMT
ETag: "7b2d05a5bd1bfeebcac62990daeafd14"
x-amz-request-id: tx000000000000000013841-005a1eff1b-a89e4-nyc3a
X-Cache-Status: MISS
Accept-Ranges: bytes
第一个要求应该是MISS
。 尝试第二次:
curl -I https://www.youcl.com/uploads/example.png
OutputHTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Wed, 29 Nov 2017 18:40:53 GMT
Content-Type: image/png
Content-Length: 81173
Connection: keep-alive
Last-Modified: Tue, 28 Nov 2017 21:19:37 GMT
ETag: "7b2d05a5bd1bfeebcac62990daeafd14"
x-amz-request-id: tx000000000000000013841-005a1eff1b-a89e4-nyc3a
X-Cache-Status: HIT
Accept-Ranges: bytes
一个HIT
! 我们现在正在从Spaces代理和缓存对象。 在下一步中,我们将设置SSL证书来保护与我们的代理的通信。
设置TLS / SSL
尽管此步骤是可选的,但强烈建议您通过安全的HTTPS连接提供您的网站和资产。 您可以通过阅读我们的教程来了解如何从Let's Encrypt证书颁发机构下载和安装免费证书。 如何设置让我们使用Ubuntu 16.04上的Nginx服务器模块进行加密 。
结论
在本教程中,我们创建了一个Nginx配置来将对象的请求代理到Spaces服务。 然后,我们添加缓存来提高性能,并提供TLS / SSL证书以提高隐私性和安全性。
这里显示的设置是一个很好的起点,但是您可能需要根据您自己独特的流量模式和需求优化一些缓存参数。 Nginx文档 ,特别是ngx http proxy_module可以提供关于可用配置选项的更多详细信息。