Azure APIM如何为带授权头的请求实现全局缓存(非按用户)
核心原因排查
你遇到的问题核心是缓存键一致但始终未命中,结合配置和Trace信息,大概率是以下几个原因之一:
1. Authorization头仍被纳入缓存键计算
即使设置了vary-by-developer="false"和vary-by-developer-groups="false",APIM默认会将请求中的Authorization头作为缓存键的一部分。不同用户的Bearer Token不同,导致Trace中隐藏的缓存键实际存在差异,每个请求对应不同的缓存条目,因此每次都是Miss。
2. 后端响应的Cache-Control头阻止缓存
虽然cache-lookup策略移除了请求的Cache-Control: no-cache, no-store,但如果后端返回的响应包含no-cache/no-store/private这类禁止缓存的指令,APIM的cache-store策略会忽略存储该响应,即便Trace显示"会缓存"。
3. Cache-Store策略配置缺失关键参数
若cache-store未同步设置caching-type="external"、allow-private-response-caching="true",或者未显式排除Authorization头的影响,会导致缓存无法正确存储。
4. 响应包含Set-Cookie头
如果后端响应带有Set-Cookie头,APIM默认不会缓存该响应,除非在cache-store策略中添加ignore-set-cookies="true"参数。
具体修复步骤
步骤1:修改Cache-Lookup策略,排除Authorization头
显式指定vary-by-header为空,避免Authorization头干扰缓存键计算:
<cache-lookup vary-by-developer="false" vary-by-developer-groups="false" downstream-caching-type="none" caching-type="external" allow-private-response-caching="true" vary-by-header="" />
步骤2:同步配置Cache-Store策略
确保cache-store与cache-lookup配置匹配,添加必要参数:
<cache-store duration="3600" caching-type="external" allow-private-response-caching="true" ignore-set-cookies="true" />
ignore-set-cookies="true":若后端返回Set-Cookie头,必须添加此参数才能缓存。duration="3600":确保缓存时长符合预期。
步骤3:强制覆盖后端响应的Cache-Control头
如果后端返回禁止缓存的响应头,在cache-store之前添加set-header策略,强制设置允许缓存的头:
<set-header name="Cache-Control" exists-action="override"> <value>public, max-age=3600</value> </set-header>
步骤4:验证Redis缓存条目
通过Redis CLI连接Azure Redis实例,使用KEYS *命令查看是否生成了对应的缓存键,确认缓存条目是否存在。
验证方法
- 再次执行Trace,观察
cache-lookup是否显示"Cache lookup resulted in a hit"。 - 检查Redis中的缓存键是否与Trace中显示的一致。
- 使用不同Bearer Token发起请求,确认是否能命中同一缓存条目。
内容的提问来源于stack exchange,提问作者bosco

