如何在Ubuntu16.04上使用Nginx代理DigitalOceanSpaces

来自菜鸟教程
跳转至:导航、​搜索

注意: 自本教程发布以来,DigitalOcean Spaces 添加了一个免费的 CDN 选项,其中包含可自定义的端点子域。 此 CDN 功能提供下面介绍的大部分功能,包括缓存、自定义域、SSL 以及将资产移近用户。

请阅读 官方 Spaces 产品文档 了解如何 启用 CDN 和 自定义 CDN 端点。


介绍

DigitalOcean Spaces 是与 S3 API 兼容的 对象存储 服务。 在本教程中,我们将向您展示如何使用 Nginx 代理对您空间上的对象的请求。 Nginx 将接收来自您的用户的 HTTP(S) 请求并将它们传递给 Spaces 服务,该服务将通过 Nginx 将结果发送回。

您可能希望在 Spaces 前面放置 Nginx 代理的一些原因是:

  • 添加自定义域
  • 添加自己的缓存
  • 使用您自己的 SSL 证书
  • 使用不同的访问控制机制
  • 在离用户更近的数据中心缓存资产

在本教程中,我们将设置 Nginx 来回答我们自己域上的请求(使用可选的 Let's Encrypt SSL 证书)并将这些请求转发到具有 public 资产的空间。 然后,我们将添加缓存以加快对频繁访问的对象的后续响应。

先决条件

要完成本教程,您应该具备以下条件:

  • 安装了 Nginx 的 Ubuntu 16.04 服务器,如我们的教程 How To Install Nginx on Ubuntu 16.04 中所述

  • 根据 如何使用 DigitalOcean 设置主机名,指向您的服务器的域名。 我们将在本教程中使用 assets.example.com

  • 一个数字海洋空间。 您可以通过阅读 DigitalOcean Spaces 简介 了解如何创建新空间。

    您需要知道个人空间的 URL。 您可以通过在 DigitalOcean 控制面板中导航到您的空间来找到它。 URL 位于 UI 中空间名称的正下方。 这在下面的屏幕截图中突出显示:

    您还需要将文件上传到您的空间以进行测试。 前面提到的 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:

/etc/nginx/sites-available/assets.example.com

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 行在将响应传递回客户端之前去除了 Strict-Transport-Security 标头。 Spaces 使用此标头强制所有连接到 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 URL 直接从您的空间中获取对象。 我们将使用我们的 example.png 文件:

curl -I https://example.nyc3.digitaloceanspaces.com/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 http://assets.example.com/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 标头。 如果您的输出相似,则您的代理工作正常!

在下一步中,我们将设置缓存以减少代理和空间之间的带宽使用,并加快响应时间。

设置缓存

为了缓存响应,Nginx 需要一个地方来存储键、元数据和实际的响应内容。 我们将在系统的/tmp目录中设置一个缓存目录。 为此,我们将在 /etc/nginx/conf.d/ 中的新文件中添加一个配置片段。 现在打开该文件:

sudo nano /etc/nginx/conf.d/example-cache.conf

粘贴以下行,然后保存并关闭文件:

/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/ 是缓存的路径。
  • levels=1:2 设置两级目录层次结构来存储缓存的内容。 将太多文件放在单个目录中会导致速度和可靠性问题,因此 Nginx 将基于此选项在多个目录之间拆分文件。
  • keys_zone=example-cache:16m 命名我们的缓存并设置 16 兆字节的内存来存储密钥。 这应该足够存储超过 100,000 个键的数据。
  • max_size=10g 将缓存大小限制为 10 GB。 您可以对其进行调整以适应您的存储和使用需求。
  • inactive=60m 表示 Nginx 将在 60 分钟后删除缓存的文件,如果在这段时间内没有被访问(即使文件仍然有效且未过期)。 如果你有很多不经常访问的对象,你可能想尝试增加这个。
  • use_temp_path=off 指示 Nginx 将临时文件写入缓存目录,从而可能避免在文件系统之间复制文件的需要,这可能会影响性能。

现在我们已经定义了一个缓存,我们需要在我们的服务器块中启用它,并设置一些额外的选项。 再次打开站点的配置文件:

sudo nano /etc/nginx/sites-available/assets.example.com

将以下内容添加到 location / 块的末尾(在 proxy_hide_header 指令之后,但在结束 } 括号之前):

/etc/nginx/sites-available/assets.example.com

. . .
        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 将使用缓存的副本,而无需向 Spaces 请求更新。 请注意,如果您的对象设置了 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 http://assets.example.com/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 http://assets.example.com/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 连接可用。 您可以通过阅读我们的教程 如何在 Ubuntu 16.04 上使用 Nginx 服务器块设置 Let's Encrypt 来了解如何从 Let's Encrypt 证书颁发机构下载和安装免费证书。

结论

在本教程中,我们创建了一个 Nginx 配置来代理对 Spaces 服务的对象请求。 然后,我们添加了缓存以提高性能,并添加了 TLS/SSL 证书以提高隐私和安全性。

此处显示的设置是一个很好的起点,但您可能希望根据自己独特的流量模式和需求优化一些缓存参数。 Nginx 文档,特别是 ngx_http_proxy_module 可以提供有关可用配置选项的更详细信息。