让 Spartacus 服务器端渲染引入 long API 调用超时机制的两种配置方法

举报
汪子熙 发表于 2023/04/17 10:58:38 2023/04/17
【摘要】 两种方法,使用 config.backend.timeout = { 浏览器:...,服务器:...} ,或者可以更具体地配置,即基于 Request 粒度,通过将 HTTP_TIMEOUT_CONFIG HttpContextToken 传递给 Angular HttpClient 的方法来针对每个具体请求进行配置。在SSR(Node.js)中,超时处理耗时过长的外部http调用是一项尤为...

两种方法,使用 config.backend.timeout = { 浏览器:...,服务器:...} ,或者可以更具体地配置,即基于 Request 粒度,通过将 HTTP_TIMEOUT_CONFIG HttpContextToken 传递给 Angular HttpClient 的方法来针对每个具体请求进行配置。

在SSR(Node.js)中,超时处理耗时过长的外部http调用是一项尤为重要的改进,因为在Node.js中,与浏览器不同,Node.js 运行环境下并没有默认的外部http调用超时时间(浏览器通常会在长时间后超时长时间的http调用,例如1分钟)。

这种可配置的超时逻辑现在已经在Spartacus中的 Angular Http拦截器层面上实现。也就是说,在 Spartacus SSR long API timeout 功能发布之前,客户可以自己实现类似的逻辑,例如通过自己实现 Angular Http 拦截器来实现。

配置代码:

provideConfig({ 
  backend: { 
    timeout: { 
      server: 3_000,
      browser: 3_000
    }
  }
})

如何使用代理服务器制造后台 API 响应的延时效果

首先Install http-proxy tool:npm install -g http-proxy

然后开发一个 http-proxy.js server file

const httpProxy = require('http-proxy');
const http = require('http');

const proxy = httpProxy.createProxyServer({ secure: false });

const ENDPOINT_FOR_DELAY = 'consenttemplates';
const BACKEND_BASE_URL = 'https://jerry:9002';
const DELAY = 3000; // 手动硬编码的延时

/** custom predicate, whether we should delay a request */
const shouldDelay = (req) => {
  // Note: In browser there are 2 requests: preflight (OPTIONS) and actual request (GET).

  const result = req.url.includes(ENDPOINT_FOR_DELAY);
  result && console.log({ delay: DELAY, url: req.url, method: req.method });
  return result;
};

http
  .createServer(function (req, res) {
    const forwardRequest = () =>
      proxy.web(req, res, { target: BACKEND_BASE_URL });
    const delay = shouldDelay(req) ? DELAY : 0;
    setTimeout(forwardRequest, delay);
  })
  .listen(9002);

然后启动这个代理服务器:node http-proxy.js

最后在 .env-cmdrc 里指定环境变量 CX_BASE_URL:

  "dev": {
    "CX_BASE_URL": "http://localhost:9002"
  },

针对某个具体请求设置 timeout:

import { HTTP_TIMEOUT_CONFIG, HttpTimeoutConfig } from `@spartacus/core`;/* ... */
​
​
return this.httpClient.get('/some/api', {
  context: new HttpContext().set(
    HTTP_TIMEOUT_CONFIG, 
    { server: 15_000 } // value in milliseconds 
  )
})

当超时真的发生之后,可以在 console 看到下列的警告消息:

Request to URL ‘${request.url}’ exceeded expected time of ${timeoutValue}ms and was aborted.

总之,对于在 NodeJS 中运行的服务器端渲染应用程序的稳定性来说,为每个传出的 http 调用设置一个明确的超时时间是至关重要的。 否则,如果后端 API 响应非常慢(或从不响应),服务器端呈现的应用程序将等待响应很长时间(或永远)。 在这种情况下,为该应用程序分配的内存不会被释放,这会引起内存泄漏问题。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。