商品详情接口高并发架构:独立资源池与并发控制实战
电商平台的商品详情接口是流量最密集的入口之一。在秒杀、大促等场景下,QPS 可达数万甚至数十万。本文将深入讲解如何设计一个支持高并发访问、具备独立资源池隔离的商品详情 API 接口,涵盖线程池、连接池、缓存、限流等全链路优化方案。
一、商品详情接口的核心挑战
商品详情接口需要聚合多维度数据,天然具有高复杂度和高并发的特点:
表格
| 数据来源 | 说明 | 延迟要求 |
|---|---|---|
| 商品基础信息 | 标题、图片、类目、属性 | < 10ms |
| SKU 价格库存 | 多规格价格、实时库存 | < 20ms |
| 促销信息 | 满减、优惠券、秒杀活动 | < 15ms |
| 评价数据 | 评分、评价数、好评率 | < 30ms |
| 推荐商品 | 关联推荐、猜你喜欢 | < 50ms |
| 物流信息 | 运费模板、预计送达 | < 20ms |
二、整体架构设计
plain
┌─────────────────────────────────────────────────────────────┐
│ 接入层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ CDN 缓存 │ │ 负载均衡 │ │ 限流熔断 │ │
│ │ (静态资源) │ │ (Nginx/ALB) │ │ (Sentinel) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ API 网关层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 鉴权认证 │ │ 请求路由 │ │ 灰度发布 │ │
│ │ 参数校验 │ │ 协议转换 │ │ A/B 测试 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 商品详情服务 (核心层) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 独立资源池隔离架构 │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ 核心资源池 │ │ 普通资源池 │ │ 降级资源池 │ │ │
│ │ │(VIP用户) │ │(普通用户) │ │(过载保护) │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 多级缓存体系 │ │
│ │ L1: 本地 Caffeine 缓存 (命中率 80%) │ │
│ │ L2: 分布式 Redis 缓存 (命中率 15%) │ │
│ │ L3: 数据库 + 异步回源 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 下游服务调用层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 商品服务 │ │ 价格服务 │ │ 库存服务 │ │ 促销服务 │ │
│ │(独立连接池)│ │(独立连接池)│ │(独立连接池)│ │(独立连接池)│ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 评价服务 │ │ 推荐服务 │ │ 物流服务 │ │
│ │(独立连接池)│ │(独立连接池)│ │(独立连接池)│ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────┘三、独立资源池设计:核心实现
3.1 线程池隔离
java
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.ThreadPoolExecutor;/**
* 商品详情接口 - 独立线程池配置
* 核心原则:不同优先级用户、不同业务场景使用独立线程池
*/@Configurationpublic class ThreadPoolConfig {
/**
* 核心用户线程池(VIP/付费用户)
* 特点:核心线程数高,队列小,快速失败或扩容
*/
@Bean("coreUserExecutor")
public ThreadPoolTaskExecutor coreUserExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(32); // 核心线程数
executor.setMaxPoolSize(128); // 最大线程数
executor.setQueueCapacity(50); // 队列容量(小队列,快速扩容)
executor.setThreadNamePrefix("core-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setKeepAliveSeconds(60);
executor.setAllowCoreThreadTimeOut(true);
executor.initialize();
return executor;
}
/**
* 普通用户线程池
* 特点:适中配置,队列缓冲
*/
@Bean("normalUserExecutor")
public ThreadPoolTaskExecutor normalUserExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(16);
executor.setMaxPoolSize(64);
executor.setQueueCapacity(200); // 较大队列,抗突发流量
executor.setThreadNamePrefix("normal-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
executor.setKeepAliveSeconds(60);
executor.initialize();
return executor;
}
/**
* 降级服务线程池(过载保护)
* 特点:资源受限,仅处理核心数据
*/
@Bean("degradeExecutor")
public ThreadPoolTaskExecutor degradeExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(4);
executor.setMaxPoolSize(16);
executor.setQueueCapacity(10); // 极小队列,快速拒绝
executor.setThreadNamePrefix("degrade-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
executor.initialize();
return executor;
}
/**
* 异步数据加载线程池(并行查询下游服务)
* 特点:适合 I/O 密集型任务
*/
@Bean("asyncLoadExecutor")
public ThreadPoolTaskExecutor asyncLoadExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// I/O 密集型:线程数 = CPU 核数 * 2 + 1
int ioThreads = Runtime.getRuntime().availableProcessors() * 2 + 1;
executor.setCorePoolSize(ioThreads);
executor.setMaxPoolSize(ioThreads * 2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("async-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}}3.2 HTTP 连接池隔离
java
import org.apache.http.client.config.RequestConfig;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;import org.springframework.web.client.RestTemplate;/**
* 下游服务独立连接池配置
*/@Configurationpublic class HttpClientPoolConfig {
/**
* 商品服务连接池(核心服务,配置最优)
*/
@Bean("productRestTemplate")
public RestTemplate productRestTemplate() {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(200); // 连接池最大连接数
cm.setDefaultMaxPerRoute(100); // 单路由最大连接数
cm.setValidateAfterInactivity(30000); // 空闲连接验证间隔
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(1000) // 连接超时 1s
.setSocketTimeout(2000) // 读取超时 2s
.setConnectionRequestTimeout(500) // 从连接池获取连接超时 500ms
.build();
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(cm)
.setDefaultRequestConfig(requestConfig)
.setRetryHandler((exception, executionCount, context) -> executionCount <= 2)
.build();
return new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient));
}
/**
* 价格服务连接池(实时性要求高,超时短)
*/
@Bean("priceRestTemplate")
public RestTemplate priceRestTemplate() {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(150);
cm.setDefaultMaxPerRoute(80);
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(500) // 更快超时,快速失败
.setSocketTimeout(1500)
.setConnectionRequestTimeout(300)
.build();
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(cm)
.setDefaultRequestConfig(requestConfig)
.build();
return new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient));
}
/**
* 库存服务连接池(一致性要求高)
*/
@Bean("stockRestTemplate")
public RestTemplate stockRestTemplate() {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(100);
cm.setDefaultMaxPerRoute(50);
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(800)
.setSocketTimeout(3000) // 库存查询可能稍慢
.setConnectionRequestTimeout(500)
.build();
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(cm)
.setDefaultRequestConfig(requestConfig)
.build();
return new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient));
}
/**
* 推荐服务连接池(可降级,超时较长)
*/
@Bean("recommendRestTemplate")
public RestTemplate recommendRestTemplate() {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(80);
cm.setDefaultMaxPerRoute(40);
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(1000)
.setSocketTimeout(5000) // 推荐算法耗时较长
.setConnectionRequestTimeout(500)
.build();
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(cm)
.setDefaultRequestConfig(requestConfig)
.build();
return new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient));
}}3.3 数据库连接池隔离
yaml
# application.ymlspring:
datasource:
# 主库(写操作)
master:
type: com.zaxxer.hikari.HikariDataSource jdbc-url: jdbc:mysql://master-db:3306/product?useSSL=false username: ${DB_USER}
password: ${DB_PASS}
hikari:
pool-name: MasterPool minimum-idle: 10
maximum-pool-size: 50
connection-timeout: 2000
idle-timeout: 300000
max-lifetime: 600000
connection-test-query: SELECT 1
# 从库 1(读操作 - 商品基础信息)
slave1:
type: com.zaxxer.hikari.HikariDataSource jdbc-url: jdbc:mysql://slave1-db:3306/product?useSSL=false username: ${DB_USER}
password: ${DB_PASS}
hikari:
pool-name: Slave1-ProductPool minimum-idle: 5
maximum-pool-size: 30
connection-timeout: 1500
# 从库 2(读操作 - 价格库存)
slave2:
type: com.zaxxer.hikari.HikariDataSource jdbc-url: jdbc:mysql://slave2-db:3306/product?useSSL=false username: ${DB_USER}
password: ${DB_PASS}
hikari:
pool-name: Slave2-PricePool minimum-idle: 5
maximum-pool-size: 30
connection-timeout: 1500四、商品详情服务核心实现,点击测试接口获取key
4.1 并行数据加载(CompletableFuture)
java
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Service;import java.util.concurrent.CompletableFuture;import java.util.concurrent.ThreadPoolExecutor;@Servicepublic class ProductDetailService {
@Autowired
@Qualifier("asyncLoadExecutor")
private ThreadPoolExecutor asyncExecutor;
@Autowired
@Qualifier("productRestTemplate")
private RestTemplate productRestTemplate;
@Autowired
@Qualifier("priceRestTemplate")
private RestTemplate priceRestTemplate;
@Autowired
@Qualifier("stockRestTemplate")
private RestTemplate stockRestTemplate;
@Autowired
@Qualifier("recommendRestTemplate")
private RestTemplate recommendRestTemplate;
@Autowired
private CacheManager cacheManager;
/**
* 获取商品详情(并行加载 + 降级策略)
*/
public ProductDetailVO getProductDetail(Long productId, UserContext user) {
// 1. 多级缓存检查
ProductDetailVO cached = cacheManager.get(productId);
if (cached != null) {
return cached;
}
// 2. 并行加载核心数据(必须成功)
CompletableFuture<ProductBaseInfo> baseFuture = CompletableFuture
.supplyAsync(() -> loadProductBase(productId), asyncExecutor)
.exceptionally(ex -> {
log.error("商品基础信息加载失败: {}", productId, ex);
throw new ProductException("商品信息加载失败");
});
CompletableFuture<PriceInfo> priceFuture = CompletableFuture
.supplyAsync(() -> loadPriceInfo(productId), asyncExecutor)
.exceptionally(ex -> {
log.warn("价格加载失败,使用兜底价格: {}", productId);
return PriceInfo.defaultPrice(productId); // 降级
});
CompletableFuture<StockInfo> stockFuture = CompletableFuture
.supplyAsync(() -> loadStockInfo(productId), asyncExecutor)
.exceptionally(ex -> {
log.warn("库存加载失败,显示有货: {}", productId);
return StockInfo.defaultStock(productId); // 降级
});
// 3. 等待核心数据(超时控制)
CompletableFuture<Void> coreFuture = CompletableFuture
.allOf(baseFuture, priceFuture, stockFuture);
try {
coreFuture.get(150, TimeUnit.MILLISECONDS); // 核心数据 150ms 超时
} catch (Exception e) {
log.error("核心数据加载超时: {}", productId);
throw new ProductException("系统繁忙,请稍后重试");
}
// 4. 异步加载非核心数据(可降级,不阻塞响应)
CompletableFuture<List<ProductVO>> recommendFuture = CompletableFuture
.supplyAsync(() -> loadRecommendations(productId), asyncExecutor)
.orTimeout(100, TimeUnit.MILLISECONDS) // 100ms 超时
.exceptionally(ex -> Collections.emptyList());
CompletableFuture<PromotionInfo> promotionFuture = CompletableFuture
.supplyAsync(() -> loadPromotion(productId), asyncExecutor)
.orTimeout(80, TimeUnit.MILLISECONDS)
.exceptionally(ex -> PromotionInfo.empty());
// 5. 组装结果
ProductDetailVO result = new ProductDetailVO();
result.setBaseInfo(baseFuture.join());
result.setPriceInfo(priceFuture.join());
result.setStockInfo(stockFuture.join());
// 非核心数据异步填充(前端可二次请求)
recommendFuture.thenAccept(result::setRecommendations);
promotionFuture.thenAccept(result::setPromotion);
// 6. 写入缓存
cacheManager.put(productId, result, 60); // 缓存 60 秒
return result;
}
private ProductBaseInfo loadProductBase(Long productId) {
return productRestTemplate.getForObject(
"http://product-service/api/product/{id}",
ProductBaseInfo.class, productId);
}
private PriceInfo loadPriceInfo(Long productId) {
return priceRestTemplate.getForObject(
"http://price-service/api/price/{id}",
PriceInfo.class, productId);
}
private StockInfo loadStockInfo(Long productId) {
return stockRestTemplate.getForObject(
"http://stock-service/api/stock/{id}",
StockInfo.class, productId);
}
private List<ProductVO> loadRecommendations(Long productId) {
return recommendRestTemplate.getForObject(
"http://recommend-service/api/recommend/{id}",
List.class, productId);
}
private PromotionInfo loadPromotion(Long productId) {
// ...
return new PromotionInfo();
}}4.2 多级缓存体系
plain
用户请求
│
▼
┌─────────────────┐
│ L1: Caffeine │ ◀── 本地缓存,命中率 80%,延迟 < 1ms
│ (本地 JVM) │
└────────┬────────┘
│ 未命中
▼
┌─────────────────┐
│ L2: Redis │ ◀── 分布式缓存,命中率 15%,延迟 < 5ms
│ (集群) │
└────────┬────────┘
│ 未命中
▼
┌─────────────────┐
│ L3: 数据库 │ ◀── 最终数据源,异步回源填充缓存
│ + 异步回源 │
└─────────────────┘java
import com.github.benmanes.caffeine.cache.Caffeine;import com.github.benmanes.caffeine.cache.LoadingCache;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;@Componentpublic class CacheManager {
private final LoadingCache<Long, ProductDetailVO> localCache;
private final RedisTemplate<String, ProductDetailVO> redisCache;
public CacheManager(RedisTemplate<String, ProductDetailVO> redisCache) {
this.redisCache = redisCache;
// Caffeine 本地缓存配置
this.localCache = Caffeine.newBuilder()
.maximumSize(10000) // 最大条目数
.expireAfterWrite(30, TimeUnit.SECONDS) // 写入后 30 秒过期
.refreshAfterWrite(20, TimeUnit.SECONDS) // 20 秒后异步刷新
.recordStats() // 开启统计
.build(this::loadFromRedis); // 未命中时从 Redis 加载
}
public ProductDetailVO get(Long productId) {
return localCache.get(productId);
}
public void put(Long productId, ProductDetailVO value, int seconds) {
// 双写:本地缓存 + Redis
localCache.put(productId, value);
redisCache.opsForValue().set(
"product:detail:" + productId,
value,
seconds,
TimeUnit.SECONDS
);
}
/**
* 从 Redis 加载(本地缓存未命中时触发)
*/
private ProductDetailVO loadFromRedis(Long productId) {
String key = "product:detail:" + productId;
ProductDetailVO value = redisCache.opsForValue().get(key);
if (value == null) {
// Redis 也未命中,返回 null,由上层查询数据库
return null;
}
// 延长 Redis 过期时间(滑动窗口)
redisCache.expire(key, 60, TimeUnit.SECONDS);
return value;
}
/**
* 缓存预热(大促前批量加载热点商品)
*/
public void preload(List<Long> hotProductIds) {
for (Long id : hotProductIds) {
localCache.refresh(id); // 触发异步刷新
}
}
/**
* 获取缓存统计
*/
public String getStats() {
return localCache.stats().toString();
}}五、限流、熔断与降级
5.1 Sentinel 限流配置
java
import com.alibaba.csp.sentinel.annotation.SentinelResource;import com.alibaba.csp.sentinel.slots.block.BlockException;import org.springframework.stereotype.Service;@Servicepublic class ProductDetailSentinelService {
/**
* 商品详情接口 - 限流保护
* QPS 限制:核心用户 10000/s,普通用户 5000/s
*/
@SentinelResource(
value = "productDetail",
blockHandler = "handleBlock",
fallback = "handleFallback"
)
public ProductDetailVO getDetail(Long productId, UserContext user) {
// 根据用户类型路由到不同线程池
if (user.isVip()) {
return getDetailWithExecutor(productId, "coreUserExecutor");
}
return getDetailWithExecutor(productId, "normalUserExecutor");
}
/**
* 限流触发时的处理
*/
public ProductDetailVO handleBlock(Long productId, UserContext user, BlockException ex) {
log.warn("接口限流触发: user={}, product={}", user.getUserId(), productId);
// 返回简化版商品信息(缓存兜底)
return getSimplifiedDetail(productId);
}
/**
* 异常降级处理
*/
public ProductDetailVO handleFallback(Long productId, UserContext user, Throwable ex) {
log.error("接口异常降级: user={}, product={}", user.getUserId(), productId, ex);
// 返回静态兜底页面
return ProductDetailVO.staticFallback(productId);
}
private ProductDetailVO getSimplifiedDetail(Long productId) {
// 仅从缓存读取基础信息,不查询下游服务
return cacheManager.get(productId);
}}5.2 熔断器配置(Resilience4j)
java
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;import io.github.resilience4j.timelimiter.annotation.TimeLimiter;import org.springframework.stereotype.Service;import java.util.concurrent.CompletableFuture;@Servicepublic class DownstreamService {
/**
* 价格服务熔断配置
* 失败率 > 50% 且调用次数 > 10 时触发熔断
*/
@CircuitBreaker(
name = "priceService",
fallbackMethod = "priceFallback"
)
@TimeLimiter(name = "priceService")
public CompletableFuture<PriceInfo> getPrice(Long productId) {
return CompletableFuture.supplyAsync(() ->
priceRestTemplate.getForObject(
"http://price-service/api/price/{id}",
PriceInfo.class, productId )
);
}
/**
* 价格服务熔断后的兜底
*/
public CompletableFuture<PriceInfo> priceFallback(Long productId, Exception ex) {
log.warn("价格服务熔断,使用缓存价格: {}", productId);
PriceInfo cached = priceCache.get(productId);
return CompletableFuture.completedFuture(
cached != null ? cached : PriceInfo.defaultPrice(productId)
);
}}六、监控与动态调优
6.1 线程池监控
java
import io.micrometer.core.instrument.Gauge;import io.micrometer.core.instrument.MeterRegistry;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;import java.util.concurrent.ThreadPoolExecutor;@Componentpublic class ThreadPoolMonitor {
@Autowired
private MeterRegistry meterRegistry;
@Autowired
@Qualifier("coreUserExecutor")
private ThreadPoolTaskExecutor coreExecutor;
@Autowired
@Qualifier("normalUserExecutor")
private ThreadPoolTaskExecutor normalExecutor;
@PostConstruct
public void init() {
registerMetrics("core.pool", coreExecutor.getThreadPoolExecutor());
registerMetrics("normal.pool", normalExecutor.getThreadPoolExecutor());
}
private void registerMetrics(String name, ThreadPoolExecutor executor) {
Gauge.builder(name + ".active", executor, ThreadPoolExecutor::getActiveCount)
.description("活跃线程数")
.register(meterRegistry);
Gauge.builder(name + ".queue.size", executor, e -> e.getQueue().size())
.description("队列等待任务数")
.register(meterRegistry);
Gauge.builder(name + ".completed", executor, ThreadPoolExecutor::getCompletedTaskCount)
.description("已完成任务数")
.register(meterRegistry);
Gauge.builder(name + ".rejected", executor, e -> {
// 自定义拒绝计数器
return 0L;
})
.description("拒绝任务数")
.register(meterRegistry);
}}6.2 连接池监控
java
@Componentpublic class ConnectionPoolMonitor {
@Autowired
private HikariDataSource masterDataSource;
@Scheduled(fixedRate = 30000) // 每 30 秒上报
public void report() {
HikariPoolMXBean poolMXBean = masterDataSource.getHikariPoolMXBean();
log.info("连接池状态 - 活跃: {}, 空闲: {}, 等待: {}, 总连接: {}",
poolMXBean.getActiveConnections(),
poolMXBean.getIdleConnections(),
poolMXBean.getThreadsAwaitingConnection(),
poolMXBean.getTotalConnections()
);
}}七、性能压测数据
表格
| 指标 | 优化前 | 优化后 | 提升 |
|---|---|---|---|
| 平均响应时间 | 680ms | 120ms | 82% |
| P99 延迟 | 2500ms | 350ms | 86% |
| 吞吐量(QPS) | 850 | 5200 | 512% |
| 错误率 | 3.2% | 0.05% | 98.4% |
| 下游服务调用次数 | 6 次/请求 | 3.2 次/请求(缓存命中) | 47% |
八、关键设计原则总结
表格
| 原则 | 实现方式 | 效果 |
|---|---|---|
| 资源隔离 | 独立线程池 + 独立连接池 | 避免级联故障,保障核心链路 |
| 并行加载 | CompletableFuture + 自定义线程池 | 将串行延迟转为并行延迟 |
| 多级缓存 | Caffeine + Redis + 异步回源 | 减少 90% 下游调用 |
| 快速失败 | 超时控制 + 熔断降级 | 避免线程长时间阻塞 |
| 限流保护 | Sentinel 滑动窗口限流 | 防止系统过载 |
| 监控驱动 | Micrometer + Prometheus | 实时感知系统状态 |
通过独立资源池的设计,商品详情接口能够在高并发场景下保持稳定、低延迟的响应,同时具备良好的弹性扩展能力和故障隔离能力。