SpringBoot + 网关请求聚合 + 并行调用优化:多个微服务接口合并为一次响应,减少 RTT
引言:一次性能优化的启示
我们的移动端 App 首页加载速度一直被用户吐槽。经过排查发现,首页需要调用 7 个微服务接口,每个接口平均耗时 100ms,串行调用导致总耗时高达 700ms。
用户体验极差,用户等待时间过长,转化率大幅下降。
通过引入网关请求聚合 + 并行调用优化,我们将首页加载时间从 700ms 降低到 150ms,性能提升 4.6 倍!
今天,我就来分享这个优化方案。
一、问题分析:为什么需要请求聚合?
1.1 传统串行调用的问题
┌─────────────────────────────────────────────────────────────┐
│ 传统串行调用模式(问题) │
├─────────────────────────────────────────────────────────────┤
│ │
│ 客户端 │
│ │ │
│ │ 1. 请求用户信息 (100ms) │
│ ├───────────────────────────────────────────────────────>│
│ │ │
│ │ 2. 请求订单信息 (100ms) │
│ │ <───────────────────────────────────────────────────────│
│ │ │
│ │ 3. 请求商品信息 (100ms) │
│ ├───────────────────────────────────────────────────────>│
│ │ │
│ │ 4. 请求优惠券信息 (100ms) │
│ │ <───────────────────────────────────────────────────────│
│ │ │
│ │ 5. 请求推荐信息 (100ms) │
│ ├───────────────────────────────────────────────────────>│
│ │ │
│ │ 6. 请求广告信息 (100ms) │
│ │ <───────────────────────────────────────────────────────│
│ │ │
│ │ 7. 请求配置信息 (100ms) │
│ ├───────────────────────────────────────────────────────>│
│ │ │
│ │ │
│ ▼ │
│ 总耗时:700ms (7 × 100ms) │
│ 问题: │
│ - RTT(往返时间)累积 │
│ - 串行调用,无法并行 │
│ - 客户端需要多次请求 │
│ - 网络开销大 │
│ │
└─────────────────────────────────────────────────────────────┘
1.2 网关聚合的优势
┌─────────────────────────────────────────────────────────────┐
│ 网关聚合模式(优化) │
├─────────────────────────────────────────────────────────────┤
│ │
│ 客户端 │
│ │ │
│ │ 1. 一次请求聚合接口 │
│ ├───────────────────────────────────────────────────────>│
│ │ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 网关聚合服务 │ │
│ │ │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ 用户服务 │ │ 订单服务 │ │ 商品服务 │ │ │
│ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │
│ │ │ │ │ │ │
│ │ │ 2. 并行调用 (100ms) │ │
│ │ └────────────┼────────────┘ │ │
│ │ │ │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ 优惠券 │ │ 推荐服务 │ │ 广告服务 │ │ │
│ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │
│ │ │ │ │ │ │
│ │ └────────────┼────────────┘ │ │
│ │ │ │ │
│ │ ┌─────────┐ │ │
│ │ │ 配置服务 │ │ │
│ │ └────┬────┘ │ │
│ │ │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ 3. 聚合响应 │ │
│ │ <───────────────────────────────────────────────────────│
│ │ │
│ ▼ │
│ 总耗时:150ms (100ms + 50ms聚合) │
│ 优势: │
│ - 减少RTT:从7次减少到1次 │
│ - 并行调用:7个服务同时调用 │
│ - 客户端只需1次请求 │
│ - 网络开销大幅减少 │
│ │
└─────────────────────────────────────────────────────────────┘
1.3 性能对比
| 指标 | 串行调用 | 网关聚合 | 提升 |
|---|---|---|---|
| 请求次数 | 7次 | 1次 | 减少 85.7% |
| 总耗时 | 700ms | 150ms | 提升 78.6% |
| 网络开销 | 高 | 低 | 大幅降低 |
| 客户端复杂度 | 高 | 低 | 大幅简化 |
二、网关聚合架构设计
2.1 整体架构
┌─────────────────────────────────────────────────────────────────────┐
│ 网关聚合架构设计 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────────────────────────────┐ │
│ │ 客户端 │ │ API 网关 │ │
│ │ (Mobile) │───>│ ┌─────────────────────────────┐ │ │
│ └─────────────┘ │ │ 网关聚合服务 │ │ │
│ │ │ ┌─────────────────────┐ │ │ │
│ │ │ │ 请求聚合器 │ │ │ │
│ │ │ │ - 并行调用 │ │ │ │
│ │ │ │ - 结果聚合 │ │ │ │
│ │ │ │ - 异常处理 │ │ │ │
│ │ │ └─────────────────────┘ │ │ │
│ │ └─────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌─────────────────────────────┐ │ │
│ │ │ 微服务集群 │ │ │
│ │ │ ┌───┐ ┌───┐ ┌───┐ │ │ │
│ │ │ │用户│ │订单│ │商品│ │ │ │
│ │ │ └───┘ └───┘ └───┘ │ │ │
│ │ │ ┌───┐ ┌───┐ ┌───┐ │ │ │
│ │ │ │优惠券│ │推荐│ │广告│ │ │ │
│ │ │ └───┘ └───┘ └───┘ │ │ │
│ │ │ ┌───┐ │ │ │
│ │ │ │配置│ │ │ │
│ │ │ └───┘ │ │ │
│ │ └─────────────────────────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────────────┐ │ │
│ │ │ 缓存层 │ │ │
│ │ │ ┌─────────────────────┐ │ │ │
│ │ │ │ Redis / Caffeine │ │ │ │
│ │ │ └─────────────────────┘ │ │ │
│ │ └─────────────────────────────┘ │ │
│ └─────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
2.2 核心组件
┌─────────────────────────────────────────────────────────────┐
│ 核心组件设计 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 请求聚合器 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ 并行调用 │ │ 结果聚合 │ │ 超时控制 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 缓存策略 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ 多级缓存 │ │ 缓存预热 │ │ 缓存更新 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 容错机制 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ 熔断降级 │ │ 重试机制 │ │ 限流保护 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
三、Spring Boot 实现网关聚合
3.1 项目依赖
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Starter Data Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- Spring Boot Starter Cache -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- Caffeine Cache -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<!-- Resilience4j -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>2.1.0</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- FastJSON -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.40</version>
</dependency>
</dependencies>
3.2 聚合请求定义
@Data
@Builder
public class AggregationRequest {
private String userId;
private String deviceId;
private String platform;
private String version;
private Map<String, Object> params;
}
3.3 聚合响应定义
@Data
@Builder
public class AggregationResponse {
private UserInfo userInfo;
private List<OrderInfo> orders;
private List<ProductInfo> products;
private List<CouponInfo> coupons;
private List<RecommendInfo> recommends;
private List<AdInfo> ads;
private ConfigInfo config;
private long totalDuration; // 总耗时
private Map<String, Long> serviceDurations; // 各服务耗时
}
3.4 微服务客户端接口
public interface MicroServiceClient {
/**
* 获取用户信息
*/
CompletableFuture<UserInfo> getUserInfo(String userId);
/**
* 获取订单信息
*/
CompletableFuture<List<OrderInfo>> getOrders(String userId);
/**
* 获取商品信息
*/
CompletableFuture<List<ProductInfo>> getProducts(String userId);
/**
* 获取优惠券信息
*/
CompletableFuture<List<CouponInfo>> getCoupons(String userId);
/**
* 获取推荐信息
*/
CompletableFuture<List<RecommendInfo>> getRecommends(String userId);
/**
* 获取广告信息
*/
CompletableFuture<List<AdInfo>> getAds(String userId, String platform);
/**
* 获取配置信息
*/
CompletableFuture<ConfigInfo> getConfig(String platform, String version);
}
3.5 网关聚合服务
@Service
@Slf4j
public class AggregationService {
@Autowired
private MicroServiceClient microServiceClient;
@Autowired
private CacheManager cacheManager;
@Autowired
private AggregationMetrics metrics;
private static final long TIMEOUT_MS = 5000;
/**
* 聚合请求
*/
public AggregationResponse aggregate(AggregationRequest request) {
long startTime = System.currentTimeMillis();
log.info("开始聚合请求: userId={}", request.getUserId());
try {
// 并行调用所有微服务
CompletableFuture<UserInfo> userFuture = microServiceClient.getUserInfo(request.getUserId());
CompletableFuture<List<OrderInfo>> ordersFuture = microServiceClient.getOrders(request.getUserId());
CompletableFuture<List<ProductInfo>> productsFuture = microServiceClient.getProducts(request.getUserId());
CompletableFuture<List<CouponInfo>> couponsFuture = microServiceClient.getCoupons(request.getUserId());
CompletableFuture<List<RecommendInfo>> recommendsFuture = microServiceClient.getRecommends(request.getUserId());
CompletableFuture<List<AdInfo>> adsFuture = microServiceClient.getAds(request.getUserId(), request.getPlatform());
CompletableFuture<ConfigInfo> configFuture = microServiceClient.getConfig(request.getPlatform(), request.getVersion());
// 等待所有任务完成(带超时)
CompletableFuture<Void> allFutures = CompletableFuture.allOf(
userFuture, ordersFuture, productsFuture,
couponsFuture, recommendsFuture, adsFuture, configFuture
);
// 设置超时
allFutures.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
// 聚合结果
AggregationResponse response = AggregationResponse.builder()
.userInfo(userFuture.get())
.orders(ordersFuture.get())
.products(productsFuture.get())
.coupons(couponsFuture.get())
.recommends(recommendsFuture.get())
.ads(adsFuture.get())
.config(configFuture.get())
.build();
// 记录耗时
long duration = System.currentTimeMillis() - startTime;
response.setTotalDuration(duration);
// 记录指标
metrics.recordAggregationSuccess(duration);
log.info("聚合请求完成: userId={}, 耗时={}ms", request.getUserId(), duration);
return response;
} catch (TimeoutException e) {
log.error("聚合请求超时: userId={}", request.getUserId(), e);
metrics.recordAggregationTimeout();
throw new AggregationException("聚合请求超时", e);
} catch (Exception e) {
log.error("聚合请求失败: userId={}", request.getUserId(), e);
metrics.recordAggregationFailure();
throw new AggregationException("聚合请求失败", e);
}
}
/**
* 部分聚合(只调用部分服务)
*/
public AggregationResponse partialAggregate(AggregationRequest request, List<String> services) {
long startTime = System.currentTimeMillis();
log.info("开始部分聚合请求: userId={}, services={}", request.getUserId(), services);
try {
List<CompletableFuture<?>> futures = new ArrayList<>();
AggregationResponse.AggregationResponseBuilder builder = AggregationResponse.builder();
// 根据服务列表并行调用
for (String service : services) {
switch (service) {
case "user":
CompletableFuture<UserInfo> userFuture = microServiceClient.getUserInfo(request.getUserId());
futures.add(userFuture);
builder.userInfo(userFuture.get());
break;
case "orders":
CompletableFuture<List<OrderInfo>> ordersFuture = microServiceClient.getOrders(request.getUserId());
futures.add(ordersFuture);
builder.orders(ordersFuture.get());
break;
// ... 其他服务
}
}
// 等待所有任务完成
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
AggregationResponse response = builder.build();
long duration = System.currentTimeMillis() - startTime;
response.setTotalDuration(duration);
log.info("部分聚合请求完成: userId={}, 耗时={}ms", request.getUserId(), duration);
return response;
} catch (Exception e) {
log.error("部分聚合请求失败: userId={}", request.getUserId(), e);
throw new AggregationException("部分聚合请求失败", e);
}
}
}
3.6 微服务客户端实现
@Service
@Slf4j
public class MicroServiceClientImpl implements MicroServiceClient {
@Autowired
private RestTemplate restTemplate;
@Autowired
private CacheManager cacheManager;
private static final String USER_SERVICE_URL = "http://localhost:8081";
private static final String ORDER_SERVICE_URL = "http://localhost:8082";
private static final String PRODUCT_SERVICE_URL = "http://localhost:8083";
@Override
public CompletableFuture<UserInfo> getUserInfo(String userId) {
return CompletableFuture.supplyAsync(() -> {
// 先查缓存
Cache cache = cacheManager.getCache("userInfo");
UserInfo cached = cache.get(userId, UserInfo.class);
if (cached != null) {
log.debug("用户信息命中缓存: userId={}", userId);
return cached;
}
// 调用服务
long startTime = System.currentTimeMillis();
UserInfo userInfo = restTemplate.getForObject(
USER_SERVICE_URL + "/api/user/" + userId,
UserInfo.class
);
long duration = System.currentTimeMillis() - startTime;
log.info("调用用户服务: userId={}, 耗时={}ms", userId, duration);
// 写入缓存
cache.put(userId, userInfo);
return userInfo;
});
}
@Override
public CompletableFuture<List<OrderInfo>> getOrders(String userId) {
return CompletableFuture.supplyAsync(() -> {
// 先查缓存
Cache cache = cacheManager.getCache("orders");
List<OrderInfo> cached = cache.get(userId, List.class);
if (cached != null) {
log.debug("订单信息命中缓存: userId={}", userId);
return cached;
}
// 调用服务
long startTime = System.currentTimeMillis();
OrderInfo[] orders = restTemplate.getForObject(
ORDER_SERVICE_URL + "/api/order/user/" + userId,
OrderInfo[].class
);
long duration = System.currentTimeMillis() - startTime;
log.info("调用订单服务: userId={}, 耗时={}ms", userId, duration);
List<OrderInfo> orderList = Arrays.asList(orders);
// 写入缓存
cache.put(userId, orderList);
return orderList;
});
}
// ... 其他服务实现类似
}
3.7 聚合控制器
@RestController
@RequestMapping("/api/aggregation")
@Slf4j
public class AggregationController {
@Autowired
private AggregationService aggregationService;
/**
* 全量聚合
*/
@PostMapping("/full")
public Result<AggregationResponse> fullAggregation(@RequestBody AggregationRequest request) {
log.info("收到全量聚合请求: userId={}", request.getUserId());
AggregationResponse response = aggregationService.aggregate(request);
return Result.success(response);
}
/**
* 部分聚合
*/
@PostMapping("/partial")
public Result<AggregationResponse> partialAggregation(
@RequestBody AggregationRequest request,
@RequestParam List<String> services) {
log.info("收到部分聚合请求: userId={}, services={}", request.getUserId(), services);
AggregationResponse response = aggregationService.partialAggregate(request, services);
return Result.success(response);
}
/**
* 用户信息聚合
*/
@GetMapping("/user/{userId}")
public Result<AggregationResponse> userAggregation(@PathVariable String userId) {
log.info("收到用户聚合请求: userId={}", userId);
AggregationRequest request = AggregationRequest.builder()
.userId(userId)
.build();
AggregationResponse response = aggregationService.aggregate(request);
return Result.success(response);
}
}
四、性能优化:从可用到高效
4.1 多级缓存
@Service
@Slf4j
public class MultiLevelCacheService {
@Autowired
private CacheManager cacheManager;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
private static final String REDIS_KEY_PREFIX = "aggregation:";
/**
* 获取缓存(多级)
*/
public <T> T get(String key, String cacheName, Class<T> type) {
// L1: Caffeine 本地缓存
Cache localCache = cacheManager.getCache(cacheName);
T cached = localCache.get(key, type);
if (cached != null) {
log.debug("L1缓存命中: key={}", key);
return cached;
}
// L2: Redis 分布式缓存
String redisKey = REDIS_KEY_PREFIX + cacheName + ":" + key;
Object redisValue = redisTemplate.opsForValue().get(redisKey);
if (redisValue != null) {
log.debug("L2缓存命中: key={}", key);
// 回写L1缓存
localCache.put(key, redisValue);
return (T) redisValue;
}
return null;
}
/**
* 设置缓存(多级)
*/
public void set(String key, String cacheName, Object value, long ttl) {
// 写入L1缓存
Cache localCache = cacheManager.getCache(cacheName);
localCache.put(key, value);
// 写入L2缓存
String redisKey = REDIS_KEY_PREFIX + cacheName + ":" + key;
redisTemplate.opsForValue().set(redisKey, value, ttl, TimeUnit.SECONDS);
}
}
4.2 熔断降级
@Service
@Slf4j
public class CircuitBreakerService {
private final CircuitBreaker circuitBreaker;
private final RestTemplate restTemplate;
public CircuitBreakerService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
// 配置熔断器
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
.failureRateThreshold(50) // 失败率阈值50%
.waitDurationInOpenState(Duration.ofSeconds(30)) // 熔断30秒
.permittedNumberOfCallsInHalfOpenState(3) // 半开状态允许3次调用
.slidingWindowSize(10) // 滑动窗口10次
.build();
this.circuitBreaker = CircuitBreaker.of("microService", config);
}
/**
* 带熔断的调用
*/
public <T> T callWithCircuitBreaker(String url, Class<T> responseType) {
Supplier<T> supplier = CircuitBreaker.decorateSupplier(
circuitBreaker,
() -> restTemplate.getForObject(url, responseType)
);
try {
return supplier.get();
} catch (CallNotPermittedException e) {
log.error("熔断器打开,调用被拒绝: url={}", url);
throw new ServiceUnavailableException("服务暂时不可用");
} catch (Exception e) {
log.error("服务调用失败: url={}", url, e);
throw e;
}
}
}
4.3 异步线程池优化
@Configuration
public class AsyncConfig {
@Bean("aggregationExecutor")
public Executor aggregationExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数
executor.setCorePoolSize(10);
// 最大线程数
executor.setMaxPoolSize(50);
// 队列容量
executor.setQueueCapacity(100);
// 线程名前缀
executor.setThreadNamePrefix("aggregation-");
// 拒绝策略:调用者运行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 等待所有任务完成后再关闭
executor.setWaitForTasksToCompleteOnShutdown(true);
// 等待时间
executor.setAwaitTerminationSeconds(60);
executor.initialize();
return executor;
}
}
五、监控告警:让性能可视化
5.1 指标收集
@Component
public class AggregationMetrics {
private final MeterRegistry meterRegistry;
private Counter successCounter;
private Counter failureCounter;
private Counter timeoutCounter;
private Timer aggregationTimer;
@PostConstruct
public void init() {
successCounter = Counter.builder("aggregation.success")
.description("聚合成功次数")
.register(meterRegistry);
failureCounter = Counter.builder("aggregation.failure")
.description("聚合失败次数")
.register(meterRegistry);
timeoutCounter = Counter.builder("aggregation.timeout")
.description("聚合超时次数")
.register(meterRegistry);
aggregationTimer = Timer.builder("aggregation.duration")
.description("聚合耗时")
.register(meterRegistry);
}
public void recordAggregationSuccess(long durationMs) {
successCounter.increment();
aggregationTimer.record(durationMs, TimeUnit.MILLISECONDS);
}
public void recordAggregationFailure() {
failureCounter.increment();
}
public void recordAggregationTimeout() {
timeoutCounter.increment();
}
}
5.2 性能监控
@Aspect
@Component
@Slf4j
public class AggregationMonitorAspect {
@Autowired
private AggregationMetrics metrics;
@Around("@annotation(com.example.demo.annotation.AggregationMonitor)")
public Object monitor(ProceedingJoinPoint joinPoint) throws Throwable {
String methodName = joinPoint.getSignature().getName();
long startTime = System.currentTimeMillis();
try {
Object result = joinPoint.proceed();
long duration = System.currentTimeMillis() - startTime;
log.info("聚合方法执行: method={}, duration={}ms", methodName, duration);
return result;
} catch (Exception e) {
log.error("聚合方法执行失败: method={}", methodName, e);
throw e;
}
}
}
六、最佳实践
6.1 聚合策略
| 策略 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 全量聚合 | 首页加载 | 一次获取所有数据 | 部分服务故障影响整体 |
| 部分聚合 | 按需加载 | 灵活可控 | 需要多次请求 |
| 增量聚合 | 数据更新频繁 | 减少数据传输 | 需要客户端维护状态 |
6.2 超时设置
// 不同场景的超时设置
public class TimeoutConfig {
// 首页聚合:500ms(用户体验优先)
public static final long HOME_PAGE_TIMEOUT = 500;
// 详情页聚合:1000ms(数据完整性优先)
public static final long DETAIL_PAGE_TIMEOUT = 1000;
// 后台管理:3000ms(数据准确性优先)
public static final long ADMIN_PAGE_TIMEOUT = 3000;
}
6.3 降级策略
@Service
public class FallbackService {
/**
* 用户信息降级
*/
public UserInfo getUserInfoFallback(String userId) {
return UserInfo.builder()
.userId(userId)
.nickname("游客")
.avatar("default.png")
.build();
}
/**
* 推荐信息降级
*/
public List<RecommendInfo> getRecommendFallback() {
return Collections.emptyList();
}
/**
* 广告信息降级
*/
public List<AdInfo> getAdFallback() {
return Collections.emptyList();
}
}
七、总结
网关请求聚合 + 并行调用优化是提升系统性能的有效手段。
核心要点:
- 减少RTT:从多次请求减少到一次请求
- 并行调用:充分利用网络带宽和服务器资源
- 多级缓存:L1本地缓存 + L2分布式缓存
- 熔断降级:保证系统稳定性
- 性能监控:实时监控聚合性能
性能提升:
- 请求次数减少 85%+
- 总耗时降低 70%+
- 用户体验显著提升
如果本文对你有帮助,欢迎关注「服务端技术精选」公众号,获取更多后端技术干货。
互动题:
- 在你的项目中,如何优化多接口调用的性能?
- 如何设计一个支持动态配置的聚合服务?
- 如何处理聚合服务中的部分失败场景?
欢迎在评论区分享你的想法和经验,我们一起交流学习!
标题:SpringBoot + 网关请求聚合 + 并行调用优化:多个微服务接口合并为一次响应,减少 RTT
作者:jiangyi
地址:http://jiangyi.space/articles/2026/03/10/1772952110056.html
公众号:服务端技术精选
- 引言:一次性能优化的启示
- 一、问题分析:为什么需要请求聚合?
- 1.1 传统串行调用的问题
- 1.2 网关聚合的优势
- 1.3 性能对比
- 二、网关聚合架构设计
- 2.1 整体架构
- 2.2 核心组件
- 三、Spring Boot 实现网关聚合
- 3.1 项目依赖
- 3.2 聚合请求定义
- 3.3 聚合响应定义
- 3.4 微服务客户端接口
- 3.5 网关聚合服务
- 3.6 微服务客户端实现
- 3.7 聚合控制器
- 四、性能优化:从可用到高效
- 4.1 多级缓存
- 4.2 熔断降级
- 4.3 异步线程池优化
- 五、监控告警:让性能可视化
- 5.1 指标收集
- 5.2 性能监控
- 六、最佳实践
- 6.1 聚合策略
- 6.2 超时设置
- 6.3 降级策略
- 七、总结
评论
0 评论