SAP

Spartacus 部署到 CCV2 上造成 Nginx 返回

2023-09-24  本文已影响0人  华山令狐冲

当 OCC 在“/pages” API 与“/components” API 之间返回不一致的响应时,就会发生该错误。 特别是,当 OCC /pages API 返回至少一个 CmsLink 组件(在 cms 导航中)时,OCC /components API 并不知情(因此,当询问详细信息时,/components API 返回空响应 此 CmsLink 组件 id),然后 Spartacus NavigationService 进入无限循环,尝试一遍又一遍地加载此 CmsLink 组件的详细信息。

考虑这种边界情况:

在本地重现错误的步骤

我们需要模拟 OCC “/pages” API 返回某个 CMS 组件的 ID,但“/components” API 在被要求提供该组件 ID 时应返回空响应。 对于客户来说,发生这种情况是因为端点“/components”(早期缓存失效)与“/pages”(晚期缓存失效)之间的 OCC 缓存失效时间不同。

为了在本地重现这个错误,我们实现一个自定义的 Angular HTTP_INTERCEPTOR 就足够了,在这个 interceptor 里,我们故意让它永远不会返回有关某些特定 CMS 组件的信息。

然后打开店面并在 ChromeDevTools Network 选项卡中观察对“/components”端点的 http 调用的无限循环。

如果任何其他客户缓存 OCC 响应(出于性能原因,他们应该这样做)并随时删除 CMS 中的某些链接,则本文描述的这个错误也可能会发生。

过时的缓存“/pages” API 返回的组件可能比最新的“/components” API 返回的详细信息要多。 最终会导致挂起 NodeJS(CPU 使用率为 100%)并造成 Nginx 返回 504 Gateway Timeout 错误页面给最终用户,而不是 CSR fallback 或最终用户可以使用的任何有意义的页面。

注意:无论Spartacus运行在浏览器(CSR)还是NodeJS(SSR)中,都会发生这样的无限循环。

从 Spartacus 的角度来看,当 /pages API 返回 cms 结构中的组件 ID 时,Spartacus 会尝试通过 /components API 加载所有这些组件的详细信息。 目前,当“/components” API 返回给定 ID 的空响应时,ngrx 状态对象引用会被更新,尽管该空响应实际上并未更改 ngrx 状态 - 它只是状态的对象引用无缘无故地更改了 。 对象引用的此类更改会触发在此状态下可观察到的 RxJ 的 emit.

这会导致从“NavigationService.getNavigationNode()”返回的流中的“$data” Observable 对象发出一个新值。 在此流的逻辑中,Spartacus 认识到某些组件的详细信息仍然丢失,因此尝试通过调用“CmsService.loadNavigationItems(navigation.id,missingItems)”来加载它们。

这个错误已经在这个 Pull Request里修复了。

上一篇 下一篇

猜你喜欢

热点阅读