1. 缓存
场景:下游接口是相对静态或者可以容忍一定程度的延迟更新
策略:
- 在上游接口增加本地缓存(Guava Cache)或者是分布式缓存(Redis)
- 缓存下游接口的数据,进行主动刷新(规定的时间间隔)或者被动刷新(特定事件触发)
- 对于复杂查询,可以缓存查询的聚合结果
优点:减少对下游接口的调用,提高响应时间
缺点:对于时效性要求极高的业务,比如新闻,热点,价格等。对于设置缓存的过期时间及主动刷新的策略需要具体事物具体分析
//伪代码
private Cache<String, Object> cache = CacheBuilder.newBuilder().expireAfterWrite(10,TimeUnit.MINUTES).build();
public Object getCache(String key){
return cache.get(key, () -> fetchFromDownStream(key));
}
2.异步调用
场景:上游接口不要求实时等待下游服务的结果
举例:厨师做菜,等待肉煮熟的时间,我可以先去剥蒜,切菜
策略:
- 使用异步架构(如CompletableFuture,RxJava)实现异步调用。
- 讲下游的业务封装为异步任务,同时返回初步响应,后续通过轮询或回调的方式提供完整的数据
优点:可以提高上游的接口的吞吐量
private CompletableFuture<Response> fetchDataAsync(String param) {
return CompletableFuture.supplyAsync(() -> fetchFromDownStream(params));
}
3.同步调用
场景:上游接口依赖多个下游接口数据的结果
策略:
- 如果上游接口的数据需要从多个下游服务获取,并可以并行调用下游服务。
- 使用并行编程框架(如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.请求批量化
场景:上游接口的请求量高,且对下游服务的调用重复率高。
策略:
- 短时间将多个请求合并成一个批量请求,减少对下游服务器的调用频率
- 下游服务返回批量结果后,按需拆分返回上游
优点:减少对下游服务的压力和网络延时
缺点:会相应提升一点上游接口的响应时间
public List<Response> fetchBatch(List<String> params) {
return fetchFromDownstreamInBatch(params);
}
5.限流与降级
场景:下游服务的响应时间不可控,但是上游不能因为下游延迟而受到全面的影响
策略:
- 实现限流:对上游接口的请求频率进行限制,避免过载调用下游服务。
- 实现降级:在下游服务不可用或者响应超时时,提供降级数据(如缓存,默认值或者预估数据),也就是所谓的兜底数据
优点:提升系统的稳定性和可用性
private Response getDataWithFallback(String param) {
try {
return fetchFromDownstream(param);
} catch (TimeoutException e) {
return getFallbackData(param);
}
}
6.减少数据传输
场景:下游返回的数据量较大,接口只需要少部分数据
策略:
- 在调用下游服务时,使用过滤参数请求所需数据。
- 对下游服务返回的数据进行压缩、分页等优化。
优点:减少数据传输时间,降低网络开销
private Response fetchPartialData(String param) {
return fetchFromDownstreamWithFilter (param, "fields = neededField");
}
7.超时与重试机制
场景:下游服务偶发性响应慢或失败
策略:
- 为下游调用服务设置合适的超时与重试时间
- 对短暂性或者偶发性的事故进行有限的重试机会
优点:减少因偶发性延迟导致的请求失败
private Response fetchDataWithRetry(String param) {
int retries = 3;
while (retries-- > 0) {
try {
return fetchFromDownstream(param);
} catch (TimeoutException e) {
if (retries == 0) throw e; // 重试结束仍失败
}
}
}
8.使用反向代理或者网关优化
场景:下游服务响应速度与其负载相关
策略:
- 在下游服务前部署反向代理(NGINX)
- 实现请求路由、负载均衡和静态资源缓存
优点:提升下游服务的并发处理能力和响应时间
9.数据预加载与预计算
场景:上游接口的数据可以提前预测
策略:
- 周期性地调用下游接口,将结果缓存在上游
- 当上游接口被调用时,直接返回预加载的数据
优点:避免实时依赖下游服务。
10.组合以上的策略
在复杂的场景下,可以结合多个优化策略:
- 缓存 + 异步调用:减少重复请求并提升吞吐量
- 并行调用 + 降级:依赖多个下游服务时,确保部分部分服务器不会影响整体的结果
- 批量化 + 限流:降低下游服务的压力
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。