架构之高并发
引言
“天下武功,唯快不破”
在互联网时代,这一哲学思想在技术架构领域有着深刻的指导意义。高并发架构的核心就是"快":快速响应、快速处理、快速扩展。当系统面临海量用户同时访问时,如何在保证用户体验的同时,确保系统的稳定性和可扩展性,成为每一个架构师必须面对的挑战。
高并发法则强调:通过合理的架构设计和优化策略,使系统能够高效处理大量并发请求,在保证用户体验的同时,确保系统的稳定性和可扩展性。这不仅是对技术能力的考验,更是对架构智慧的检验。
高并发架构的核心理念
什么是高并发?
高并发指的是系统同时处理很多请求的能力。具体表现为:
- 高并发连接:同时维持大量用户连接
- 高并发请求:单位时间内处理大量请求
- 高并发计算:同时处理大量计算任务
- 高并发数据访问:同时处理大量数据读写操作
典型的高并发场景
高并发架构的挑战
高并发架构设计原则
1. 分而治之原则
将大系统拆分为小系统,将复杂问题分解为简单问题。
2. 空间换时间原则
通过增加存储空间来换取处理时间的优化。
// 多级缓存架构示例
@Service
public class MultiLevelCacheService {
// L1缓存:本地内存缓存
private final Cache<String, Object> localCache = Caffeine.newBuilder()
.maximumSize(10000)
.expireAfterWrite(5, TimeUnit.MINUTES)
.build();
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private DatabaseService databaseService;
public <T> T getWithMultiLevelCache(String key, Supplier<T> loader, Duration expireTime) {
// L1: 本地缓存
T value = (T) localCache.getIfPresent(key);
if (value != null) {
return value;
}
// L2: Redis缓存
value = (T) redisTemplate.opsForValue().get(key);
if (value != null) {
localCache.put(key, value);
return value;
}
// L3: 数据库
value = loader.get();
if (value != null) {
// 同时写入L2和L1
redisTemplate.opsForValue().set(key, value, expireTime);
localCache.put(key, value);
}
return value;
}
}
3. 异步处理原则
将同步操作转换为异步操作,提高系统吞吐量。
// 异步处理框架配置
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean("asyncExecutor")
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(1000);
executor.setThreadNamePrefix("Async-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
// 异步服务示例
@Service
public class AsyncOrderService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private MessageQueueService messageQueueService;
@Async("asyncExecutor")
public CompletableFuture<Order> createOrderAsync(CreateOrderRequest request) {
try {
// 1. 创建订单
Order order = createOrder(request);
// 2. 异步发送消息
messageQueueService.sendOrderCreatedMessage(order);
// 3. 异步处理库存
updateInventoryAsync(order);
// 4. 异步发送通知
sendNotificationAsync(order);
return CompletableFuture.completedFuture(order);
} catch (Exception e) {
return CompletableFuture.failedFuture(e);
}
}
@Async("asyncExecutor")
private void updateInventoryAsync(Order order) {
// 异步更新库存
inventoryService.updateInventory(order.getItems());
}
@Async("asyncExecutor")
private void sendNotificationAsync(Order order) {
// 异步发送通知
notificationService.sendOrderNotification(order);
}
}
4. 限流保护原则
通过限流机制保护系统不被突发流量击垮。
// 分布式限流实现
@Component
public class DistributedRateLimiter {
@Autowired
private RedisTemplate<String, String> redisTemplate;
private static final String RATE_LIMIT_KEY = "rate_limit:";
/**
* 令牌桶算法实现
*/
public boolean tryAcquire(String key, int maxPermits, int refillRate, TimeUnit timeUnit) {
String luaScript = """
local key = KEYS[1]
local max_permits = tonumber(ARGV[1])
local refill_rate = tonumber(ARGV[2])
local interval = tonumber(ARGV[3])
local now = tonumber(ARGV[4])
local bucket = redis.call('hmget', key, 'tokens', 'last_refill')
local tokens = tonumber(bucket[1]) or max_permits
local last_refill = tonumber(bucket[2]) or now
-- 计算需要补充的令牌数
local delta = math.floor((now - last_refill) * refill_rate / interval)
tokens = math.min(tokens + delta, max_permits)
-- 尝试获取令牌
if tokens >= 1 then
tokens = tokens - 1
redis.call('hmset', key, 'tokens', tokens, 'last_refill', now)
redis.call('expire', key', 3600)
return 1
else
redis.call('hmset', key, 'tokens', tokens, 'last_refill', now)
redis.call('expire', key, 3600)
return 0
end
""";
long now = System.currentTimeMillis();
long interval = timeUnit.toMillis(1);
Boolean result = redisTemplate.execute(new DefaultRedisScript<>(luaScript, Boolean.class),
Collections.singletonList(RATE_LIMIT_KEY + key),
String.valueOf(maxPermits),
String.valueOf(refillRate),
String.valueOf(interval),
String.valueOf(now));
return Boolean.TRUE.equals(result);
}
}
// 使用示例
@RestController
@RequestMapping("/api")
public class ApiController {
@Autowired
private DistributedRateLimiter rateLimiter;
@GetMapping("/limited-resource")
public ResponseEntity<String> accessLimitedResource(@RequestParam String userId) {
// 每秒最多10个请求
if (!rateLimiter.tryAcquire("user:" + userId, 10, 10, TimeUnit.SECONDS)) {
return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS)
.body("请求过于频繁,请稍后再试");
}
// 处理业务逻辑
return ResponseEntity.ok("success");
}
}
高并发架构核心技术
1. 缓存架构
缓存是高并发系统的第一道防线,能够显著提升系统性能。
多级缓存实现
// 多级缓存管理器
@Component
public class MultiLevelCacheManager {
// L1: 本地缓存 - 最热数据
private final LoadingCache<String, Object> localCache = Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(1, TimeUnit.MINUTES)
.refreshAfterWrite(30, TimeUnit.SECONDS)
.build(this::loadFromRedis);
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private DatabaseService databaseService;
// 缓存穿透保护
private final Set<String> nullValueCache = ConcurrentHashMap.newKeySet();
public Object get(String key) {
// 防止缓存穿透
if (nullValueCache.contains(key)) {
return null;
}
try {
// L1: 本地缓存
Object value = localCache.get(key);
if (value != null) {
return value;
}
} catch (Exception e) {
// 本地缓存异常,降级到Redis
}
// L2: Redis缓存
Object value = redisTemplate.opsForValue().get(key);
if (value != null) {
localCache.put(key, value);
return value;
}
// L3: 数据库
value = databaseService.get(key);
if (value != null) {
// 异步回填缓存,避免缓存击穿
CompletableFuture.runAsync(() -> {
redisTemplate.opsForValue().set(key, value, Duration.ofMinutes(10));
localCache.put(key, value);
});
} else {
// 缓存空值,防止缓存穿透
nullValueCache.add(key);
redisTemplate.opsForValue().set(key, "NULL", Duration.ofMinutes(5));
}
return value;
}
private Object loadFromRedis(String key) {
return redisTemplate.opsForValue().get(key);
}
}
缓存一致性策略
// 缓存一致性管理
@Service
public class CacheConsistencyService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private MessageQueueService messageQueueService;
// 基于消息队列的缓存更新
public void updateDataWithCache(String key, Object newValue) {
// 1. 更新数据库
databaseService.update(key, newValue);
// 2. 发送缓存更新消息
CacheUpdateMessage message = new CacheUpdateMessage(key, newValue);
messageQueueService.sendCacheUpdateMessage(message);
// 3. 删除本地缓存(延迟双删策略)
deleteLocalCache(key);
// 4. 延迟再次删除,处理并发读写问题
CompletableFuture.delayedExecutor(1, TimeUnit.SECONDS).execute(() -> {
deleteLocalCache(key);
});
}
// 监听缓存更新消息
@EventListener
public void handleCacheUpdateMessage(CacheUpdateMessage message) {
String key = message.getKey();
Object value = message.getValue();
// 更新Redis缓存
if (value != null) {
redisTemplate.opsForValue().set(key, value, Duration.ofMinutes(10));
} else {
redisTemplate.delete(key);
}
// 广播删除其他节点的本地缓存
broadcastCacheDelete(key);
}
private void deleteLocalCache(String key) {
// 删除本地缓存实现
}
private void broadcastCacheDelete(String key) {
// 广播缓存删除消息
}
}
2. 异步架构
异步处理能够显著提升系统的并发处理能力和吞吐量。
消息队列架构实现
// 消息队列配置
@Configuration
public class MessageQueueConfig {
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setMessageConverter(new Jackson2JsonMessageConverter());
template.setConfirmCallback((correlationData, ack, cause) -> {
if (!ack) {
// 消息发送失败处理
handleMessageSendFailure(correlationData, cause);
}
});
return template;
}
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setMessageConverter(new Jackson2JsonMessageConverter());
factory.setConcurrentConsumers(5);
factory.setMaxConcurrentConsumers(20);
factory.setPrefetchCount(10);
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
return factory;
}
}
// 异步订单处理服务
@Service
public class AsyncOrderProcessor {
private static final String ORDER_EXCHANGE = "order.exchange";
private static final String ORDER_CREATE_QUEUE = "order.create.queue";
private static final String ORDER_PAY_QUEUE = "order.pay.queue";
private static final String ORDER_SHIP_QUEUE = "order.ship.queue";
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private OrderService orderService;
// 异步创建订单
public void createOrderAsync(CreateOrderRequest request) {
// 1. 基础验证
validateOrderRequest(request);
// 2. 生成订单ID
String orderId = generateOrderId();
// 3. 发送创建订单消息
OrderCreateMessage message = OrderCreateMessage.builder()
.orderId(orderId)
.userId(request.getUserId())
.items(request.getItems())
.totalAmount(request.getTotalAmount())
.timestamp(System.currentTimeMillis())
.build();
rabbitTemplate.convertAndSend(ORDER_EXCHANGE, "order.create", message);
// 4. 立即返回,不等待处理结果
log.info("订单创建消息已发送,订单ID: {}", orderId);
}
// 监听订单创建消息
@RabbitListener(queues = ORDER_CREATE_QUEUE)
public void handleOrderCreate(OrderCreateMessage message, Channel channel,
@Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
try {
log.info("处理订单创建消息: {}", message.getOrderId());
// 1. 创建订单
Order order = orderService.createOrder(message);
// 2. 发送支付消息
OrderPayMessage payMessage = OrderPayMessage.builder()
.orderId(order.getId())
.amount(order.getTotalAmount())
.build();
rabbitTemplate.convertAndSend(ORDER_EXCHANGE, "order.pay", payMessage);
// 3. 确认消息处理成功
channel.basicAck(deliveryTag, false);
} catch (Exception e) {
log.error("处理订单创建消息失败: {}", message.getOrderId(), e);
try {
// 拒绝消息并重新入队
channel.basicNack(deliveryTag, false, true);
} catch (IOException ioException) {
log.error("消息确认失败", ioException);
}
}
}
// 延迟消息处理
public void sendDelayedMessage(String orderId, long delayMillis) {
MessagePostProcessor processor = message -> {
message.getMessageProperties().setDelay((int) delayMillis);
return message;
};
rabbitTemplate.convertAndSend(ORDER_EXCHANGE, "order.delay",
new OrderDelayMessage(orderId), processor);
}
}
事件驱动架构实现
// 事件总线实现
@Component
public class EventBus {
private final Map<Class<?>, List<EventHandler<?>>> handlers = new ConcurrentHashMap<>();
private final ExecutorService executorService = Executors.newFixedThreadPool(10);
// 注册事件处理器
public <T extends DomainEvent> void registerHandler(Class<T> eventType, EventHandler<T> handler) {
handlers.computeIfAbsent(eventType, k -> new CopyOnWriteArrayList<>()).add(handler);
}
// 发布事件
@SuppressWarnings("unchecked")
public <T extends DomainEvent> void publish(T event) {
List<EventHandler<?>> eventHandlers = handlers.get(event.getClass());
if (eventHandlers != null) {
for (EventHandler<?> handler : eventHandlers) {
executorService.submit(() -> {
try {
((EventHandler<T>) handler).handle(event);
} catch (Exception e) {
log.error("事件处理失败: {}", event.getClass().getSimpleName(), e);
}
});
}
}
}
}
// 订单领域事件
public class OrderCreatedEvent implements DomainEvent {
private final String orderId;
private final String userId;
private final BigDecimal amount;
private final LocalDateTime occurredOn;
public OrderCreatedEvent(String orderId, String userId, BigDecimal amount) {
this.orderId = orderId;
this.userId = userId;
this.amount = amount;
this.occurredOn = LocalDateTime.now();
}
}
// 事件处理器
@Component
public class OrderEventHandler implements EventHandler<OrderCreatedEvent> {
@Autowired
private InventoryService inventoryService;
@Autowired
private NotificationService notificationService;
@Autowired
private AnalyticsService analyticsService;
@Override
public void handle(OrderCreatedEvent event) {
log.info("处理订单创建事件: {}", event.getOrderId());
// 1. 更新库存
inventoryService.updateInventory(event.getOrderId());
// 2. 发送通知
notificationService.sendOrderConfirmation(event.getUserId(), event.getOrderId());
// 3. 记录分析数据
analyticsService.recordOrderCreation(event);
// 4. 触发后续业务流程
triggerBusinessProcess(event);
}
private void triggerBusinessProcess(OrderCreatedEvent event) {
// 触发风控检查
if (event.getAmount().compareTo(new BigDecimal("1000")) > 0) {
publishEvent(new RiskCheckRequiredEvent(event.getOrderId(), event.getUserId()));
}
}
}
3. 链路保护架构
在高并发场景下,保护系统链路不被单点故障影响至关重要。
熔断器模式实现
// 熔断器状态枚举
public enum CircuitBreakerState {
CLOSED, // 关闭状态,正常处理请求
OPEN, // 开启状态,拒绝请求
HALF_OPEN // 半开状态,尝试恢复
}
// 熔断器实现
@Component
public class CircuitBreaker {
private final String name;
private final int failureThreshold;
private final int successThreshold;
private final long timeout;
private volatile CircuitBreakerState state = CircuitBreakerState.CLOSED;
private final AtomicInteger failureCount = new AtomicInteger(0);
private final AtomicInteger successCount = new AtomicInteger(0);
private volatile long lastFailureTime = 0;
public CircuitBreaker(String name, int failureThreshold, int successThreshold, long timeout) {
this.name = name;
this.failureThreshold = failureThreshold;
this.successThreshold = successThreshold;
this.timeout = timeout;
}
public <T> T execute(Supplier<T> supplier, Supplier<T> fallback) {
if (state == CircuitBreakerState.OPEN) {
if (System.currentTimeMillis() - lastFailureTime > timeout) {
state = CircuitBreakerState.HALF_OPEN;
successCount.set(0);
} else {
return fallback.get();
}
}
try {
T result = supplier.get();
onSuccess();
return result;
} catch (Exception e) {
onFailure();
return fallback.get();
}
}
private void onSuccess() {
if (state == CircuitBreakerState.HALF_OPEN) {
int successes = successCount.incrementAndGet();
if (successes >= successThreshold) {
state = CircuitBreakerState.CLOSED;
failureCount.set(0);
}
}
}
private void onFailure() {
lastFailureTime = System.currentTimeMillis();
failureCount.incrementAndGet();
if (state == CircuitBreakerState.HALF_OPEN) {
state = CircuitBreakerState.OPEN;
} else if (failureCount.get() >= failureThreshold) {
state = CircuitBreakerState.OPEN;
}
}
public CircuitBreakerState getState() {
return state;
}
}
// 服务熔断代理
@Component
public class CircuitBreakerProxy {
private final Map<String, CircuitBreaker> circuitBreakers = new ConcurrentHashMap<>();
public <T> T executeWithCircuitBreaker(String serviceName, Supplier<T> supplier, Supplier<T> fallback) {
CircuitBreaker circuitBreaker = circuitBreakers.computeIfAbsent(serviceName,
k -> new CircuitBreaker(k, 5, 3, 30000)); // 5次失败熔断,3次成功恢复,30秒超时
return circuitBreaker.execute(supplier, fallback);
}
}
服务降级实现
// 降级策略配置
@Configuration
public class DegradationConfig {
@Bean
public DegradationService degradationService() {
DegradationService service = new DegradationService();
// 配置降级策略
service.addStrategy("userService", new UserServiceDegradationStrategy());
service.addStrategy("orderService", new OrderServiceDegradationStrategy());
service.addStrategy("paymentService", new PaymentServiceDegradationStrategy());
return service;
}
}
// 降级策略接口
public interface DegradationStrategy<T> {
boolean shouldDegrade();
T degrade();
int getPriority();
}
// 用户服务降级策略
@Component
public class UserServiceDegradationStrategy implements DegradationStrategy<UserInfo> {
@Autowired
private MetricsService metricsService;
@Override
public boolean shouldDegrade() {
// 当响应时间超过1秒或错误率超过10%时触发降级
double avgResponseTime = metricsService.getAverageResponseTime("userService");
double errorRate = metricsService.getErrorRate("userService");
return avgResponseTime > 1000 || errorRate > 0.1;
}
@Override
public UserInfo degrade() {
// 返回缓存的用户信息或默认信息
return UserInfo.builder()
.id("default")
.name("默认用户")
.avatar("/default-avatar.png")
.status("offline")
.build();
}
@Override
public int getPriority() {
return 1;
}
}
// 降级服务实现
@Service
public class DegradationService {
private final Map<String, DegradationStrategy<?>> strategies = new ConcurrentHashMap<>();
private final Map<String, Boolean> degradationStatus = new ConcurrentHashMap<>();
public <T> T executeWithDegradation(String serviceName, Supplier<T> normalSupplier) {
DegradationStrategy<T> strategy = (DegradationStrategy<T>) strategies.get(serviceName);
if (strategy != null && shouldDegrade(serviceName, strategy)) {
log.warn("服务 {} 触发降级策略", serviceName);
return strategy.degrade();
}
try {
return normalSupplier.get();
} catch (Exception e) {
log.error("服务 {} 执行异常,尝试降级", serviceName, e);
if (strategy != null) {
return strategy.degrade();
}
throw new RuntimeException("服务不可用", e);
}
}
private <T> boolean shouldDegrade(String serviceName, DegradationStrategy<T> strategy) {
Boolean status = degradationStatus.get(serviceName);
if (status == null) {
status = strategy.shouldDegrade();
degradationStatus.put(serviceName, status);
// 异步更新状态,避免频繁检查
CompletableFuture.runAsync(() -> {
try {
Thread.sleep(5000); // 5秒后重新检查
degradationStatus.remove(serviceName);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
return status;
}
public void addStrategy(String serviceName, DegradationStrategy<?> strategy) {
strategies.put(serviceName, strategy);
}
}
4. 自伸缩架构
自伸缩架构能够根据负载情况自动调整资源,是高并发系统的重要特性。
Kubernetes自动扩缩容配置
# 水平Pod自动扩缩容
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: app-deployment
minReplicas: 3
maxReplicas: 100
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
name: memory
target:
type: Utilization
averageUtilization: 80
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "1000"
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
- type: Pods
value: 2
periodSeconds: 60
selectPolicy: Min
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 50
periodSeconds: 60
- type: Pods
value: 10
periodSeconds: 60
selectPolicy: Max
---
# 垂直Pod自动扩缩容
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: app-vpa
namespace: production
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: app-deployment
updatePolicy:
updateMode: "Auto"
resourcePolicy:
containerPolicies:
- containerName: app
minAllowed:
cpu: 100m
memory: 128Mi
maxAllowed:
cpu: 2
memory: 2Gi
controlledResources: ["cpu", "memory"]
自定义伸缩控制器
// 自定义伸缩控制器
@Component
public class AutoScalingController {
@Autowired
private KubernetesClient kubernetesClient;
@Autowired
private MetricsService metricsService;
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
@PostConstruct
public void init() {
// 启动定时检查任务
scheduler.scheduleWithFixedDelay(this::checkAndScale, 30, 30, TimeUnit.SECONDS);
}
private void checkAndScale() {
try {
// 1. 获取当前指标
double cpuUsage = metricsService.getAverageCpuUsage();
double memoryUsage = metricsService.getAverageMemoryUsage();
double qps = metricsService.getAverageQps();
double responseTime = metricsService.getAverageResponseTime();
// 2. 计算伸缩决策
ScalingDecision decision = calculateScalingDecision(cpuUsage, memoryUsage, qps, responseTime);
// 3. 执行伸缩操作
if (decision.shouldScale()) {
executeScaling(decision);
}
} catch (Exception e) {
log.error("自动伸缩检查失败", e);
}
}
private ScalingDecision calculateScalingDecision(double cpu, double memory, double qps, double responseTime) {
ScalingDecision decision = new ScalingDecision();
// 基于多指标的综合决策
if (cpu > 80 || memory > 85 || qps > 8000 || responseTime > 500) {
decision.setAction(ScalingAction.SCALE_UP);
decision.setReplicas(calculateTargetReplicas(cpu, memory, qps));
decision.setReason(String.format("高负载: CPU=%.1f%%, 内存=%.1f%%, QPS=%.0f, 响应时间=%.0fms",
cpu, memory, qps, responseTime));
} else if (cpu < 20 && memory < 30 && qps < 1000 && responseTime < 200) {
decision.setAction(ScalingAction.SCALE_DOWN);
decision.setReplicas(calculateMinimumReplicas());
decision.setReason(String.format("低负载: CPU=%.1f%%, 内存=%.1f%%, QPS=%.0f, 响应时间=%.0fms",
cpu, memory, qps, responseTime));
}
return decision;
}
private void executeScaling(ScalingDecision decision) {
log.info("执行伸缩操作: {}", decision.getReason());
try {
// 更新Deployment副本数
kubernetesClient.apps().deployments()
.inNamespace("production")
.withName("app-deployment")
.edit(d -> new DeploymentBuilder(d)
.editSpec()
.withReplicas(decision.getReplicas())
.endSpec()
.build());
log.info("伸缩操作完成,目标副本数: {}", decision.getReplicas());
} catch (Exception e) {
log.error("伸缩操作失败", e);
}
}
private int calculateTargetReplicas(double cpu, double memory, double qps) {
// 基于负载计算目标副本数
int cpuBasedReplicas = (int) Math.ceil(cpu / 70.0);
int memoryBasedReplicas = (int) Math.ceil(memory / 75.0);
int qpsBasedReplicas = (int) Math.ceil(qps / 6000.0);
return Math.min(100, Math.max(cpuBasedReplicas, Math.max(memoryBasedReplicas, qpsBasedReplicas)));
}
private int calculateMinimumReplicas() {
// 基于时间计算最小副本数
LocalTime now = LocalTime.now();
if (now.isAfter(LocalTime.of(9, 0)) && now.isBefore(LocalTime.of(22, 0))) {
return 5; // 白天至少5个副本
} else {
return 2; // 夜间至少2个副本
}
}
}
// 伸缩决策类
@Data
class ScalingDecision {
private ScalingAction action = ScalingAction.NO_ACTION;
private int replicas;
private String reason;
public boolean shouldScale() {
return action != ScalingAction.NO_ACTION;
}
}
enum ScalingAction {
NO_ACTION, SCALE_UP, SCALE_DOWN
}
5. 分库分表架构
当数据量达到一定程度时,需要通过分库分表来提升数据库的并发处理能力。
分片策略实现
// 分片策略接口
public interface ShardingStrategy {
String getTargetDataSource(String logicTable, Object shardingValue);
String getTargetTable(String logicTable, Object shardingValue);
}
// 哈希分片策略
@Component
public class HashShardingStrategy implements ShardingStrategy {
private final int databaseCount;
private final int tableCount;
public HashShardingStrategy(@Value("${sharding.database.count}") int databaseCount,
@Value("${sharding.table.count}") int tableCount) {
this.databaseCount = databaseCount;
this.tableCount = tableCount;
}
@Override
public String getTargetDataSource(String logicTable, Object shardingValue) {
int hash = Math.abs(shardingValue.hashCode());
int databaseIndex = hash % databaseCount;
return "ds" + databaseIndex;
}
@Override
public String getTargetTable(String logicTable, Object shardingValue) {
int hash = Math.abs(shardingValue.hashCode());
int tableIndex = (hash / databaseCount) % tableCount;
return logicTable + "_" + tableIndex;
}
}
// 范围分片策略
@Component
public class RangeShardingStrategy implements ShardingStrategy {
private final Map<String, RangeConfig> rangeConfigs = new HashMap<>();
@PostConstruct
public void init() {
// 配置分片范围
rangeConfigs.put("user", new RangeConfig(0, 1000000, 4, 8));
rangeConfigs.put("order", new RangeConfig(0, 5000000, 8, 16));
}
@Override
public String getTargetDataSource(String logicTable, Object shardingValue) {
RangeConfig config = rangeConfigs.get(logicTable);
if (config == null) {
throw new IllegalArgumentException("未找到分片配置: " + logicTable);
}
long value = Long.parseLong(shardingValue.toString());
int databaseIndex = (int) (value / config.getDatabaseRange());
return "ds" + Math.min(databaseIndex, config.getDatabaseCount() - 1);
}
@Override
public String getTargetTable(String logicTable, Object shardingValue) {
RangeConfig config = rangeConfigs.get(logicTable);
if (config == null) {
throw new IllegalArgumentException("未找到分片配置: " + logicTable);
}
long value = Long.parseLong(shardingValue.toString());
int tableIndex = (int) ((value % config.getDatabaseRange()) / config.getTableRange());
return logicTable + "_" + Math.min(tableIndex, config.getTableCount() - 1);
}
}
// 分片配置类
@Data
@AllArgsConstructor
class RangeConfig {
private long minValue;
private long maxValue;
private int databaseCount;
private int tableCount;
public long getDatabaseRange() {
return (maxValue - minValue) / databaseCount;
}
public long getTableRange() {
return getDatabaseRange() / tableCount;
}
}
分布式数据库中间件
// 分片数据源路由
@Component
public class ShardingDataSourceRouter {
@Autowired
private Map<String, DataSource> dataSources;
@Autowired
private ShardingStrategy shardingStrategy;
private final ThreadLocal<ShardingContext> contextHolder = new ThreadLocal<>();
public void setShardingContext(String logicTable, Object shardingValue) {
ShardingContext context = new ShardingContext();
context.setLogicTable(logicTable);
context.setShardingValue(shardingValue);
context.setTargetDataSource(shardingStrategy.getTargetDataSource(logicTable, shardingValue));
context.setTargetTable(shardingStrategy.getTargetTable(logicTable, shardingValue));
contextHolder.set(context);
}
public void clearShardingContext() {
contextHolder.remove();
}
public DataSource getCurrentDataSource() {
ShardingContext context = contextHolder.get();
if (context == null) {
throw new IllegalStateException("分片上下文未设置");
}
return dataSources.get(context.getTargetDataSource());
}
public String getCurrentTable() {
ShardingContext context = contextHolder.get();
if (context == null) {
throw new IllegalStateException("分片上下文未设置");
}
return context.getTargetTable();
}
}
// 分片注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Sharding {
String table();
String parameter() default "";
int parameterIndex() default 0;
}
// 分片切面
@Aspect
@Component
public class ShardingAspect {
@Autowired
private ShardingDataSourceRouter router;
@Around("@annotation(sharding)")
public Object around(ProceedingJoinPoint point, Sharding sharding) throws Throwable {
// 获取分片值
Object shardingValue = getShardingValue(point, sharding);
try {
// 设置分片上下文
router.setShardingContext(sharding.table(), shardingValue);
// 执行目标方法
return point.proceed();
} finally {
// 清理分片上下文
router.clearShardingContext();
}
}
private Object getShardingValue(ProceedingJoinPoint point, Sharding sharding) {
if (!sharding.parameter().isEmpty()) {
// 根据参数名获取
MethodSignature signature = (MethodSignature) point.getSignature();
String[] paramNames = signature.getParameterNames();
Object[] args = point.getArgs();
for (int i = 0; i < paramNames.length; i++) {
if (paramNames[i].equals(sharding.parameter())) {
return args[i];
}
}
}
// 根据参数索引获取
Object[] args = point.getArgs();
if (sharding.parameterIndex() < args.length) {
return args[sharding.parameterIndex()];
}
throw new IllegalArgumentException("无法获取分片参数");
}
}
// 使用示例
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Sharding(table = "user", parameter = "userId")
public User getUserById(String userId) {
return userRepository.findById(userId);
}
@Sharding(table = "user", parameterIndex = 0)
public void createUser(User user) {
userRepository.save(user);
}
}
分布式事务处理
// TCC事务模式实现
@Component
public class TccTransactionManager {
@Autowired
private TccTransactionRepository transactionRepository;
@Autowired
private ApplicationContext applicationContext;
public <T> T execute(TccTransactionDefinition<T> definition) {
String transactionId = generateTransactionId();
TccTransaction transaction = new TccTransaction(transactionId);
try {
// 1. Try阶段
T result = definition.tryExecute();
transaction.setStatus(TccStatus.TRY_SUCCESS);
transactionRepository.save(transaction);
// 2. Confirm阶段
try {
definition.confirm();
transaction.setStatus(TccStatus.CONFIRM_SUCCESS);
transactionRepository.update(transaction);
} catch (Exception e) {
// Confirm失败,进入Cancel阶段
log.error("Confirm阶段失败,开始Cancel", e);
definition.cancel();
transaction.setStatus(TccStatus.CANCEL_SUCCESS);
transactionRepository.update(transaction);
throw new TccException("TCC事务失败", e);
}
return result;
} catch (Exception e) {
transaction.setStatus(TccStatus.TRY_FAILED);
transactionRepository.update(transaction);
throw new TccException("TCC事务Try阶段失败", e);
}
}
}
// TCC事务定义
public interface TccTransactionDefinition<T> {
T tryExecute() throws Exception;
void confirm() throws Exception;
void cancel() throws Exception;
}
// 订单服务TCC实现
@Service
public class OrderTccService {
@Autowired
private TccTransactionManager tccTransactionManager;
@Autowired
private OrderRepository orderRepository;
@Autowired
private InventoryService inventoryService;
@Autowired
private PaymentService paymentService;
public Order createOrderWithTcc(CreateOrderRequest request) {
return tccTransactionManager.execute(new TccTransactionDefinition<Order>() {
private String orderId;
private boolean inventoryReserved = false;
private boolean paymentProcessed = false;
@Override
public Order tryExecute() throws Exception {
// 1. 创建订单(状态为PENDING)
Order order = Order.builder()
.id(generateOrderId())
.userId(request.getUserId())
.items(request.getItems())
.totalAmount(request.getTotalAmount())
.status(OrderStatus.PENDING)
.build();
orderRepository.save(order);
this.orderId = order.getId();
// 2. 预扣库存
boolean reserved = inventoryService.reserveInventory(order.getItems());
if (!reserved) {
throw new BusinessException("库存不足");
}
this.inventoryReserved = true;
// 3. 预扣款
boolean paymentReserved = paymentService.reservePayment(order.getUserId(), order.getTotalAmount());
if (!paymentReserved) {
throw new BusinessException("余额不足");
}
this.paymentProcessed = true;
return order;
}
@Override
public void confirm() throws Exception {
// 1. 确认订单
Order order = orderRepository.findById(orderId)
.orElseThrow(() -> new BusinessException("订单不存在"));
order.setStatus(OrderStatus.CONFIRMED);
orderRepository.update(order);
// 2. 确认库存扣减
inventoryService.confirmInventoryReservation(order.getItems());
// 3. 确认支付
paymentService.confirmPayment(order.getUserId(), order.getTotalAmount());
}
@Override
public void cancel() throws Exception {
// 1. 取消订单
if (orderId != null) {
Order order = orderRepository.findById(orderId)
.orElse(null);
if (order != null) {
order.setStatus(OrderStatus.CANCELLED);
orderRepository.update(order);
}
}
// 2. 释放库存
if (inventoryReserved) {
inventoryService.releaseInventoryReservation(order.getItems());
}
// 3. 释放支付
if (paymentProcessed) {
paymentService.releasePaymentReservation(order.getUserId(), order.getTotalAmount());
}
}
});
}
}
高并发架构最佳实践
1. 性能优化策略
// 连接池优化配置
@Configuration
public class ConnectionPoolConfig {
@Bean
@ConfigurationProperties("spring.datasource.hikari")
public HikariConfig hikariConfig() {
HikariConfig config = new HikariConfig();
// 核心配置
config.setMaximumPoolSize(50); // 最大连接数
config.setMinimumIdle(10); // 最小空闲连接
config.setConnectionTimeout(30000); // 连接超时
config.setIdleTimeout(600000); // 空闲超时
config.setMaxLifetime(1800000); // 连接最大生命周期
config.setLeakDetectionThreshold(60000); // 连接泄露检测
// 性能优化
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "300");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
config.addDataSourceProperty("useServerPrepStmts", "true");
config.addDataSourceProperty("useLocalSessionState", "true");
config.addDataSourceProperty("rewriteBatchedStatements", "true");
config.addDataSourceProperty("cacheResultSetMetadata", "true");
config.addDataSourceProperty("cacheServerConfiguration", "true");
config.addDataSourceProperty("elideSetAutoCommits", "true");
config.addDataSourceProperty("maintainTimeStats", "false");
return config;
}
}
// JVM优化配置
@Component
public class JvmOptimizationConfig {
@PostConstruct
public void optimizeJvm() {
// GC优化
System.setProperty("XX:+UseG1GC", "");
System.setProperty("XX:MaxGCPauseMillis", "200");
System.setProperty("XX:G1HeapRegionSize", "16m");
System.setProperty("XX:G1NewSizePercent", "30");
System.setProperty("XX:G1MaxNewSizePercent", "40");
// 内存优化
System.setProperty("XX:+UseStringDeduplication", "");
System.setProperty("XX:+OptimizeStringConcat", "");
System.setProperty("XX:+UseCompressedOops", "");
System.setProperty("XX:+UseCompressedClassPointers", "");
// 编译优化
System.setProperty("XX:+UseNUMA", "");
System.setProperty("XX:+AggressiveOpts", "");
System.setProperty("XX:+UseFastAccessorMethods", "");
// 监控优化
System.setProperty("XX:+UnlockExperimentalVMOptions", "");
System.setProperty("XX:+UseCGroupMemoryLimitForHeap", "");
System.setProperty("XX:+PrintGC", "");
System.setProperty("XX:+PrintGCDetails", "");
System.setProperty("XX:+PrintGCTimeStamps", "");
}
}
2. 监控告警体系
# Prometheus监控配置
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- "alert_rules.yml"
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
scrape_configs:
# 应用监控
- job_name: 'spring-actuator'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['app1:8080', 'app2:8080', 'app3:8080']
# 数据库监控
- job_name: 'mysql'
static_configs:
- targets: ['mysql-exporter:9104']
# Redis监控
- job_name: 'redis'
static_configs:
- targets: ['redis-exporter:9121']
# 消息队列监控
- job_name: 'rabbitmq'
static_configs:
- targets: ['rabbitmq-exporter:9419']
# 系统监控
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
---
# 告警规则配置
groups:
- name: high_concurrency_alerts
rules:
# 高并发相关告警
- alert: HighQPS
expr: rate(http_requests_total[5m]) > 5000
for: 2m
labels:
severity: warning
annotations:
summary: "QPS过高"
description: "服务 {{ $labels.instance }} QPS达到 {{ $value }}"
- alert: HighResponseTime
expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) > 0.5
for: 3m
labels:
severity: warning
annotations:
summary: "响应时间过长"
description: "服务 {{ $labels.instance }} 95分位响应时间 {{ $value }}s"
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) > 0.05
for: 1m
labels:
severity: critical
annotations:
summary: "错误率过高"
description: "服务 {{ $labels.instance }} 错误率 {{ $value | humanizePercentage }}"
- alert: HighCPUUsage
expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
for: 5m
labels:
severity: warning
annotations:
summary: "CPU使用率过高"
description: "实例 {{ $labels.instance }} CPU使用率 {{ $value }}%"
- alert: HighMemoryUsage
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
for: 5m
labels:
severity: critical
annotations:
summary: "内存使用率过高"
description: "实例 {{ $labels.instance }} 内存使用率 {{ $value }}%"
- alert: DatabaseConnectionPoolLow
expr: hikaricp_connections_active / hikaricp_connections_max > 0.9
for: 2m
labels:
severity: warning
annotations:
summary: "数据库连接池不足"
description: "数据源 {{ $labels.pool }} 连接池使用率 {{ $value | humanizePercentage }}"
- alert: RedisConnectionHigh
expr: redis_connected_clients / redis_config_maxclients > 0.8
for: 3m
labels:
severity: warning
annotations:
summary: "Redis连接数过高"
description: "Redis实例 {{ $labels.instance }} 连接数使用率 {{ $value | humanizePercentage }}"
- alert: MessageQueueBacklog
expr: rabbitmq_queue_messages > 10000
for: 5m
labels:
severity: warning
annotations:
summary: "消息队列积压"
description: "队列 {{ $labels.queue }} 积压消息数 {{ $value }}"
- alert: CircuitBreakerOpen
expr: circuit_breaker_state == 1
for: 1m
labels:
severity: critical
annotations:
summary: "熔断器开启"
description: "服务 {{ $labels.service }} 熔断器已开启"
- alert: CacheHitRateLow
expr: cache_hit_rate < 0.8
for: 10m
labels:
severity: warning
annotations:
summary: "缓存命中率低"
description: "缓存 {{ $labels.cache }} 命中率 {{ $value | humanizePercentage }}"
3. 容量规划与评估
// 容量规划服务
@Service
public class CapacityPlanningService {
@Autowired
private MetricsService metricsService;
@Autowired
private PredictionService predictionService;
// 容量评估
public CapacityAssessment assessCurrentCapacity() {
CapacityAssessment assessment = new CapacityAssessment();
// 1. 收集当前指标
double currentQps = metricsService.getCurrentQps();
double currentCpuUsage = metricsService.getAverageCpuUsage();
double currentMemoryUsage = metricsService.getAverageMemoryUsage();
double currentResponseTime = metricsService.getAverageResponseTime();
// 2. 计算容量利用率
assessment.setQpsUtilization(currentQps / getMaxQps());
assessment.setCpuUtilization(currentCpuUsage / 100);
assessment.setMemoryUtilization(currentMemoryUsage / 100);
assessment.setResponseTimeRatio(currentResponseTime / getTargetResponseTime());
// 3. 评估容量状态
assessment.setOverallStatus(calculateOverallStatus(assessment));
assessment.setBottleneckIdentify(identifyBottleneck(assessment));
return assessment;
}
// 容量预测
public CapacityForecast forecastFutureCapacity(int daysAhead) {
CapacityForecast forecast = new CapacityForecast();
// 1. 获取历史数据
List<MetricData> historicalData = metricsService.getHistoricalMetrics(30);
// 2. 预测未来负载
double predictedQps = predictionService.predictQps(historicalData, daysAhead);
double predictedUserGrowth = predictionService.predictUserGrowth(daysAhead);
// 3. 计算所需容量
int requiredInstances = calculateRequiredInstances(predictedQps);
ResourceRequirement resources = calculateResourceRequirements(predictedQps);
forecast.setPredictedQps(predictedQps);
forecast.setPredictedUserGrowth(predictedUserGrowth);
forecast.setRequiredInstances(requiredInstances);
forecast.setResourceRequirement(resources);
forecast.setRecommendedAction(generateRecommendation(forecast));
return forecast;
}
// 生成容量报告
public CapacityReport generateCapacityReport() {
CapacityReport report = new CapacityReport();
report.setAssessment(assessCurrentCapacity());
report.setForecast(forecastFutureCapacity(30));
report.setOptimizationSuggestions(generateOptimizationSuggestions());
report.setRiskAssessment(assessRisks());
report.setRecommendations(generateRecommendations());
return report;
}
private String identifyBottleneck(CapacityAssessment assessment) {
if (assessment.getCpuUtilization() > 0.8) {
return "CPU是主要瓶颈";
} else if (assessment.getMemoryUtilization() > 0.8) {
return "内存是主要瓶颈";
} else if (assessment.getQpsUtilization() > 0.8) {
return "QPS处理能力不足";
} else if (assessment.getResponseTimeRatio() > 1.5) {
return "响应时间过长";
}
return "系统运行正常";
}
private int calculateRequiredInstances(double predictedQps) {
// 假设单个实例最大处理1000 QPS,保留30%余量
double maxQpsPerInstance = 1000 * 0.7;
return (int) Math.ceil(predictedQps / maxQpsPerInstance);
}
}
高并发架构演进路径
总结
高并发架构是一门综合性的技术艺术,需要在多个维度上进行权衡和优化:
核心原则
- 分而治之:将复杂问题分解为可管理的子问题
- 空间换时间:通过增加存储来提升处理速度
- 异步处理:将同步操作转换为异步以提升吞吐量
- 限流保护:通过限流机制保护系统稳定性
关键技术
- 缓存架构:多级缓存提升访问速度
- 异步架构:消息队列和事件驱动提升并发能力
- 链路保护:熔断降级确保系统可用性
- 自伸缩架构:自动扩缩容适应负载变化
- 分库分表:数据分片支持大规模存储
成功要素
- 监控告警:实时监控系统状态
- 容量规划:提前规划系统容量
- 性能优化:持续优化系统性能
- 故障演练:定期演练故障恢复
高并发架构不是一蹴而就的,需要根据业务发展阶段和实际负载情况,循序渐进地演进和优化。关键在于:在正确的时间,选择正确的技术,解决正确的问题。
高并发架构是一门平衡的艺术,需要在性能、可用性、成本、复杂度之间找到最佳平衡点。通过遵循高并发法则,我们可以构建出既能够处理海量请求,又具备良好用户体验的优秀系统。

1216

被折叠的 条评论
为什么被折叠?



