当前位置: 首页 > news >正文

分布式系统实战:电商平台架构演进

CSDN分布式系统深度实战系列:一个电商平台从单体架构分布式微服务架构的全过程演进。涵盖技术选型、架构设计、数据迁移、性能优化四大核心模块,每个阶段都配有真实的业务场景、架构图和性能数据对比。通过订单系统、库存系统、支付系统等核心模块的演进案例,展示如何构建高可用、可扩展的电商平台架构。建议⭐收藏⭐,架构演进时随时参考!

🏗️ 电商平台架构演进全景图

单体架构
垂直拆分
分布式服务
微服务架构
云原生架构
LAMP堆栈
单一数据库
用户服务
商品服务
订单服务
服务化
消息队列
缓存集群
服务网格
容器化
CI/CD
Service Mesh
Serverless
AIOps

一、🚀 第一阶段:单体架构(日订单<1000)

1.1 技术栈与架构设计

// 单体应用结构 - Spring Boot + MySQL
@SpringBootApplication
public class MonolithEcommerceApplication {public static void main(String[] args) {SpringApplication.run(MonolithEcommerceApplication.class, args);}
}// 单体应用包结构
src/main/java/com/ebusiness/
├── controller/          # 控制层
│   ├── UserController.java
│   ├── ProductController.java
│   └── OrderController.java
├── service/            # 业务层
│   ├── UserService.java
│   ├── ProductService.java
│   └── OrderService.java
├── repository/         # 数据层
│   ├── UserRepository.java
│   ├── ProductRepository.java
│   └── OrderRepository.java
└── entity/             # 实体类├── User.java├── Product.java└── Order.java

1.2 数据库设计

-- 单一数据库设计
CREATE DATABASE ecommerce_monolith;-- 用户表
CREATE TABLE users (id BIGINT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) UNIQUE NOT NULL,email VARCHAR(100) UNIQUE NOT NULL,password_hash VARCHAR(100) NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,INDEX idx_username (username),INDEX idx_email (email)
);-- 商品表
CREATE TABLE products (id BIGINT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(200) NOT NULL,price DECIMAL(10,2) NOT NULL,stock INT NOT NULL,category_id BIGINT,status TINYINT DEFAULT 1,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,INDEX idx_category (category_id),INDEX idx_status (status)
);-- 订单表
CREATE TABLE orders (id BIGINT PRIMARY KEY AUTO_INCREMENT,user_id BIGINT NOT NULL,total_amount DECIMAL(10,2) NOT NULL,status ENUM('PENDING','PAID','SHIPPED','COMPLETED','CANCELLED') DEFAULT 'PENDING',created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,FOREIGN KEY (user_id) REFERENCES users(id),INDEX idx_user_id (user_id),INDEX idx_status (status),INDEX idx_created_at (created_at)
);-- 订单项表
CREATE TABLE order_items (id BIGINT PRIMARY KEY AUTO_INCREMENT,order_id BIGINT NOT NULL,product_id BIGINT NOT NULL,quantity INT NOT NULL,price DECIMAL(10,2) NOT NULL,FOREIGN KEY (order_id) REFERENCES orders(id),FOREIGN KEY (product_id) REFERENCES products(id),INDEX idx_order_id (order_id)
);

1.3 核心业务逻辑

@Service
@Transactional
@Slf4j
public class OrderService {@Autowiredprivate OrderRepository orderRepository;@Autowiredprivate ProductRepository productRepository;@Autowiredprivate UserRepository userRepository;/*** 创建订单 - 单体架构下的简单实现*/public Order createOrder(OrderRequest request) {// 1. 验证用户User user = userRepository.findById(request.getUserId()).orElseThrow(() -> new BusinessException("用户不存在"));// 2. 验证商品和库存List<OrderItem> items = new ArrayList<>();BigDecimal totalAmount = BigDecimal.ZERO;for (OrderItemRequest itemRequest : request.getItems()) {Product product = productRepository.findById(itemRequest.getProductId()).orElseThrow(() -> new BusinessException("商品不存在"));if (product.getStock() < itemRequest.getQuantity()) {throw new BusinessException("库存不足: " + product.getName());}// 扣减库存product.setStock(product.getStock() - itemRequest.getQuantity());productRepository.save(product);// 计算订单项BigDecimal itemTotal = product.getPrice().multiply(BigDecimal.valueOf(itemRequest.getQuantity()));totalAmount = totalAmount.add(itemTotal);OrderItem item = new OrderItem();item.setProductId(product.getId());item.setQuantity(itemRequest.getQuantity());item.setPrice(product.getPrice());items.add(item);}// 3. 创建订单Order order = new Order();order.setUserId(user.getId());order.setTotalAmount(totalAmount);order.setStatus(OrderStatus.PENDING);order.setItems(items);Order savedOrder = orderRepository.save(order);log.info("订单创建成功: {}", savedOrder.getId());return savedOrder;}
}

二、💡 第二阶段:垂直拆分(日订单1万-10万)

2.1 服务拆分策略

// 用户服务 - 独立部署
@Service
@Slf4j
public class UserService {@Autowiredprivate UserRepository userRepository;@Autowiredprivate RedisTemplate<String, User> redisTemplate;private static final String USER_CACHE_PREFIX = "user:";private static final Duration CACHE_TTL = Duration.ofHours(1);public User getUser(Long userId) {// 缓存优化String cacheKey = USER_CACHE_PREFIX + userId;User user = redisTemplate.opsForValue().get(cacheKey);if (user != null) {return user;}user = userRepository.findById(userId).orElseThrow(() -> new BusinessException("用户不存在"));redisTemplate.opsForValue().set(cacheKey, user, CACHE_TTL);return user;}
}// 商品服务 - 独立部署
@Service
@Slf4j
public class ProductService {@Autowiredprivate ProductRepository productRepository;@Autowiredprivate RedisTemplate<String, Product> redisTemplate;/*** 商品查询 - 加入缓存和搜索优化*/public Page<Product> searchProducts(ProductQuery query, Pageable pageable) {// 复杂的商品搜索逻辑Specification<Product> spec = (root, criteriaQuery, criteriaBuilder) -> {List<Predicate> predicates = new ArrayList<>();if (StringUtils.isNotBlank(query.getKeyword())) {Predicate namePredicate = criteriaBuilder.like(root.get("name"), "%" + query.getKeyword() + "%");Predicate descPredicate = criteriaBuilder.like(root.get("description"), "%" + query.getKeyword() + "%");predicates.add(criteriaBuilder.or(namePredicate, descPredicate));}if (query.getCategoryId() != null) {predicates.add(criteriaBuilder.equal(root.get("categoryId"), query.getCategoryId()));}if (query.getMinPrice() != null && query.getMaxPrice() != null) {predicates.add(criteriaBuilder.between(root.get("price"), query.getMinPrice(), query.getMaxPrice()));}return criteriaBuilder.and(predicates.toArray(new Predicate[0]));};return productRepository.findAll(spec, pageable);}
}

2.2 数据库垂直拆分

-- 用户数据库
CREATE DATABASE user_db;
CREATE TABLE users (...); -- 同单体架构,但独立数据库-- 商品数据库  
CREATE DATABASE product_db;
CREATE TABLE products (...);
CREATE TABLE categories (...);
CREATE TABLE product_skus (...);-- 订单数据库
CREATE DATABASE order_db;
CREATE TABLE orders (...);
CREATE TABLE order_items (...);

2.3 服务间通信 - RESTful API

// 订单服务调用用户服务
@Service
public class OrderService {@Autowiredprivate RestTemplate restTemplate;private static final String USER_SERVICE_URL = "http://user-service/api/users";private static final String PRODUCT_SERVICE_URL = "http://product-service/api/products";/*** 跨服务创建订单*/public Order createOrderDistributed(OrderRequest request) {// 1. 调用用户服务验证用户User user = restTemplate.getForObject(USER_SERVICE_URL + "/" + request.getUserId(), User.class);if (user == null) {throw new BusinessException("用户不存在");}// 2. 调用商品服务验证库存for (OrderItemRequest itemRequest : request.getItems()) {ProductStock stock = restTemplate.getForObject(PRODUCT_SERVICE_URL + "/" + itemRequest.getProductId() + "/stock",ProductStock.class);if (stock.getAvailable() < itemRequest.getQuantity()) {throw new BusinessException("库存不足");}}// 3. 创建订单(本地事务)return createOrderLocal(request);}
}

三、⚡ 第三阶段:分布式服务(日订单10万-100万)

3.1 服务注册与发现

# Spring Cloud Eureka 配置
eureka:client:service-url:defaultZone: http://eureka1:8761/eureka,http://eureka2:8762/eurekaregister-with-eureka: truefetch-registry: trueinstance:hostname: ${spring.application.name}prefer-ip-address: true# 应用配置
spring:application:name: order-servicecloud:loadbalancer:ribbon:enabled: true

3.2 分布式事务 - Saga模式

// Saga模式实现分布式事务
@Service
@Slf4j
public class OrderSagaService {@Autowiredprivate InventoryService inventoryService;@Autowiredprivate PaymentService paymentService;@Autowiredprivate ShippingService shippingService;@Autowiredprivate SagaCoordinator sagaCoordinator;/*** 创建订单Saga事务*/@Sagapublic OrderResult createOrderSaga(OrderRequest request) {SagaExecution saga = new SagaExecution("create-order");try {// 步骤1: 预留库存saga.addStep("reserve-inventory", () -> {inventoryService.reserveStock(request.getItems());}, () -> {inventoryService.releaseStock(request.getItems());});// 步骤2: 创建订单saga.addStep("create-order", () -> {return orderRepository.save(buildOrder(request));}, (order) -> {orderRepository.delete(order);});// 步骤3: 处理支付saga.addStep("process-payment", () -> {paymentService.processPayment(request.getPaymentInfo());}, (payment) -> {paymentService.refundPayment(payment);});// 执行Sagareturn saga.execute();} catch (SagaException e) {log.error("订单创建Saga失败", e);// 执行补偿操作saga.compensate();throw new BusinessException("订单创建失败");}}
}

3.3 消息队列异步化

// 订单创建消息生产者
@Component
@Slf4j
public class OrderEventProducer {@Autowiredprivate RocketMQTemplate rocketMQTemplate;/*** 发送订单创建事件*/public void sendOrderCreatedEvent(Order order) {OrderCreatedEvent event = new OrderCreatedEvent();event.setOrderId(order.getId());event.setUserId(order.getUserId());event.setTotalAmount(order.getTotalAmount());event.setItems(order.getItems());event.setCreateTime(order.getCreatedAt());rocketMQTemplate.convertAndSend("ORDER_CREATED_TOPIC", event);log.info("订单创建事件发送成功: {}", order.getId());}
}// 库存扣减消费者
@Component
@RocketMQMessageListener(topic = "ORDER_CREATED_TOPIC",consumerGroup = "inventory-consumer-group"
)
@Slf4j
public class InventoryDeductionConsumer implements RocketMQListener<OrderCreatedEvent> {@Autowiredprivate InventoryService inventoryService;@Overridepublic void onMessage(OrderCreatedEvent event) {try {log.info("收到订单创建事件,开始扣减库存: {}", event.getOrderId());inventoryService.deductStock(event.getOrderId(), event.getItems());log.info("库存扣减成功: {}", event.getOrderId());} catch (Exception e) {log.error("库存扣减失败: {}", event.getOrderId(), e);// 重试或人工处理throw new RuntimeException("库存扣减失败", e);}}
}

四、🏗️ 第四阶段:微服务架构(日订单100万+)

4.1 领域驱动设计(DDD)

// 订单聚合根
@Entity
@AggregateRoot
@Data
public class Order {@Idprivate Long id;private Long userId;private BigDecimal totalAmount;private OrderStatus status;private List<OrderItem> items;private Address shippingAddress;private PaymentInfo paymentInfo;/*** 创建订单 - 领域逻辑*/public static Order create(Long userId, List<OrderItem> items, Address address) {Order order = new Order();order.id = IdGenerator.nextId();order.userId = userId;order.items = items;order.shippingAddress = address;order.status = OrderStatus.PENDING;order.totalAmount = calculateTotalAmount(items);// 领域事件order.addDomainEvent(new OrderCreatedEvent(order.id, order.userId));return order;}/*** 支付订单*/public void pay(PaymentInfo paymentInfo) {if (this.status != OrderStatus.PENDING) {throw new IllegalStateException("订单状态异常");}this.paymentInfo = paymentInfo;this.status = OrderStatus.PAID;this.addDomainEvent(new OrderPaidEvent(this.id));}
}// 订单领域服务
@Service
@DomainService
@Slf4j
public class OrderDomainService {@Autowiredprivate OrderRepository orderRepository;@Autowiredprivate DomainEventPublisher eventPublisher;/*** 处理订单创建*/@Transactionalpublic Order handleOrderCreation(CreateOrderCommand command) {// 验证业务规则validateBusinessRules(command);// 创建订单聚合Order order = Order.create(command.getUserId(),command.getItems(),command.getShippingAddress());// 保存聚合orderRepository.save(order);// 发布领域事件eventPublisher.publishAll(order.getDomainEvents());order.clearDomainEvents();return order;}
}

4.2 服务网格与治理

# Istio VirtualService - 订单服务路由
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: order-service
spec:hosts:- order-servicehttp:- match:- headers:version:exact: canaryroute:- destination:host: order-servicesubset: canaryweight: 10- route:- destination:host: order-servicesubset: stableweight: 90retries:attempts: 3perTryTimeout: 2stimeout: 10s# DestinationRule - 负载均衡策略
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:name: order-service
spec:host: order-servicesubsets:- name: stablelabels:version: stabletrafficPolicy:loadBalancer:simple: LEAST_CONN- name: canarylabels:version: canarytrafficPolicy:loadBalancer:simple: ROUND_ROBIN

4.3 数据分片与读写分离

// 订单分片策略
@Component
@Slf4j
public class OrderShardingStrategy {private static final int SHARD_COUNT = 16;private static final int TABLE_COUNT_PER_SHARD = 64;/*** 根据用户ID计算分片*/public String calculateShard(Long userId) {int shardIndex = (int) (userId % SHARD_COUNT);return "order_db_" + shardIndex;}/*** 根据订单ID计算表名*/public String calculateTableName(Long orderId) {int tableIndex = (int) (orderId % TABLE_COUNT_PER_SHARD);return "orders_" + tableIndex;}
}// 分片数据源路由
@Component
public class OrderDataSourceRouter extends AbstractRoutingDataSource {@Autowiredprivate OrderShardingStrategy shardingStrategy;@Overrideprotected Object determineCurrentLookupKey() {Long userId = OrderContextHolder.getCurrentUserId();if (userId == null) {return "order_db_0"; // 默认分片}return shardingStrategy.calculateShard(userId);}
}

五、📊 性能优化实战

5.1 缓存策略优化

// 多级缓存实现
@Service
@Slf4j
public class MultiLevelCacheService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;// 本地缓存private Cache<String, Object> localCache = Caffeine.newBuilder().maximumSize(10000).expireAfterWrite(5, TimeUnit.MINUTES).build();/*** 获取订单信息 - 多级缓存*/public Order getOrderWithCache(Long orderId) {String cacheKey = "order:" + orderId;// 1. 查询本地缓存Order order = (Order) localCache.getIfPresent(cacheKey);if (order != null) {log.debug("命中本地缓存: {}", orderId);return order;}// 2. 查询Redis缓存order = (Order) redisTemplate.opsForValue().get(cacheKey);if (order != null) {log.debug("命中Redis缓存: {}", orderId);localCache.put(cacheKey, order);return order;}// 3. 查询数据库order = orderRepository.findById(orderId);if (order != null) {// 异步写入缓存CompletableFuture.runAsync(() -> {redisTemplate.opsForValue().set(cacheKey, order, Duration.ofHours(1));localCache.put(cacheKey, order);});}return order;}
}

5.2 数据库优化

-- 订单表分片后索引优化
CREATE TABLE order_db_0.orders_0 (id BIGINT PRIMARY KEY,user_id BIGINT NOT NULL,-- ... 其他字段INDEX idx_user_id (user_id),INDEX idx_status_created (status, created_at),INDEX idx_user_created (user_id, created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;-- 读写分离配置
-- 写库
spring:datasource:write:url: jdbc:mysql://master-db:3306/order_db_0username: write_userpassword: write_pass-- 读库
spring:datasource:read:url: jdbc:mysql://slave-db:3306/order_db_0username: read_userpassword: read_pass

六、🔧 监控与运维

6.1 全链路监控

# 应用监控配置
management:endpoints:web:exposure:include: health,info,metrics,prometheusendpoint:health:show-details: alwaysprobes:enabled: truemetrics:export:prometheus:enabled: true# 自定义业务指标
@Component
public class OrderMetrics {private final MeterRegistry meterRegistry;private final Counter orderCreatedCounter;private final Timer orderProcessTimer;private final Gauge activeOrdersGauge;public OrderMetrics(MeterRegistry meterRegistry) {this.meterRegistry = meterRegistry;this.orderCreatedCounter = Counter.builder("order.created").description("订单创建数量").register(meterRegistry);this.orderProcessTimer = Timer.builder("order.process.duration").description("订单处理耗时").publishPercentiles(0.5, 0.95, 0.99).register(meterRegistry);}public void recordOrderCreated() {orderCreatedCounter.increment();}
}

6.2 日志追踪

@Aspect
@Component
@Slf4j
public class LoggingAspect {@Around("execution(* com.ebusiness..service..*(..))")public Object logMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable {String methodName = joinPoint.getSignature().getName();String className = joinPoint.getTarget().getClass().getSimpleName();long startTime = System.currentTimeMillis();try {log.info("开始执行: {}.{}", className, methodName);Object result = joinPoint.proceed();long duration = System.currentTimeMillis() - startTime;log.info("执行完成: {}.{}, 耗时: {}ms", className, methodName, duration);return result;} catch (Exception e) {log.error("执行失败: {}.{}, 错误: {}", className, methodName, e.getMessage());throw e;}}
}

七、🚀 架构演进总结

7.1 性能数据对比

架构阶段QPS平均响应时间可用性扩展性
单体架构500100ms99.5%
垂直拆分5,00050ms99.9%中等
分布式服务50,00030ms99.95%良好
微服务架构500,00020ms99.99%优秀

7.2 技术债务与演进成本

// 架构演进检查清单
@Component
public class ArchitectureReviewChecklist {/*** 检查是否需要进行架构演进*/public ArchitectureReviewResult reviewCurrentArchitecture(SystemMetrics metrics) {List<String> recommendations = new ArrayList<>();// QPS检查if (metrics.getQps() > 1000 && metrics.getCurrentArchitecture() == Architecture.MONOLITH) {recommendations.add("考虑垂直拆分,QPS已超过单体架构承载能力");}// 响应时间检查if (metrics.getAvgResponseTime() > 100) {recommendations.add("响应时间过长,考虑引入缓存和异步处理");}// 可用性检查if (metrics.getAvailability() < 99.9) {recommendations.add("可用性不足,需要引入容错机制和冗余设计");}return new ArchitectureReviewResult(recommendations, getRecommendedArchitecture(metrics));}private Architecture getRecommendedArchitecture(SystemMetrics metrics) {if (metrics.getQps() < 1000) return Architecture.MONOLITH;if (metrics.getQps() < 10000) return Architecture.VERTICAL_SPLIT;if (metrics.getQps() < 100000) return Architecture.DISTRIBUTED;return Architecture.MICROSERVICES;}
}

💎 总结与最佳实践

架构演进原则

  1. 渐进式演进:不要一步到位,按需演进
  2. 数据驱动决策:基于性能指标决定演进时机
  3. 风险控制:每次演进都要有回滚方案
  4. 团队能力匹配:架构复杂度与团队能力相适应

技术选型建议

  • 初创阶段:单体架构 + 简单缓存
  • 成长阶段:服务拆分 + 消息队列
  • 成熟阶段:微服务 + 服务网格
  • 大规模阶段:云原生 + 多集群

💬 互动话题:你在电商平台架构演进中遇到过哪些挑战?是如何解决的?欢迎在评论区分享经验!

👉 下一篇预告:《高并发秒杀系统设计:从理论到实践》
(点击关注第一时间获取更新通知)


🎁 文末福利

关注+私信回复"电商架构"获取

  • 📚 完整架构演进脑图(PDF版)
  • 🛠️ 各阶段配置模板
  • 📊 性能压测脚本
  • 💻 监控Dashboard配置
http://www.dtcms.com/a/449867.html

相关文章:

  • 基于YOLOv8+CNN的智能停车场车牌识别系统(视频图片均可)(完整实现,附完整可直接运行代码)
  • @ComponentScan组件扫描原理
  • 沈阳制作网站的公司网站开发要什么
  • MySQL 8.0存储引擎选型指南
  • 做移动端网站设计网站怎样制作
  • redis的哨兵机制简单问题
  • 打造自己的中秋 AR 赏月应用:实现虚实融合的节日体验
  • 建设网站学什么建设考试的报名网站
  • 色块网站设计在家做的网站编辑
  • WebRTC 入门与实战(二)之中级篇
  • pass@1是什么意思
  • 沈阳网站建设技术公司百度站长工具seo
  • 做国内电影网站赚钱不简述电子商务网站开发的主要步骤
  • InputStream和OutputStream在网络编程发挥的作用
  • CCS闪退问题---------中文系统用户名
  • 专业电竞体育数据与系统解决方案
  • 初阶运维工程师工作内容与能力体系:专业视角解析
  • 我的钢铁网网站架构林芝北京网站建设
  • OpenManus项目架构解析
  • 【HarmonyOS】消息通知
  • 网上做流量对网站有什么影响asp.net 做网站实例
  • 深圳建设资格注册中心网站网站建设采用的技术
  • gRPC从0到1系列【22】
  • 闹钟定时器(Alarm Timer)初始化:构建可挂起的定时器基础框架
  • 云南公司建网站多少钱wordpress修改菜单的原始链接
  • 自己如何建设个网站首页站酷网官方入口网页版
  • 华为matebook16s 2022数字键无法使用解决方法
  • 邯郸网站建设品牌公司app和网站开发区别
  • 并查集的优化
  • LeetCode:93.最长回文子串