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

码途星河引
• 阅读 624

除非客户在 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.

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

这个错误消息是由 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 不响应客户端请求:
关于服务器端渲染的 Web 应用的 504 错误问题

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

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
VBox 启动虚拟机失败
在Vbox(5.0.8版本)启动Ubuntu的虚拟机时,遇到错误信息:NtCreateFile(\\Device\\VBoxDrvStub)failed:0xc000000034STATUS\_OBJECT\_NAME\_NOT\_FOUND(0retries) (rc101)Makesurethekern
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这