如何在没有 404 的情况下更新 AWS 负载均衡器后面的 React 应用程序,因为更改了 main.js 上的哈希值?

问题描述 投票:0回答:2

我正在使用

AWC CodeDeploy
部署一个react-app,以下结构是由
npx create-react-app
npm build

生成的
/var/www/my-website
.
├── asset-manifest.json
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
├── robots.txt
└── static
    ├── css
    │   ├── main.2be1a5a0.css
    │   └── main.2be1a5a0.css.map
    ├── js
    │   ├── 787.28cb0dcd.chunk.js
    │   ├── 787.28cb0dcd.chunk.js.map
    │   ├── main.77918f81.js
    │   ├── main.77918f81.js.LICENSE.txt
    │   └── main.77918f81.js.map
    └── media
        ├── ...

生成的

index.html
看起来像这样

<!doctype html>
<html lang="en">
   <head>
      <meta charset="utf-8"/>
      <link rel="icon" href="/favicon.ico"/>
      <meta name="viewport" content="width=device-width,initial-scale=1"/>
      <meta name="theme-color" content="#000000"/>
      <meta name="description" content="Web site created using create-react-app"/>
      <link rel="apple-touch-icon" href="/logo192.png"/>
      <link rel="manifest" href="/manifest.json"/>
      <title>React App</title>
      <script defer="defer" src="/static/js/main.77918f81.js"></script>
      <link href="/static/css/main.2be1a5a0.css" rel="stylesheet">
   </head>
   <body>
      <noscript>You need to enable JavaScript to run this app.</noscript>
      <div id="root"></div>
   </body>
</html>

EC2 AMI 配置了 nginx

    server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /var/www/my-website;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }

现在,当使用

in-place
blue/green
部署在 AWS 负载均衡器后面运行 AWS CodeDeploy 时,会出现这样的情况:在一段时间内(直到
in-place
完成或
blue/green
取消注册所有旧实例)某些实例为新版本和一些旧版本。

现在出现以下问题:

  1. HTTP 请求路由到
    InstanceOld1
    ,index.html 带有
    <script defer="defer" src="/static/js/main.hash1.js">
  2. InstanceOld1 尝试通过负载均衡器通过 HTTP 调用
    /static/js/main.hash1.js
     来加载 
    http://abc-alb-xyz.eu-central-1.elb.amazonaws.com/static/js/main.hash1.js
  3. 负载均衡器将调用分配给
    InstanceNew1
    ,它不知道
    main.hash1.js
    ,而只知道
    main.hash2.js
    ,因此它返回 404

同样的情况也适用于相反的情况。仅当所有提取碰巧命中部署了相同版本的实例时,它才有效。

有什么办法可以解决这个问题吗?例如。不通过负载均衡器而是在本地加载 main.js 和 main.css?

reactjs amazon-web-services aws-code-deploy
2个回答
0
投票

您可以尝试为您的资产使用 CDN(例如 CloudFront)。 CDN 将缓存旧资产并在部署期间继续为它们提供服务。您可以在构建过程中上传它们吗?

但是 CDN 仍然存在问题,如果部署仍在进行并且您不断刷新页面,您可能会看到一个版本,然后返回旧版本。

您可以尝试使用IP地址进行负载平衡(https://nginx.org/en/docs/http/ngx_http_upstream_module.html#ip_hash)。那么来自一个用户的请求总是最终到达同一台服务器(具有相同的版本)?


0
投票

我花了很长时间来解决这个问题......

但我通过在用于反应应用程序的目标组中启用粘性会话解决了这个问题。

现在对index.html的请求将带有AWS cookie标头。这将确保对静态文件的所有后续请求都将从同一实例提供服务。

© www.soinside.com 2019 - 2024. All rights reserved.