1. 缓存

场景:下游接口是相对静态或者可以容忍一定程度的延迟更新

策略:

  1. 在上游接口增加本地缓存(Guava Cache)或者是分布式缓存(Redis)
  2. 缓存下游接口的数据,进行主动刷新(规定的时间间隔)或者被动刷新(特定事件触发)
  3. 对于复杂查询,可以缓存查询的聚合结果

优点:减少对下游接口的调用,提高响应时间
缺点:对于时效性要求极高的业务,比如新闻,热点,价格等。对于设置缓存的过期时间及主动刷新的策略需要具体事物具体分析

//伪代码    
private Cache<String, Object> cache = CacheBuilder.newBuilder().expireAfterWrite(10,TimeUnit.MINUTES).build();

public Object getCache(String key){
    return cache.get(key, () -> fetchFromDownStream(key));
}

2.异步调用

场景:上游接口不要求实时等待下游服务的结果

举例:厨师做菜,等待肉煮熟的时间,我可以先去剥蒜,切菜

策略:

  1. 使用异步架构(如CompletableFuture,RxJava)实现异步调用。
  2. 讲下游的业务封装为异步任务,同时返回初步响应,后续通过轮询或回调的方式提供完整的数据

优点:可以提高上游的接口的吞吐量

private CompletableFuture<Response> fetchDataAsync(String param) {
    return CompletableFuture.supplyAsync(() -> fetchFromDownStream(params));
}

3.同步调用

场景:上游接口依赖多个下游接口数据的结果

策略:

  1. 如果上游接口的数据需要从多个下游服务获取,并可以并行调用下游服务。
  2. 使用并行编程框架(如CompletableFuture或者线程池)组合结果

优点:并行处理可以减少整体响应时间,响应时间主要取决于响应最慢服务的时间(木桶效应

private Response fetchFromMultipleServices(String param) {
    CompetableFuture<Data1> data1Future = Competable.supplyAsync(() -> fetchFromDownStreamService1(param));
    CompetableFuture<Data2> data2Future = Competable.supplyAsync(() -> fetchFromDownStreamService2(param));
    return data1Future.thenCombine(data2Future, (data1, data2) -> merge(data1, data2)).join);
}

4.请求批量化

场景:上游接口的请求量高,且对下游服务的调用重复率高。

策略:

  1. 短时间将多个请求合并成一个批量请求,减少对下游服务器的调用频率
  2. 下游服务返回批量结果后,按需拆分返回上游

优点:减少对下游服务的压力和网络延时
缺点:会相应提升一点上游接口的响应时间

public List<Response> fetchBatch(List<String> params) {
    return fetchFromDownstreamInBatch(params);
}

5.限流与降级

场景:下游服务的响应时间不可控,但是上游不能因为下游延迟而受到全面的影响

策略:

  1. 实现限流:对上游接口的请求频率进行限制,避免过载调用下游服务。
  2. 实现降级:在下游服务不可用或者响应超时时,提供降级数据(如缓存,默认值或者预估数据),也就是所谓的兜底数据

优点:提升系统的稳定性和可用性

private Response getDataWithFallback(String param) {
    try {
        return fetchFromDownstream(param);
    } catch (TimeoutException e) {
        return getFallbackData(param);
    }
}

6.减少数据传输

场景:下游返回的数据量较大,接口只需要少部分数据

策略:

  1. 在调用下游服务时,使用过滤参数请求所需数据。
  2. 对下游服务返回的数据进行压缩、分页等优化。

优点:减少数据传输时间,降低网络开销

private Response fetchPartialData(String param) {
    return fetchFromDownstreamWithFilter (param, "fields = neededField");
}

7.超时与重试机制

场景:下游服务偶发性响应慢或失败

策略:

  1. 为下游调用服务设置合适的超时与重试时间
  2. 对短暂性或者偶发性的事故进行有限的重试机会

优点:减少因偶发性延迟导致的请求失败

private Response fetchDataWithRetry(String param) {
    int retries = 3;
    while (retries-- > 0) {
        try {
            return fetchFromDownstream(param);
        } catch (TimeoutException e) {
            if (retries == 0) throw e; // 重试结束仍失败
        }
    }    
}

8.使用反向代理或者网关优化

场景:下游服务响应速度与其负载相关

策略:

  1. 在下游服务前部署反向代理(NGINX)
  2. 实现请求路由、负载均衡和静态资源缓存

优点:提升下游服务的并发处理能力和响应时间

9.数据预加载与预计算

场景:上游接口的数据可以提前预测

策略:

  1. 周期性地调用下游接口,将结果缓存在上游
  2. 当上游接口被调用时,直接返回预加载的数据

优点:避免实时依赖下游服务。

10.组合以上的策略

在复杂的场景下,可以结合多个优化策略:

  • 缓存 + 异步调用:减少重复请求并提升吞吐量
  • 并行调用 + 降级:依赖多个下游服务时,确保部分部分服务器不会影响整体的结果
  • 批量化 + 限流:降低下游服务的压力

爱跑步的猕猴桃
1 声望0 粉丝