You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

API调用位置抉择:网关过滤器VS微服务内部?

API调用位置选型分析

背景

每个请求都会经过API网关,且请求携带包含自定义声明"x-token"的JWT。这个"x-token"是用于从数据库获取对应数据的ID,3个微服务中有2个会用到它。

问题

获取xTokenObject的API调用应该放在哪里执行?

现有方案分析

1. API网关过滤器方案

在Spring Cloud Gateway中添加API过滤器,对所有GET/POST请求做修改:

  • 创建过滤器,在过滤器里调用API获取与"x-token"关联的xTokenObject,然后修改请求,把xTokenObject加入请求体,让微服务的Controller可以直接使用。

优点

  • 权限集中管控:只有API网关拥有访问该数据API的权限
  • 微服务使用便捷:控制器可以直接拿到xTokenObject,无需额外处理

微服务控制器使用示例代码:

@PostMapping()
public ResponseEntity<SomeObject> someMethod(@RequestBody @Valid XTokenObject xTokenObject){
  return ResponseEntity.ok(this.someService.someFunction(xTokenObject));
}

缺点

  • 存在请求体冲突问题:如果请求本身已有请求体,无法直接将xTokenObject合并进去,微服务控制器也难以同时获取原请求体和新增对象。

2. 微服务内部调用方案

在网关过滤器里给请求添加携带"x-token"的请求头,然后在微服务的@Service层中用这个值调用API获取xTokenObject。

优点

  • 实现成本低:网关添加请求头比修改请求体简单得多

微服务Service层示例代码:

@Service
public class SomeService {  
    public SomeObject someFunction(String xTokenId) {
    // 在这里用xTokenId调用API获取数据
    return someObject;
  }
}

缺点

  • 重复配置多:需要用到该数据的2个微服务都得单独配置与数据API的连接,冗余工作多。

补充疑问与考量

哪种方案性能更快?有没有更优的方案?另外,Token Data微服务的数据包含敏感信息,是加密存储在认证服务器的同库不同表中的,我还考虑用Redis缓存这些数据。

方案对比与最优建议

性能对比

  • 网关过滤器方案:所有请求仅在网关层调用一次数据API,配合Redis缓存的话,还能直接从缓存取结果,避免重复调用,高并发场景下性能优势明显。
  • 微服务内部调用方案:每个微服务都要单独发起API请求,即使是同一个x-token的请求,不同微服务可能重复调用,性能损耗大,缓存也需要每个微服务单独维护,成本高。

网关方案的请求体问题解决

如果请求已有请求体,不建议修改原请求体,推荐用以下方式传递xTokenObject:

自定义请求头传递

在网关过滤器中将xTokenObject序列化为JSON字符串,放到自定义请求头(如X-Token-Object)中,微服务控制器通过@RequestHeader获取后反序列化即可。
示例代码:

// 网关过滤器中
ObjectMapper objectMapper = new ObjectMapper();
String xTokenObjectJson = objectMapper.writeValueAsString(xTokenObject);
exchange.getRequest().mutate().header("X-Token-Object", xTokenObjectJson).build();

// 微服务控制器中
@PostMapping()
public ResponseEntity<SomeObject> someMethod(@RequestBody @Valid OriginalRequestBody originalBody,
                                             @RequestHeader("X-Token-Object") String xTokenObjectStr) throws JsonProcessingException {
    XTokenObject xTokenObject = new ObjectMapper().readValue(xTokenObjectStr, XTokenObject.class);
    return ResponseEntity.ok(this.someService.someFunction(originalBody, xTokenObject));
}

最优方案推荐

推荐网关过滤器+Redis缓存的组合:

  1. 网关层统一处理:只有网关调用数据API,优先从Redis缓存读取,缓存失效时再请求后端,减少数据库压力。
  2. 请求头传递数据:避免修改原请求体的冲突问题,实现简单。
  3. 权限与复杂度管控:微服务无需直接连接数据API,权限集中在网关,降低微服务配置复杂度。

敏感数据处理建议

因为数据是加密存储的,网关获取后:

  • 优先传递微服务所需的非敏感字段,减少敏感数据传输范围;
  • 如果必须传递敏感信息,保持加密状态传输,微服务按需解密(需确保微服务有解密权限),降低传输泄露风险。

内容的提问来源于stack exchange,提问作者dvbngln

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 09:45:42