反模式:缓存错误响应

您正在查看 ApigeeApigee Hybrid 文档。
查看 Apigee Edge 文档。

缓存是将数据临时存储在称为缓存的存储区域以供将来参考的过程。缓存数据具有显著的性能优势,因为它可:

  • 加快数据检索速度
  • 避免重复生成数据,从而缩短处理时间
  • 阻止 API 请求到达后端服务器,从而减少后端服务器的开销
  • 刚好地利用系统/应用资源
  • 缩短 API 的响应时间

只要我们必须经常访问某些不经常更改的数据,我们就强烈建议您使用缓存来存储此类数据。

Apigee 能够在运行时将数据存储在缓存中,以实现持久性和更快检索。缓存功能可通过 PopulateCache 政策LookupCache 政策InvalidateCache 政策ResponseCache 政策提供。

在本部分中,我们来了解响应缓存政策。Apigee 平台中的响应缓存政策允许您从后端服务器缓存响应。如果客户端应用反复向同一后端资源发出请求,并且资源会定期更新,则我们可以使用此政策缓存这些响应。响应缓存政策有助于返回缓存的响应,从而避免不必要地将请求转发到后端服务器。

响应缓存政策:

  • 减少到达后端的请求数
  • 减少网络带宽
  • 提高 API 性能和缩短响应时间

反模式

默认情况下,ResponseCache 政策让您可缓存 HTTP 响应以及任何可能的状态代码。这意味着成功和错误响应都可以缓存。

以下是采用默认配置的响应缓存政策示例:

<!-- /antipatterns/examples/1-1.xml -->
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ResponseCache async="false" continueOnError="false" enabled="true" name="TargetServerResponseCache">
  <DisplayName>TargetServer ResponseCache</DisplayName>
  <CacheKey>
    <Key Fragment ref="request.uri" /></CacheKey>
    <Scope>Exclusive</Scope>
    <ExpirySettings>
      <TimeoutInSec ref="flow.variable.here">600</TimeoutInSec>
    </ExpirySettings>
  <CacheResource>targetCache</CacheResource>
</ResponseCache>

响应缓存政策以其默认配置缓存错误响应。但是,建议不要在未仔细考虑不良后果的情况下缓存错误响应,因为:

  • 场景 1:临时未知时间段出现故障,即使问题已修复,我们可能会因缓存而继续发送错误响应

    OR

  • 场景 2:在固定时间段观察到故障,然后我们必须修改代码,以避免在问题得到修复后缓存响应

我们通过这两个场景来详细解释这一点。

场景 1:临时后端/资源故障

假设后端服务器故障可能是由以下某种原因造成的:

  • 临时网络故障
  • 后端服务器极其忙碌,暂时无法响应请求
  • 所请求的后端资源可能暂时被移除/不可用
  • 由于临时处理时间过长等原因,后端服务器响应缓慢。

在所有这些情况下,未知时间段可能会发生故障,之后我们可能会开始收到成功响应。如果我们缓存错误响应,则即使后端服务器问题得到解决,我们可能仍会继续给用户发送错误响应。

场景 2:持久或已更正后端/资源故障

假设我们知道后端故障将在固定时间段发生。例如,您会发现:

  • 特定后端资源将不可用 1 小时

    OR

  • 由于突发网站故障、扩缩问题、维护、升级等,后端服务器将在 24 小时内被移除/不可用。

利用这些信息,我们可以在响应缓存政策中适当地设置缓存过期时间,以便我们不会将错误响应缓存更长时间。但是,当后端服务器/资源再次可用后,我们必须修改该政策以避免缓存错误响应。这是因为,如果后端服务器出现暂时性/一次性故障,我们会缓存响应,最终导致上面场景 1 中介绍的问题。

影响

  • 缓存错误响应可能会导致发送错误响应,即使问题已在后端服务器中得到解决也是如此
  • 用户可能会花费大量精力排查问题的原因,而不知道该问题是由缓存来自后端服务器的错误响应导致的

最佳做法

  • 不要将错误响应存储在响应缓存中。确保将 ResponseCache 政策中的 <ExcludeErrorResponse> 元素设置为 true,以防止缓存错误响应,如以下代码段所示。使用此配置时,系统只会缓存默认成功代码 200 至 205 的响应(除非修改成功代码)。
    <!-- /antipatterns/examples/1-2.xml -->
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ResponseCache async="false" continueOnError="false" enabled="true" name="TargetServerResponseCache">
      <DisplayName>TargetServerResponseCache</DisplayName>
      <CacheKey>
        <KeyFragment ref="request.uri" />
      </CacheKey>
      <Scope>Exclusive</Scope>
      <ExpirySettings>
        <TimeoutinSec ref="flow.variable.here">600</TimeoutinSec>
      </ExpirySettings>
      <CacheResource>targetCache</CacheResource>
      <ExcludeErrorResponse>true</ExcludeErrorResponse>
    </ResponseCache>
  • 如果您需要出于特定原因缓存错误响应,则可以确定观察到故障的最长时长/确切时长(如果可能):
    • 适当设置过期时间,以确保您不会将错误响应缓存长于可看到故障的时长。
    • 使用响应缓存政策缓存没有 <ExcludeErrorResponse> 元素的错误响应。

    仅当您绝对确信后端服务器故障不是短期/临时故障时才执行此操作。

  • Apigee 不建议从后端服务器缓存 5xx 响应。