如何让nginx try_files及时获取html资源

如何让nginx try_files及时获取html资源

在实例上使用nginx1.8.1 Amazon Linux EC2。用作反向代理以支持Apache在不同实例上运行的 https。除了这个问题之外,一切运行正常。

我想提供一个静态页面,以防nginx万一我需要关闭Apache服务器实例。所以我这样做了:

    location   / {
        try_files /site-down.html $uri @backend;
    }

因此,在关闭后端服务器之前,我在nginx服务器的根目录中创建了一个指向静态 html 文件的符号链接,如下所示:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

  <title>example.com</title>
  <style type="text/css">
  body {
    background-image:url('/images/back-soon-background.jpg');
    font-family: arial,verdana,sans-serif;
    text-align: center;
  }
  #msg {
    background-image: url('/images/back-soon-oval.png');
    background-repeat: no-repeat;
    width: 600px;
    padding-top: 140px;
    padding-left: 50px;
    padding-right: 50px;
    padding-bottom: 150px;
  }
  </style>
</head>

<body>
<div id="msg">
<h1>Sorry, the site is currently unavailable.</h1>
<h2>We expect to be back within 2 hours.</h2>
</div>
</body>
</html>

问题是,当我这样做时,页面会立即显示为 的文本内容,而不显示部分中div指定的图像。使用开发人员工具的“网络”选项卡,我可以看到对图像 URL 的请求,并获取 200 个状态代码。但如果我单击这些请求,则没有可用的预览,并且正文长度太短。重新加载页面不会立即有所帮助。但如果我让它在那里停留一会儿,最终会出现带有图像的正确输出。如果我将浏览器直接指向,页面会立即正确显示。<style><head>Chrome/site-down.html

Chrome 52.0.2743.116 m和的Firefox 48.0.2行为方式相同。我对 还不熟悉nginx,但我无法想象为什么 try_files 中的第一个行为与在文件存在的情况下uri直接转到 的行为有什么不同。我遗漏了什么?uri

答案1

@Michael-Hampton 的评论为我提出的问题提供了答案。大约 6 周前,我建议,如果他将该信息发布为答案,我会将其标记为已接受。但由于他没有这样做,我在这里构建了一个答案以供接受。没有回答这个问题似乎很可惜。

我问的这个问题的答案只是我指定的 nginx 配置强制全部请求首先尝试提供静态site-down.html页面。由于图像被指定为同一站点的 URL,因此这些图像请求也由该/ location指令处理,因此指令try_files也应用并更改了它们以提供页面site-down.html

我不知道为什么经过几次重新加载和等待之后图像最终会出现,一定是某些东西超时了。

在我看来,解决这个问题最直接的方法是将背景图像的 URL 更改data为将图像内容本身嵌入字符串的 URL base64。通过这样做,site-down.html页面不会生成任何额外的资源请求,并且它按照我最初的意图工作。

但他还指出,我尝试做的事情是,在工作时,即使网站基本上处于关闭状态,也会给出 200 状态代码。我解释说,该网站仅供交互式用户使用,而不是服务器,这是为了应对短期故意中断,而不是后端服务器崩溃等错误。所以我认为这不是一个大问题。但事实是,给出一个有意义的状态代码总是最好的。所以我认为对我来说“正确”的解决方案是有两个不同的“可用”nginx 配置文件,其中一个只是使用 site-down.html 作为自定义错误页面硬编码 503 响应。然后,我不应该在根目录中创建/删除名为 site-down.html 的符号链接,并依靠 try_files 来提供所需的行为,而应该只更改 sites-enabled 目录中的符号链接以选择正确的配置并执行操作sudo service nginx reload以平滑切换行为。

使用 try_files 的优点是只需一个命令即可立即切换行为,而缺点是状态代码表明网站运行正常,即使事实并非如此。切换配置文件的优点是它提供了有意义的状态,而缺点是重新加载 nginx 的额外步骤可能会被遗忘。但是,最终切换将由脚本完成,并且脚本不会忘记重新加载配置。

答案2

try_files 按照您指定的顺序尝试文件。将顺序更改为类似以下顺序

try_files $uri @backend /site-down.html;

我假设由于页面现在正在提供服务,所以您已将其他所有设置都设置好了。尝试一下,如果您需要进一步的帮助,请在答案上发表评论。如果适用,请务必包含日志。

答案3

使用error_page指令来处理后端宕机的情况。这还可以让您返回正确的 HTTP 响应代码。

例如:

server {
    try_files $uri @backend;

    error_page 500 502 503 504 =503 /site-down.html;

    #....

在这种情况下,我们首先提供静态文件,然后转到后端。如果后端返回列出的错误之一,则 nginx 将/site-down.html使用 HTTP 503 响应提供服务。

这种方法的好处是你不必手动添加或删除文件site-down.html。你把它留在原处,如果后端实际上向下。

相关内容