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%
总耗时700ms150ms提升 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();
    }
}

七、总结

网关请求聚合 + 并行调用优化是提升系统性能的有效手段。

核心要点:

  1. 减少RTT:从多次请求减少到一次请求
  2. 并行调用:充分利用网络带宽和服务器资源
  3. 多级缓存:L1本地缓存 + L2分布式缓存
  4. 熔断降级:保证系统稳定性
  5. 性能监控:实时监控聚合性能

性能提升:

  • 请求次数减少 85%+
  • 总耗时降低 70%+
  • 用户体验显著提升

如果本文对你有帮助,欢迎关注「服务端技术精选」公众号,获取更多后端技术干货。


互动题:

  1. 在你的项目中,如何优化多接口调用的性能?
  2. 如何设计一个支持动态配置的聚合服务?
  3. 如何处理聚合服务中的部分失败场景?

欢迎在评论区分享你的想法和经验,我们一起交流学习!


标题:SpringBoot + 网关请求聚合 + 并行调用优化:多个微服务接口合并为一次响应,减少 RTT
作者:jiangyi
地址:http://jiangyi.space/articles/2026/03/10/1772952110056.html
公众号:服务端技术精选
    评论
    0 评论
avatar

取消