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

简介: 关于服务器端渲染的 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.

91cda3e0db515157f56dacf18c2cccdd.png

这个错误消息是由 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 不响应客户端请求:

442b255d9e91c8a846b44d3b0e8e5e56.png

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

相关文章
|
3天前
|
JavaScript 搜索推荐 前端开发
理解服务器端渲染(SSR):提高网页性能与SEO的秘籍
理解服务器端渲染(SSR):提高网页性能与SEO的秘籍
|
2天前
|
缓存 监控 安全
Django框架在大型Web应用中的架构设计与实战
【5月更文挑战第18天】Django框架在构建大型Web应用中扮演重要角色,采用分层架构(数据、业务逻辑、表示层)和多应用组织模式,结合缓存策略(如Memcached、Redis)提升性能。通过异步处理、分布式部署提高响应速度和扩展性。关注数据分区、安全设计及监控日志,确保系统高效、稳定。Django为复杂业务提供坚实基础,助力打造卓越Web系统。
18 7
|
2天前
|
开发框架 中间件 数据库
Django 框架入门全攻略:轻松构建 Web 应用
【5月更文挑战第18天】本文是 Django 入门教程,介绍了如何使用 Django 构建 Web 应用。内容包括安装、项目与应用创建、模型定义、数据库迁移、视图编写、路由配置、模板系统、表单处理和中间件的使用。通过实例展示了 Django 基本流程,帮助初学者快速上手。Django 提供高效工具,便于开发者聚焦业务逻辑,轻松构建功能丰富的 Web 应用。
18 5
|
2天前
|
存储 缓存 API
Flask 框架在大型 Web 应用中的使用与挑战
【5月更文挑战第18天】Flask框架适用于快速开发轻量级Web应用,但用于大型应用时需应对性能、代码管理和团队协作的挑战。通过集成扩展处理复杂需求,使用蓝图组织代码,以及引入缓存优化性能,结合明确的代码规范和开发流程,可有效应对挑战,构建高效稳定的应用。
18 5
|
2天前
|
数据库连接 Python
Flask 框架入门与实践:构建你的第一个 Web 应用
【5月更文挑战第18天】本文介绍了使用 Flask 框架构建第一个 Web 应用的步骤。首先通过 `pip install Flask` 安装框架,然后编写基本的 Python 代码创建应用,包括定义路由和响应。示例展示如何显示 &quot;Hello, World!&quot;,并扩展到显示用户信息的功能。利用模板(如 `index.html`)可使页面更丰富。随着学习深入,可以利用 Flask 的更多特性,如表单处理和数据库连接,来构建更复杂的 Web 应用。本文旨在激发读者对 Flask 和 Web 开发的兴趣,鼓励不断探索和实践。
15 7
|
2天前
|
JavaScript 前端开发 Java
web服务器是什么
web服务器是什么
15 0
|
2天前
|
存储 前端开发 网络协议
所有的 Web 应用其实就是一个 socket 服务端, 而用户使用的浏览器就是一个 socket 客户端程序
所有的 Web 应用其实就是一个 socket 服务端, 而用户使用的浏览器就是一个 socket 客户端程序
8 0
|
3天前
|
前端开发 Java Go
从前端到后端:构建现代化Web应用的技术实践
本文将介绍如何通过前端和后端技术相结合,构建现代化Web应用的技术实践。我们将探讨前端开发、后端架构以及多种编程语言(如Java、Python、C、PHP、Go)在构建高效、可扩展的Web应用中的应用。
|
4天前
|
JavaScript 前端开发 API
Vue中的组件:构建现代Web应用的基石
Vue中的组件:构建现代Web应用的基石
|
4天前
|
前端开发 JavaScript 开发者
深入理解MVC和MVVM:构建现代Web应用的利器
深入理解MVC和MVVM:构建现代Web应用的利器
http://www.vxiaotou.com