学习目标
掌握企业级系统架构设计方法,学习高并发系统设计模式,深入理解分布式锁与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);
}
}