讓 Spartacus 伺服器端渲染引入 long API 呼叫超時機制的兩種配置方法

JerryWang_汪子熙發表於2023-04-16

兩種方法,使用 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 響應非常慢(或從不響應),伺服器端呈現的應用程式將等待響應很長時間(或永遠)。 在這種情況下,為該應用程式分配的記憶體不會被釋放,這會引起記憶體洩漏問題。

相關文章