乐趣区

关于前端:关于服务器端渲染的-Web-应用的-504-错误问题

除非客户在 SSR 中增加了用于显式发送 504 的自定义逻辑,否则 504 不会来自 SSR。

在默认的 Spartacus/SSR 中,没有显式发送 504 的逻辑。默认状况下它只发送 200 或 500(仅在 APP_INITIALIZER 失败的状况下)。

咱们在浏览器里看到的这个 504 谬误:

An error occurred.

Sorry, the page you are looking for is currently unavailable.

这个谬误音讯是由 nginx 生成的,并发送 504(网关超时),依据 MDN,这意味着:

504 Gateway Timeout 服务器谬误响应代码示意服务器在充当网关或代理时,没有及时从上游服务器 (the upstream server) 取得实现申请所需的响应。

在这种状况下,上游服务器是 node.js 服务器。node.js 基本没有响应,于是 nginx 网关向客户端发回 504 错误码。

如果 Node.js 响应速度过慢,Nginx 就会间接将客户端发送过去的申请通过 504 错误码响应。

在某些非凡的场景下,有问题的申请在 Dynatrace 中实际上是不可见的。

集体的猜想是 Dynatrace 只有 在申请实现时才记录了该我的项目。所以那些永远不会实现的永远不会被 Dynatrace 记录。

例如,某些申请逻辑进入了有限循环(在 Java 代码中),导致线程从未完结,该申请从未记录在 Dynatrace 中。

上面这段代码能够模仿 Node.js 主线程被 block 的场景:

export class AppComponent {constructor(protected location: Location) {}

  ngOnInit() {const url = this.location.path();
    const shouldBlock = url.endsWith('?block-main-thread-super-long');
    console.log({url, shouldBlock});
    if (shouldBlock) {this.blockMainThreadSuperLong();
    }
  }

  blockMainThreadSuperLong() {
    const SUPER_BIG_BUMER = 1_000_000_000_000_000;
    for (let i = 0; i < SUPER_BIG_BUMER; i++) {// do nothing, just looping to simulate a slow operation}
  }
}

运行命令行 curl http://localhost:4200/electronics-spa/?block-main-thread-super-long,不会收到任何响应,因为主线程被 block 住了。

再发送其余申请 curl http://localhost:4200,也收不到任何回应,这也是预料中的后果,因为主线程被 block 了。

上面代码是模仿 Node.js SSR 不再响应任何申请的场景:

// server.ts
  
  /*...*/

  let neverSendResponsesAnymore = false;

  // All regular routes use the Universal engine
  server.get('*', (req, res) => {if (req.url.endsWith('?never-send-responses-anymore')) {neverSendResponsesAnymore = true;}

    if (neverSendResponsesAnymore) {return;}

    res.render(indexHtml, {
      req,
      providers: [{provide: APP_BASE_HREF, useValue: req.baseUrl}],
    });
  });

上面这段高亮代码会导致 SSR 不响应客户端申请:

这两段代码均来自我的共事 Kris.

退出移动版