Java学习第29天 - 企业级系统架构与实战

学习目标

掌握企业级系统架构设计方法,学习高并发系统设计模式,深入理解分布式锁与ID生成,掌握系统架构演进路径,学习企业级开发最佳实践。


1. 企业级架构设计

1.1 领域驱动设计(DDD)

DDD核心概念实现:

java 复制代码
// 实体(Entity)- 有唯一标识
@Entity
@Table(name = "t_order")
@Data
@Slf4j
public class Order {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String orderNumber;
    private Long userId;
    private BigDecimal totalAmount;
    private OrderStatus status;
    private Date createTime;
    
    // 领域行为
    public void confirm() {
        if (this.status != OrderStatus.PENDING) {
            throw new IllegalStateException("只有待确认订单才能确认");
        }
        this.status = OrderStatus.CONFIRMED;
        log.info("订单确认: orderNumber={}", this.orderNumber);
    }
    
    public void cancel() {
        if (this.status == OrderStatus.COMPLETED || this.status == OrderStatus.CANCELLED) {
            throw new IllegalStateException("已完成或已取消的订单不能取消");
        }
        this.status = OrderStatus.CANCELLED;
        log.info("订单取消: orderNumber={}", this.orderNumber);
    }
    
    public void pay(BigDecimal amount) {
        if (this.status != OrderStatus.CONFIRMED) {
            throw new IllegalStateException("只有已确认订单才能支付");
        }
        if (amount.compareTo(this.totalAmount) != 0) {
            throw new IllegalArgumentException("支付金额与订单金额不匹配");
        }
        this.status = OrderStatus.PAID;
        log.info("订单支付: orderNumber={}, amount={}", this.orderNumber, amount);
    }
}

// 值对象(Value Object)- 无唯一标识,通过属性值判断相等
@Embeddable
@Data
public class Address {
    
    private String province;
    private String city;
    private String district;
    private String street;
    private String zipCode;
    
    public Address(String province, String city, String district, String street, String zipCode) {
        this.province = province;
        this.city = city;
        this.district = district;
        this.street = street;
        this.zipCode = zipCode;
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Address address = (Address) o;
        return Objects.equals(province, address.province) &&
               Objects.equals(city, address.city) &&
               Objects.equals(district, address.district) &&
               Objects.equals(street, address.street) &&
               Objects.equals(zipCode, address.zipCode);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(province, city, district, street, zipCode);
    }
}

// 聚合根(Aggregate Root)- 聚合的入口
@AggregateRoot
@Entity
@Table(name = "t_order")
@Data
@Slf4j
public class OrderAggregate {
    
    @Id
    private Long id;
    
    private String orderNumber;
    private Long userId;
    
    @Embedded
    private Address shippingAddress;
    
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "order_id")
    private List<OrderItem> items;
    
    private OrderStatus status;
    
    // 聚合内部一致性保证
    public void addItem(OrderItem item) {
        if (this.items == null) {
            this.items = new ArrayList<>();
        }
        
        // 业务规则:订单项不能重复添加
        boolean exists = this.items.stream()
            .anyMatch(i -> i.getProductId().equals(item.getProductId()));
        if (exists) {
            throw new IllegalArgumentException("订单项已存在");
        }
        
        this.items.add(item);
        log.info("添加订单项: orderNumber={}, productId={}", this.orderNumber, item.getProductId());
    }
    
    public void removeItem(Long productId) {
        if (this.items == null || this.items.isEmpty()) {
            throw new IllegalArgumentException("订单项为空");
        }
        
        boolean removed = this.items.removeIf(item -> item.getProductId().equals(productId));
        if (!removed) {
            throw new IllegalArgumentException("订单项不存在");
        }
        
        log.info("移除订单项: orderNumber={}, productId={}", this.orderNumber, productId);
    }
    
    // 计算订单总金额
    public BigDecimal calculateTotal() {
        if (this.items == null || this.items.isEmpty()) {
            return BigDecimal.ZERO;
        }
        return this.items.stream()
            .map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
            .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
}

// 领域服务(Domain Service)- 不属于任何实体的业务逻辑
@Service
@Slf4j
public class OrderDomainService {
    
    @Autowired
    private OrderRepository orderRepository;
    
    @Autowired
    private InventoryService inventoryService;
    
    // 领域服务:处理复杂的业务逻辑
    public Order createOrder(Long userId, List<OrderItem> items, Address shippingAddress) {
        // 1. 验证库存
        for (OrderItem item : items) {
            boolean available = inventoryService.checkAvailability(item.getProductId(), item.getQuantity());
            if (!available) {
                throw new InsufficientInventoryException("库存不足: productId=" + item.getProductId());
            }
        }
        
        // 2. 创建订单
        OrderAggregate order = new OrderAggregate();
        order.setOrderNumber(generateOrderNumber());
        order.setUserId(userId);
        order.setShippingAddress(shippingAddress);
        order.setStatus(OrderStatus.PENDING);
        
        // 3. 添加订单项
        for (OrderItem item : items) {
            order.addItem(item);
        }
        
        // 4. 保存订单
        orderRepository.save(order);
        
        // 5. 扣减库存
        for (OrderItem item : items) {
            inventoryService.deductInventory(item.getProductId(), item.getQuantity());
        }
        
        log.info("创建订单成功: orderNumber={}, userId={}", order.getOrderNumber(), userId);
        return convertToOrder(order);
    }
    
    private String generateOrderNumber() {
        return "ORD" + System.currentTimeMillis() + (int)(Math.random() * 1000);
    }
    
    private Order convertToOrder(OrderAggregate aggregate) {
        // 转换为Order实体
        Order order = new Order();
        order.setId(aggregate.getId());
        order.setOrderNumber(aggregate.getOrderNumber());
        order.setUserId(aggregate.getUserId());
        order.setStatus(aggregate.getStatus());
        return order;
    }
}

// 领域事件(Domain Event)
@Data
@AllArgsConstructor
public class OrderCreatedEvent {
    private String orderNumber;
    private Long userId;
    private BigDecimal totalAmount;
    private Date createTime;
}

// 领域事件发布器
@Component
@Slf4j
public class DomainEventPublisher {
    
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    
    public void publish(DomainEvent event) {
        log.info("发布领域事件: {}", event.getClass().getSimpleName());
        eventPublisher.publishEvent(event);
    }
}

// 领域事件处理器
@Component
@Slf4j
public class OrderEventHandler {
    
    @EventListener
    public void handleOrderCreated(OrderCreatedEvent event) {
        log.info("处理订单创建事件: orderNumber={}", event.getOrderNumber());
        // 发送通知、更新统计等
    }
}

1.2 CQRS(命令查询职责分离)

CQRS实现:

java 复制代码
// 命令(Command)- 写操作
@Data
@AllArgsConstructor
public class CreateOrderCommand {
    private Long userId;
    private List<OrderItemDTO> items;
    private AddressDTO shippingAddress;
}

@Data
@AllArgsConstructor
public class CancelOrderCommand {
    private String orderNumber;
    private String reason;
}

// 命令处理器
@Component
@Slf4j
public class OrderCommandHandler {
    
    @Autowired
    private OrderDomainService orderDomainService;
    
    @Autowired
    private OrderWriteRepository orderWriteRepository;
    
    public void handle(CreateOrderCommand command) {
        // 执行写操作
        Order order = orderDomainService.createOrder(
            command.getUserId(),
            convertToOrderItems(command.getItems()),
            convertToAddress(command.getShippingAddress())
        );
        
        orderWriteRepository.save(order);
        log.info("处理创建订单命令: userId={}", command.getUserId());
    }
    
    public void handle(CancelOrderCommand command) {
        Order order = orderWriteRepository.findByOrderNumber(command.getOrderNumber());
        if (order == null) {
            throw new OrderNotFoundException("订单不存在: " + command.getOrderNumber());
        }
        
        order.cancel();
        orderWriteRepository.save(order);
        log.info("处理取消订单命令: orderNumber={}", command.getOrderNumber());
    }
    
    private List<OrderItem> convertToOrderItems(List<OrderItemDTO> dtos) {
        return dtos.stream()
            .map(dto -> new OrderItem(dto.getProductId(), dto.getQuantity(), dto.getPrice()))
            .collect(Collectors.toList());
    }
    
    private Address convertToAddress(AddressDTO dto) {
        return new Address(dto.getProvince(), dto.getCity(), dto.getDistrict(), 
                          dto.getStreet(), dto.getZipCode());
    }
}

// 查询(Query)- 读操作
@Data
@AllArgsConstructor
public class GetOrderQuery {
    private String orderNumber;
}

@Data
@AllArgsConstructor
public class GetUserOrdersQuery {
    private Long userId;
    private int page;
    private int size;
}

// 查询处理器
@Component
@Slf4j
public class OrderQueryHandler {
    
    @Autowired
    private OrderReadRepository orderReadRepository;
    
    public OrderDTO handle(GetOrderQuery query) {
        OrderReadModel order = orderReadRepository.findByOrderNumber(query.getOrderNumber());
        if (order == null) {
            throw new OrderNotFoundException("订单不存在: " + query.getOrderNumber());
        }
        return convertToDTO(order);
    }
    
    public Page<OrderDTO> handle(GetUserOrdersQuery query) {
        Page<OrderReadModel> orders = orderReadRepository.findByUserId(
            query.getUserId(), 
            PageRequest.of(query.getPage(), query.getSize())
        );
        return orders.map(this::convertToDTO);
    }
    
    private OrderDTO convertToDTO(OrderReadModel model) {
        OrderDTO dto = new OrderDTO();
        dto.setOrderNumber(model.getOrderNumber());
        dto.setUserId(model.getUserId());
        dto.setTotalAmount(model.getTotalAmount());
        dto.setStatus(model.getStatus());
        dto.setCreateTime(model.getCreateTime());
        return dto;
    }
}

// 读写分离的Repository
@Repository
public interface OrderWriteRepository extends JpaRepository<Order, Long> {
    Order findByOrderNumber(String orderNumber);
}

@Repository
public interface OrderReadRepository extends JpaRepository<OrderReadModel, Long> {
    OrderReadModel findByOrderNumber(String orderNumber);
    Page<OrderReadModel> findByUserId(Long userId, Pageable pageable);
}

// 读模型(优化查询)
@Entity
@Table(name = "order_read_view")
@Data
public class OrderReadModel {
    
    @Id
    private Long id;
    private String orderNumber;
    private Long userId;
    private BigDecimal totalAmount;
    private OrderStatus status;
    private Date createTime;
    
    // 只读字段,用于查询优化
    private String userName;
    private String userPhone;
    private int itemCount;
}

1.3 事件驱动架构

事件驱动架构实现:

java 复制代码
// 事件总线
@Component
@Slf4j
public class EventBus {
    
    private final Map<Class<? extends DomainEvent>, List<EventHandler>> handlers = new ConcurrentHashMap<>();
    
    // 注册事件处理器
    public <T extends DomainEvent> void subscribe(Class<T> eventType, EventHandler<T> handler) {
        handlers.computeIfAbsent(eventType, k -> new CopyOnWriteArrayList<>()).add(handler);
        log.info("注册事件处理器: eventType={}, handler={}", eventType.getSimpleName(), handler.getClass().getSimpleName());
    }
    
    // 发布事件
    public <T extends DomainEvent> void publish(T event) {
        List<EventHandler> eventHandlers = handlers.get(event.getClass());
        if (eventHandlers != null) {
            for (EventHandler handler : eventHandlers) {
                try {
                    handler.handle(event);
                } catch (Exception e) {
                    log.error("事件处理失败: event={}, handler={}", event, handler.getClass().getSimpleName(), e);
                }
            }
        }
        log.info("发布事件: {}", event.getClass().getSimpleName());
    }
    
    // 异步发布事件
    public <T extends DomainEvent> void publishAsync(T event) {
        CompletableFuture.runAsync(() -> publish(event));
    }
}

// 事件处理器接口
public interface EventHandler<T extends DomainEvent> {
    void handle(T event);
}

// 订单事件处理器
@Component
@Slf4j
public class OrderEventHandlers {
    
    @Autowired
    private NotificationService notificationService;
    
    @Autowired
    private InventoryService inventoryService;
    
    @Autowired
    private PaymentService paymentService;
    
    @Autowired
    private EventBus eventBus;
    
    @PostConstruct
    public void init() {
        // 注册事件处理器
        eventBus.subscribe(OrderCreatedEvent.class, this::handleOrderCreated);
        eventBus.subscribe(OrderPaidEvent.class, this::handleOrderPaid);
        eventBus.subscribe(OrderCancelledEvent.class, this::handleOrderCancelled);
    }
    
    private void handleOrderCreated(OrderCreatedEvent event) {
        log.info("处理订单创建事件: orderNumber={}", event.getOrderNumber());
        
        // 1. 发送通知
        notificationService.sendOrderCreatedNotification(event.getUserId(), event.getOrderNumber());
        
        // 2. 扣减库存
        // inventoryService.deductInventory(...);
        
        // 3. 触发其他业务逻辑
    }
    
    private void handleOrderPaid(OrderPaidEvent event) {
        log.info("处理订单支付事件: orderNumber={}", event.getOrderNumber());
        
        // 1. 发送支付成功通知
        notificationService.sendPaymentSuccessNotification(event.getUserId(), event.getOrderNumber());
        
        // 2. 更新订单状态
        // orderService.updateOrderStatus(...);
    }
    
    private void handleOrderCancelled(OrderCancelledEvent event) {
        log.info("处理订单取消事件: orderNumber={}", event.getOrderNumber());
        
        // 1. 发送取消通知
        notificationService.sendOrderCancelledNotification(event.getUserId(), event.getOrderNumber());
        
        // 2. 恢复库存
        // inventoryService.restoreInventory(...);
    }
}

// 事件存储
@Repository
public interface EventStore extends JpaRepository<EventEntity, Long> {
    List<EventEntity> findByAggregateIdAndAggregateType(String aggregateId, String aggregateType);
}

@Entity
@Table(name = "event_store")
@Data
public class EventEntity {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String aggregateId;
    private String aggregateType;
    private String eventType;
    
    @Lob
    private String eventData;
    
    private Date occurredOn;
    private int version;
}

2. 高并发系统设计

2.1 限流算法

限流算法实现:

java 复制代码
// 限流器接口
public interface RateLimiter {
    boolean tryAcquire();
    boolean tryAcquire(int permits);
}

// 固定窗口限流
@Component
@Slf4j
public class FixedWindowRateLimiter implements RateLimiter {
    
    private final int limit;
    private final long windowSize; // 窗口大小(毫秒)
    private final AtomicInteger counter = new AtomicInteger(0);
    private volatile long windowStart = System.currentTimeMillis();
    private final Object lock = new Object();
    
    public FixedWindowRateLimiter(int limit, long windowSizeMillis) {
        this.limit = limit;
        this.windowSize = windowSizeMillis;
    }
    
    @Override
    public boolean tryAcquire() {
        return tryAcquire(1);
    }
    
    @Override
    public boolean tryAcquire(int permits) {
        long currentTime = System.currentTimeMillis();
        
        synchronized (lock) {
            // 检查是否进入新窗口
            if (currentTime - windowStart >= windowSize) {
                counter.set(0);
                windowStart = currentTime;
            }
            
            // 检查是否超过限制
            if (counter.get() + permits <= limit) {
                counter.addAndGet(permits);
                return true;
            }
            
            return false;
        }
    }
    
    public int getCurrentCount() {
        return counter.get();
    }
}

// 滑动窗口限流
@Component
@Slf4j
public class SlidingWindowRateLimiter implements RateLimiter {
    
    private final int limit;
    private final long windowSize;
    private final Queue<Long> requests = new ConcurrentLinkedQueue<>();
    
    public SlidingWindowRateLimiter(int limit, long windowSizeMillis) {
        this.limit = limit;
        this.windowSize = windowSizeMillis;
    }
    
    @Override
    public boolean tryAcquire() {
        return tryAcquire(1);
    }
    
    @Override
    public boolean tryAcquire(int permits) {
        long currentTime = System.currentTimeMillis();
        
        // 移除过期的请求
        while (!requests.isEmpty() && currentTime - requests.peek() > windowSize) {
            requests.poll();
        }
        
        // 检查是否超过限制
        if (requests.size() + permits <= limit) {
            for (int i = 0; i < permits; i++) {
                requests.offer(currentTime);
            }
            return true;
        }
        
        return false;
    }
}

// 令牌桶限流
@Component
@Slf4j
public class TokenBucketRateLimiter implements RateLimiter {
    
    private final int capacity; // 桶容量
    private final double refillRate; // 每秒补充的令牌数
    private double tokens; // 当前令牌数
    private long lastRefillTime; // 上次补充时间
    private final Object lock = new Object();
    
    public TokenBucketRateLimiter(int capacity, double refillRate) {
        this.capacity = capacity;
        this.refillRate = refillRate;
        this.tokens = capacity;
        this.lastRefillTime = System.currentTimeMillis();
    }
    
    @Override
    public boolean tryAcquire() {
        return tryAcquire(1);
    }
    
    @Override
    public boolean tryAcquire(int permits) {
        synchronized (lock) {
            refillTokens();
            
            if (tokens >= permits) {
                tokens -= permits;
                return true;
            }
            
            return false;
        }
    }
    
    private void refillTokens() {
        long currentTime = System.currentTimeMillis();
        long elapsed = currentTime - lastRefillTime;
        
        if (elapsed > 0) {
            double tokensToAdd = (elapsed / 1000.0) * refillRate;
            tokens = Math.min(capacity, tokens + tokensToAdd);
            lastRefillTime = currentTime;
        }
    }
}

// 漏桶限流
@Component
@Slf4j
public class LeakyBucketRateLimiter implements RateLimiter {
    
    private final int capacity; // 桶容量
    private final double leakRate; // 每秒漏出的速率
    private double water; // 当前水量
    private long lastLeakTime; // 上次漏水时间
    private final Object lock = new Object();
    
    public LeakyBucketRateLimiter(int capacity, double leakRate) {
        this.capacity = capacity;
        this.leakRate = leakRate;
        this.water = 0;
        this.lastLeakTime = System.currentTimeMillis();
    }
    
    @Override
    public boolean tryAcquire() {
        return tryAcquire(1);
    }
    
    @Override
    public boolean tryAcquire(int permits) {
        synchronized (lock) {
            leakWater();
            
            if (water + permits <= capacity) {
                water += permits;
                return true;
            }
            
            return false;
        }
    }
    
    private void leakWater() {
        long currentTime = System.currentTimeMillis();
        long elapsed = currentTime - lastLeakTime;
        
        if (elapsed > 0) {
            double waterToLeak = (elapsed / 1000.0) * leakRate;
            water = Math.max(0, water - waterToLeak);
            lastLeakTime = currentTime;
        }
    }
}

// 限流注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {
    int limit() default 100;
    long windowSize() default 1000; // 毫秒
    RateLimitType type() default RateLimitType.FIXED_WINDOW;
}

enum RateLimitType {
    FIXED_WINDOW,
    SLIDING_WINDOW,
    TOKEN_BUCKET,
    LEAKY_BUCKET
}

// 限流切面
@Aspect
@Component
@Slf4j
public class RateLimitAspect {
    
    private final Map<String, RateLimiter> limiters = new ConcurrentHashMap<>();
    
    @Around("@annotation(rateLimit)")
    public Object rateLimit(ProceedingJoinPoint joinPoint, RateLimit rateLimit) throws Throwable {
        String key = generateKey(joinPoint);
        RateLimiter limiter = limiters.computeIfAbsent(key, k -> createRateLimiter(rateLimit));
        
        if (!limiter.tryAcquire()) {
            log.warn("请求被限流: key={}", key);
            throw new RateLimitException("请求过于频繁,请稍后重试");
        }
        
        return joinPoint.proceed();
    }
    
    private String generateKey(ProceedingJoinPoint joinPoint) {
        return joinPoint.getSignature().toLongString();
    }
    
    private RateLimiter createRateLimiter(RateLimit rateLimit) {
        switch (rateLimit.type()) {
            case FIXED_WINDOW:
                return new FixedWindowRateLimiter(rateLimit.limit(), rateLimit.windowSize());
            case SLIDING_WINDOW:
                return new SlidingWindowRateLimiter(rateLimit.limit(), rateLimit.windowSize());
            case TOKEN_BUCKET:
                return new TokenBucketRateLimiter(rateLimit.limit(), rateLimit.limit() / (rateLimit.windowSize() / 1000.0));
            case LEAKY_BUCKET:
                return new LeakyBucketRateLimiter(rateLimit.limit(), rateLimit.limit() / (rateLimit.windowSize() / 1000.0));
            default:
                return new FixedWindowRateLimiter(rateLimit.limit(), rateLimit.windowSize());
        }
    }
}

2.2 熔断降级

熔断降级实现:

java 复制代码
// 熔断器状态
enum CircuitBreakerState {
    CLOSED,    // 关闭:正常状态
    OPEN,      // 打开:熔断状态
    HALF_OPEN  // 半开:尝试恢复
}

// 熔断器
@Component
@Slf4j
public class CircuitBreaker {
    
    private volatile CircuitBreakerState state = CircuitBreakerState.CLOSED;
    private final AtomicInteger failureCount = new AtomicInteger(0);
    private final AtomicInteger successCount = new AtomicInteger(0);
    private volatile long lastFailureTime;
    
    private final int failureThreshold; // 失败阈值
    private final long timeout; // 超时时间(毫秒)
    private final long halfOpenTimeout; // 半开状态超时时间
    
    public CircuitBreaker(int failureThreshold, long timeout, long halfOpenTimeout) {
        this.failureThreshold = failureThreshold;
        this.timeout = timeout;
        this.halfOpenTimeout = halfOpenTimeout;
    }
    
    public <T> T execute(Supplier<T> supplier) {
        if (state == CircuitBreakerState.OPEN) {
            // 检查是否可以进入半开状态
            if (System.currentTimeMillis() - lastFailureTime > timeout) {
                state = CircuitBreakerState.HALF_OPEN;
                successCount.set(0);
                log.info("熔断器进入半开状态");
            } else {
                throw new CircuitBreakerOpenException("熔断器已打开");
            }
        }
        
        try {
            T result = supplier.get();
            onSuccess();
            return result;
        } catch (Exception e) {
            onFailure();
            throw e;
        }
    }
    
    private void onSuccess() {
        if (state == CircuitBreakerState.HALF_OPEN) {
            successCount.incrementAndGet();
            if (successCount.get() >= 3) { // 连续成功3次,恢复正常
                state = CircuitBreakerState.CLOSED;
                failureCount.set(0);
                log.info("熔断器恢复正常");
            }
        } else {
            failureCount.set(0);
        }
    }
    
    private void onFailure() {
        failureCount.incrementAndGet();
        lastFailureTime = System.currentTimeMillis();
        
        if (failureCount.get() >= failureThreshold) {
            state = CircuitBreakerState.OPEN;
            log.warn("熔断器打开: failureCount={}", failureCount.get());
        }
    }
    
    public CircuitBreakerState getState() {
        return state;
    }
}

// 降级策略
@Component
@Slf4j
public class FallbackService {
    
    @Autowired
    private CircuitBreaker circuitBreaker;
    
    // 执行带降级的操作
    public <T> T executeWithFallback(Supplier<T> supplier, Supplier<T> fallback) {
        try {
            return circuitBreaker.execute(supplier);
        } catch (CircuitBreakerOpenException e) {
            log.warn("执行降级策略");
            return fallback.get();
        } catch (Exception e) {
            log.error("执行失败,使用降级策略", e);
            return fallback.get();
        }
    }
    
    // 异步降级
    public <T> CompletableFuture<T> executeWithAsyncFallback(
        Supplier<CompletableFuture<T>> supplier, 
        Supplier<T> fallback) {
        
        return supplier.get()
            .exceptionally(throwable -> {
                log.warn("异步执行失败,使用降级策略", throwable);
                return fallback.get();
            });
    }
}

// 熔断降级使用示例
@Service
@Slf4j
public class UserServiceWithCircuitBreaker {
    
    @Autowired
    private CircuitBreaker circuitBreaker;
    
    @Autowired
    private FallbackService fallbackService;
    
    @Autowired
    private UserRepository userRepository;
    
    public User getUserById(Long userId) {
        return fallbackService.executeWithFallback(
            () -> {
                // 正常查询
                return userRepository.findById(userId)
                    .orElseThrow(() -> new UserNotFoundException("用户不存在"));
            },
            () -> {
                // 降级策略:返回默认用户
                log.info("使用降级策略返回默认用户");
                return createDefaultUser(userId);
            }
        );
    }
    
    private User createDefaultUser(Long userId) {
        User user = new User();
        user.setId(userId);
        user.setName("默认用户");
        return user;
    }
}

3. 分布式锁深度应用

3.1 Redis分布式锁

Redis分布式锁实现:

java 复制代码
// Redis分布式锁
@Component
@Slf4j
public class RedisDistributedLock {
    
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    private static final String LOCK_PREFIX = "lock:";
    private static final String LOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "return redis.call('del', KEYS[1]) " +
        "else return 0 end";
    
    // 获取锁
    public DistributedLock acquireLock(String key, long expireTime, TimeUnit timeUnit) {
        String lockKey = LOCK_PREFIX + key;
        String lockValue = UUID.randomUUID().toString();
        long expireMillis = timeUnit.toMillis(expireTime);
        
        Boolean acquired = redisTemplate.opsForValue().setIfAbsent(
            lockKey, 
            lockValue, 
            expireMillis, 
            TimeUnit.MILLISECONDS
        );
        
        if (Boolean.TRUE.equals(acquired)) {
            log.info("获取分布式锁成功: key={}, value={}", lockKey, lockValue);
            return new RedisLockImpl(lockKey, lockValue, expireMillis);
        }
        
        log.warn("获取分布式锁失败: key={}", lockKey);
        return null;
    }
    
    // 可重入锁实现
    private class RedisLockImpl implements DistributedLock {
        private final String lockKey;
        private final String lockValue;
        private final long expireTime;
        private final ThreadLocal<Integer> reentrantCount = new ThreadLocal<>();
        
        public RedisLockImpl(String lockKey, String lockValue, long expireTime) {
            this.lockKey = lockKey;
            this.lockValue = lockValue;
            this.expireTime = expireTime;
            this.reentrantCount.set(1);
        }
        
        @Override
        public boolean tryLock(long timeout, TimeUnit unit) {
            Integer count = reentrantCount.get();
            if (count != null && count > 0) {
                reentrantCount.set(count + 1);
                return true;
            }
            return false;
        }
        
        @Override
        public void unlock() {
            Integer count = reentrantCount.get();
            if (count != null && count > 1) {
                reentrantCount.set(count - 1);
                return;
            }
            
            // 使用Lua脚本保证原子性
            DefaultRedisScript<Long> script = new DefaultRedisScript<>();
            script.setScriptText(LOCK_SCRIPT);
            script.setResultType(Long.class);
            
            Long result = redisTemplate.execute(script, 
                Collections.singletonList(lockKey), lockValue);
            
            if (result != null && result == 1) {
                log.info("释放分布式锁成功: key={}", lockKey);
                reentrantCount.remove();
            } else {
                log.warn("释放分布式锁失败: key={}", lockKey);
            }
        }
        
        @Override
        public void close() {
            unlock();
        }
    }
}

// ZooKeeper分布式锁
@Component
@Slf4j
public class ZooKeeperDistributedLock {
    
    private final CuratorFramework client;
    private static final String LOCK_PATH = "/locks";
    
    public ZooKeeperDistributedLock(@Value("${zookeeper.connect-string}") String connectString) {
        this.client = CuratorFrameworkFactory.newClient(connectString, 
            new RetryForever(1000));
        this.client.start();
    }
    
    public DistributedLock acquireLock(String key) {
        String lockPath = LOCK_PATH + "/" + key;
        
        try {
            InterProcessMutex mutex = new InterProcessMutex(client, lockPath);
            mutex.acquire();
            
            log.info("获取ZooKeeper分布式锁成功: key={}", key);
            return new ZooKeeperLockImpl(mutex, key);
        } catch (Exception e) {
            log.error("获取ZooKeeper分布式锁失败: key={}", key, e);
            throw new RuntimeException("获取锁失败", e);
        }
    }
    
    private class ZooKeeperLockImpl implements DistributedLock {
        private final InterProcessMutex mutex;
        private final String key;
        
        public ZooKeeperLockImpl(InterProcessMutex mutex, String key) {
            this.mutex = mutex;
            this.key = key;
        }
        
        @Override
        public boolean tryLock(long timeout, TimeUnit unit) {
            try {
                return mutex.acquire(timeout, unit);
            } catch (Exception e) {
                log.error("尝试获取锁失败: key={}", key, e);
                return false;
            }
        }
        
        @Override
        public void unlock() {
            try {
                mutex.release();
                log.info("释放ZooKeeper分布式锁成功: key={}", key);
            } catch (Exception e) {
                log.error("释放锁失败: key={}", key, e);
            }
        }
        
        @Override
        public void close() {
            unlock();
        }
    }
}

// 数据库分布式锁
@Component
@Slf4j
public class DatabaseDistributedLock {
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    // 基于数据库唯一索引的分布式锁
    public DistributedLock acquireLock(String key, long expireTime) {
        String lockKey = "lock_" + key;
        String lockValue = UUID.randomUUID().toString();
        Date expireTime = new Date(System.currentTimeMillis() + expireTime);
        
        try {
            // 尝试插入锁记录
            jdbcTemplate.update(
                "INSERT INTO distributed_lock (lock_key, lock_value, expire_time) VALUES (?, ?, ?)",
                lockKey, lockValue, expireTime
            );
            
            log.info("获取数据库分布式锁成功: key={}", lockKey);
            return new DatabaseLockImpl(lockKey, lockValue);
        } catch (DuplicateKeyException e) {
            // 锁已存在,检查是否过期
            Map<String, Object> lock = jdbcTemplate.queryForMap(
                "SELECT * FROM distributed_lock WHERE lock_key = ?", lockKey
            );
            
            Date existingExpireTime = (Date) lock.get("expire_time");
            if (existingExpireTime.before(new Date())) {
                // 锁已过期,删除并重新获取
                jdbcTemplate.update("DELETE FROM distributed_lock WHERE lock_key = ?", lockKey);
                return acquireLock(key, expireTime);
            }
            
            log.warn("获取数据库分布式锁失败: key={}, 锁已存在且未过期", lockKey);
            return null;
        }
    }
    
    private class DatabaseLockImpl implements DistributedLock {
        private final String lockKey;
        private final String lockValue;
        
        public DatabaseLockImpl(String lockKey, String lockValue) {
            this.lockKey = lockKey;
            this.lockValue = lockValue;
        }
        
        @Override
        public boolean tryLock(long timeout, TimeUnit unit) {
            return true; // 已获取锁
        }
        
        @Override
        public void unlock() {
            int deleted = jdbcTemplate.update(
                "DELETE FROM distributed_lock WHERE lock_key = ? AND lock_value = ?",
                lockKey, lockValue
            );
            
            if (deleted > 0) {
                log.info("释放数据库分布式锁成功: key={}", lockKey);
            } else {
                log.warn("释放数据库分布式锁失败: key={}", lockKey);
            }
        }
        
        @Override
        public void close() {
            unlock();
        }
    }
}

// 分布式锁接口
public interface DistributedLock extends AutoCloseable {
    boolean tryLock(long timeout, TimeUnit unit);
    void unlock();
}

4. 分布式ID生成

4.1 雪花算法

雪花算法实现:

java 复制代码
// 雪花算法ID生成器
@Component
@Slf4j
public class SnowflakeIdGenerator {
    
    // 开始时间戳 (2024-01-01)
    private static final long START_TIMESTAMP = 1704067200000L;
    
    // 机器ID所占的位数
    private static final long WORKER_ID_BITS = 5L;
    // 数据中心ID所占的位数
    private static final long DATACENTER_ID_BITS = 5L;
    // 序列号所占的位数
    private static final long SEQUENCE_BITS = 12L;
    
    // 机器ID最大值
    private static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS);
    // 数据中心ID最大值
    private static final long MAX_DATACENTER_ID = ~(-1L << DATACENTER_ID_BITS);
    
    // 机器ID向左移12位
    private static final long WORKER_ID_SHIFT = SEQUENCE_BITS;
    // 数据中心ID向左移17位(12+5)
    private static final long DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
    // 时间戳向左移22位(5+5+12)
    private static final long TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS;
    
    // 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095)
    private static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS);
    
    // 工作机器ID(0~31)
    private final long workerId;
    // 数据中心ID(0~31)
    private final long datacenterId;
    // 毫秒内序列(0~4095)
    private long sequence = 0L;
    // 上次生成ID的时间戳
    private long lastTimestamp = -1L;
    
    private final Object lock = new Object();
    
    public SnowflakeIdGenerator(@Value("${snowflake.worker-id}") long workerId,
                               @Value("${snowflake.datacenter-id}") long datacenterId) {
        if (workerId > MAX_WORKER_ID || workerId < 0) {
            throw new IllegalArgumentException(
                String.format("worker Id can't be greater than %d or less than 0", MAX_WORKER_ID));
        }
        if (datacenterId > MAX_DATACENTER_ID || datacenterId < 0) {
            throw new IllegalArgumentException(
                String.format("datacenter Id can't be greater than %d or less than 0", MAX_DATACENTER_ID));
        }
        this.workerId = workerId;
        this.datacenterId = datacenterId;
        log.info("初始化雪花算法ID生成器: workerId={}, datacenterId={}", workerId, datacenterId);
    }
    
    public synchronized long nextId() {
        synchronized (lock) {
            long timestamp = timeGen();
            
            // 如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过
            if (timestamp < lastTimestamp) {
                throw new RuntimeException(
                    String.format("Clock moved backwards. Refusing to generate id for %d milliseconds",
                        lastTimestamp - timestamp));
            }
            
            // 如果是同一时间生成的,则进行毫秒内序列
            if (lastTimestamp == timestamp) {
                sequence = (sequence + 1) & SEQUENCE_MASK;
                // 毫秒内序列溢出
                if (sequence == 0) {
                    // 阻塞到下一个毫秒,获得新的时间戳
                    timestamp = tilNextMillis(lastTimestamp);
                }
            } else {
                // 时间戳改变,毫秒内序列重置
                sequence = 0L;
            }
            
            // 上次生成ID的时间戳
            lastTimestamp = timestamp;
            
            // 移位并通过或运算拼到一起组成64位的ID
            return ((timestamp - START_TIMESTAMP) << TIMESTAMP_LEFT_SHIFT)
                | (datacenterId << DATACENTER_ID_SHIFT)
                | (workerId << WORKER_ID_SHIFT)
                | sequence;
        }
    }
    
    // 阻塞到下一个毫秒,直到获得新的时间戳
    private long tilNextMillis(long lastTimestamp) {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen();
        }
        return timestamp;
    }
    
    // 返回以毫秒为单位的当前时间
    private long timeGen() {
        return System.currentTimeMillis();
    }
    
    // 解析ID信息
    public SnowflakeIdInfo parseId(long id) {
        long timestamp = (id >> TIMESTAMP_LEFT_SHIFT) + START_TIMESTAMP;
        long datacenterId = (id >> DATACENTER_ID_SHIFT) & ((1L << DATACENTER_ID_BITS) - 1);
        long workerId = (id >> WORKER_ID_SHIFT) & ((1L << WORKER_ID_BITS) - 1);
        long sequence = id & SEQUENCE_MASK;
        
        return new SnowflakeIdInfo(timestamp, datacenterId, workerId, sequence);
    }
}

// ID信息
@Data
@AllArgsConstructor
public class SnowflakeIdInfo {
    private long timestamp;
    private long datacenterId;
    private long workerId;
    private long sequence;
}

4.2 其他ID生成方案

其他ID生成方案:

java 复制代码
// UUID生成器
@Component
@Slf4j
public class UUIDGenerator {
    
    public String generateUUID() {
        return UUID.randomUUID().toString();
    }
    
    public String generateUUIDWithoutHyphens() {
        return UUID.randomUUID().toString().replace("-", "");
    }
}

// 数据库序列ID生成器
@Component
@Slf4j
public class DatabaseSequenceIdGenerator {
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    public Long generateId(String sequenceName) {
        // MySQL
        jdbcTemplate.update("UPDATE sequence SET current_value = current_value + 1 WHERE name = ?", sequenceName);
        Long id = jdbcTemplate.queryForObject(
            "SELECT current_value FROM sequence WHERE name = ?", 
            Long.class, sequenceName);
        return id;
    }
    
    // Redis自增ID生成器
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    public Long generateIdFromRedis(String key) {
        return redisTemplate.opsForValue().increment(key);
    }
    
    public Long generateIdWithPrefix(String prefix) {
        String key = "id:" + prefix;
        return redisTemplate.opsForValue().increment(key);
    }
}

// ID生成器工厂
@Component
@Slf4j
public class IdGeneratorFactory {
    
    @Autowired
    private SnowflakeIdGenerator snowflakeIdGenerator;
    
    @Autowired
    private UUIDGenerator uuidGenerator;
    
    @Autowired
    private DatabaseSequenceIdGenerator databaseSequenceIdGenerator;
    
    public Long generateId(IdType type) {
        switch (type) {
            case SNOWFLAKE:
                return snowflakeIdGenerator.nextId();
            case DATABASE_SEQUENCE:
                return databaseSequenceIdGenerator.generateId("default_sequence");
            case REDIS_INCREMENT:
                return databaseSequenceIdGenerator.generateIdFromRedis("id:default");
            default:
                throw new IllegalArgumentException("不支持的ID类型: " + type);
        }
    }
    
    public String generateStringId(IdType type) {
        switch (type) {
            case UUID:
                return uuidGenerator.generateUUID();
            case UUID_WITHOUT_HYPHENS:
                return uuidGenerator.generateUUIDWithoutHyphens();
            default:
                throw new IllegalArgumentException("不支持的字符串ID类型: " + type);
        }
    }
}

enum IdType {
    SNOWFLAKE,
    UUID,
    UUID_WITHOUT_HYPHENS,
    DATABASE_SEQUENCE,
    REDIS_INCREMENT
}

5. 系统架构演进

5.1 单体到微服务演进

架构演进示例:

java 复制代码
// 单体架构示例
@RestController
@RequestMapping("/api")
@Slf4j
public class MonolithicController {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private OrderService orderService;
    
    @Autowired
    private PaymentService paymentService;
    
    // 单体架构:所有功能在一个应用中
    @PostMapping("/order")
    public Order createOrder(@RequestBody CreateOrderRequest request) {
        // 1. 创建用户(如果不存在)
        User user = userService.getOrCreateUser(request.getUserId());
        
        // 2. 创建订单
        Order order = orderService.createOrder(request);
        
        // 3. 处理支付
        Payment payment = paymentService.processPayment(order);
        
        return order;
    }
}

// 微服务架构:服务拆分
// User Service
@RestController
@RequestMapping("/api/users")
@Slf4j
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @GetMapping("/{userId}")
    public User getUser(@PathVariable Long userId) {
        return userService.getUserById(userId);
    }
}

// Order Service
@RestController
@RequestMapping("/api/orders")
@Slf4j
public class OrderController {
    
    @Autowired
    private OrderService orderService;
    
    @Autowired
    private UserFeignClient userFeignClient;
    
    @Autowired
    private PaymentFeignClient paymentFeignClient;
    
    @PostMapping
    public Order createOrder(@RequestBody CreateOrderRequest request) {
        // 调用用户服务
        User user = userFeignClient.getUser(request.getUserId());
        
        // 创建订单
        Order order = orderService.createOrder(request);
        
        // 调用支付服务
        Payment payment = paymentFeignClient.processPayment(order);
        
        return order;
    }
}

// Feign客户端
@FeignClient(name = "user-service", url = "${services.user-service.url}")
public interface UserFeignClient {
    @GetMapping("/api/users/{userId}")
    User getUser(@PathVariable("userId") Long userId);
}

@FeignClient(name = "payment-service", url = "${services.payment-service.url}")
public interface PaymentFeignClient {
    @PostMapping("/api/payments")
    Payment processPayment(@RequestBody Order order);
}

5.2 微服务到云原生演进

云原生架构:

java 复制代码
// 云原生配置
@Configuration
@Slf4j
public class CloudNativeConfig {
    
    // 配置中心(Nacos/Config Server)
    @Bean
    @ConfigurationProperties(prefix = "app")
    public AppProperties appProperties() {
        return new AppProperties();
    }
    
    // 服务发现(Nacos/Eureka)
    @Bean
    public ServiceDiscovery serviceDiscovery() {
        return new NacosServiceDiscovery();
    }
    
    // 健康检查
    @Bean
    public HealthIndicator customHealthIndicator() {
        return new CustomHealthIndicator();
    }
}

// 云原生应用特性
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableConfigServer
@Slf4j
public class CloudNativeApplication {
    
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(CloudNativeApplication.class);
        
        // 从环境变量读取配置(12-Factor App)
        String port = System.getenv("PORT");
        if (port != null) {
            app.setDefaultProperties(Collections.singletonMap("server.port", port));
        }
        
        app.run(args);
    }
}

// 容器化支持
@Component
@Slf4j
public class ContainerAwareService {
    
    // 检测是否在容器中运行
    public boolean isRunningInContainer() {
        return new File("/.dockerenv").exists() || 
               System.getenv("KUBERNETES_SERVICE_HOST") != null;
    }
    
    // 获取容器信息
    public ContainerInfo getContainerInfo() {
        ContainerInfo info = new ContainerInfo();
        info.setContainerId(System.getenv("HOSTNAME"));
        info.setPodName(System.getenv("POD_NAME"));
        info.setNamespace(System.getenv("POD_NAMESPACE"));
        return info;
    }
}

6. 企业级最佳实践

6.1 代码规范与设计模式

最佳实践示例:

java 复制代码
// 策略模式:支付策略
public interface PaymentStrategy {
    PaymentResult pay(PaymentRequest request);
}

@Component
public class AlipayStrategy implements PaymentStrategy {
    @Override
    public PaymentResult pay(PaymentRequest request) {
        // 支付宝支付逻辑
        return new PaymentResult(true, "支付宝支付成功");
    }
}

@Component
public class WechatPayStrategy implements PaymentStrategy {
    @Override
    public PaymentResult pay(PaymentRequest request) {
        // 微信支付逻辑
        return new PaymentResult(true, "微信支付成功");
    }
}

// 策略工厂
@Component
@Slf4j
public class PaymentStrategyFactory {
    
    private final Map<PaymentType, PaymentStrategy> strategies;
    
    public PaymentStrategyFactory(List<PaymentStrategy> strategyList) {
        this.strategies = strategyList.stream()
            .collect(Collectors.toMap(
                this::getPaymentType,
                strategy -> strategy
            ));
    }
    
    public PaymentStrategy getStrategy(PaymentType type) {
        PaymentStrategy strategy = strategies.get(type);
        if (strategy == null) {
            throw new IllegalArgumentException("不支持的支付方式: " + type);
        }
        return strategy;
    }
    
    private PaymentType getPaymentType(PaymentStrategy strategy) {
        if (strategy instanceof AlipayStrategy) {
            return PaymentType.ALIPAY;
        } else if (strategy instanceof WechatPayStrategy) {
            return PaymentType.WECHAT;
        }
        throw new IllegalArgumentException("未知的支付策略");
    }
}

// 建造者模式:复杂对象构建
@Data
@Builder
public class OrderRequest {
    private Long userId;
    private List<OrderItem> items;
    private Address shippingAddress;
    private PaymentMethod paymentMethod;
    private String remark;
    
    public static class OrderRequestBuilder {
        public OrderRequestBuilder validate() {
            if (userId == null) {
                throw new IllegalArgumentException("用户ID不能为空");
            }
            if (items == null || items.isEmpty()) {
                throw new IllegalArgumentException("订单项不能为空");
            }
            return this;
        }
    }
}

// 观察者模式:事件通知
@Component
@Slf4j
public class OrderEventNotifier {
    
    private final List<OrderEventListener> listeners = new CopyOnWriteArrayList<>();
    
    public void addListener(OrderEventListener listener) {
        listeners.add(listener);
    }
    
    public void notifyOrderCreated(Order order) {
        OrderEvent event = new OrderCreatedEvent(order);
        listeners.forEach(listener -> {
            try {
                listener.onOrderCreated(event);
            } catch (Exception e) {
                log.error("事件监听器处理失败", e);
            }
        });
    }
}

6.2 性能优化实践

性能优化示例:

java 复制代码
// 批量操作优化
@Service
@Slf4j
public class BatchOperationService {
    
    @Autowired
    private UserRepository userRepository;
    
    // 批量插入优化
    @Transactional
    public void batchInsertUsers(List<User> users) {
        int batchSize = 1000;
        for (int i = 0; i < users.size(); i += batchSize) {
            List<User> batch = users.subList(i, Math.min(i + batchSize, users.size()));
            userRepository.saveAll(batch);
            userRepository.flush(); // 强制刷新到数据库
        }
    }
    
    // 异步批量处理
    @Async
    public CompletableFuture<Void> batchProcessAsync(List<Order> orders) {
        return CompletableFuture.runAsync(() -> {
            orders.parallelStream().forEach(this::processOrder);
        });
    }
}

// 连接池优化
@Configuration
public class DataSourceConfig {
    
    @Bean
    public DataSource dataSource() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/db");
        config.setUsername("root");
        config.setPassword("password");
        
        // 连接池优化配置
        config.setMaximumPoolSize(20); // 最大连接数
        config.setMinimumIdle(5); // 最小空闲连接
        config.setConnectionTimeout(30000); // 连接超时
        config.setIdleTimeout(600000); // 空闲超时
        config.setMaxLifetime(1800000); // 最大生命周期
        config.setLeakDetectionThreshold(60000); // 泄漏检测
        
        return new HikariDataSource(config);
    }
}
相关推荐
程序猿DD2 小时前
探索 Java 中的新 HTTP 客户端
java·后端
m0_495562782 小时前
Swift-Enum
java·算法·swift
姓蔡小朋友2 小时前
Redis:Feed流、SortedSet实现点赞人排序、SortedSet滚动分页
java
青山的青衫2 小时前
【前后缀】Leetcode hot 100
java·算法·leetcode
q***46522 小时前
基于SpringBoot和PostGIS的各省与地级市空间距离分析
java·spring boot·spring
狂团商城小师妹2 小时前
JAVA国际版同城服务同城信息同城任务发布平台APP源码Android + IOS
android·java·ios
后端小张2 小时前
【JAVA 进阶】Spring Boot 自动配置原理与自定义 Starter 实战
java·spring boot·后端·spring·spring cloud·自定义·原理
Zzzzmo_2 小时前
Java数据结构:二叉树
java·数据结构·算法
多多*2 小时前
一个有 IP 的服务端监听了某个端口,那么他的 TCP 最大链接数是多少
java·开发语言·网络·网络协议·tcp/ip·缓存·mybatis