基于 Spring + SpringMVC + MyBatis 的分布式敏捷开发系统架构

Author:周均扬

date: 2025.09.20


以下是一个基于 Spring + SpringMVC + MyBatis 的分布式敏捷开发系统架构的详细示例说明,涵盖架构设计、模块划分、分布式特性以及敏捷开发实践的结合。示例以一个典型的分布式电商系统为背景,逐步讲解。


1. 架构概述

Spring + SpringMVC + MyBatis 是一种经典的 Java 企业级开发技术栈,适合构建高性能、可扩展的分布式系统。分布式架构将系统拆分为多个独立的服务模块,通过服务间通信实现协作,结合敏捷开发方法可以快速迭代和响应需求变化。

核心技术栈

分布式系统特点


2. 示例:分布式电商系统架构

假设我们要开发一个分布式电商平台,包含用户管理、商品管理、订单管理和支付功能。以下是基于 Spring + SpringMVC + MyBatis 的分布式架构设计。

2.1 架构分层

  1. 前端层:
    • 使用前端框架(如 Vue.js 或 React)与后端通过 RESTful API 交互。
    • 静态资源托管在 CDN 上,提升访问速度。
  2. 网关层:
    • 使用 Spring Cloud Gateway 或 Zuul 作为 API 网关。
    • 功能:路由分发、负载均衡、认证授权、限流、日志记录。
    • 示例:用户请求 /api/order/create 被网关路由到订单服务。
  3. 服务层:
    • 拆分为多个微服务模块(如用户服务、商品服务、订单服务、支付服务)。
    • 使用 Spring Boot 快速构建微服务,结合 SpringMVC 处理 RESTful 请求。
    • 服务间通信通过 Dubbo(基于 RPC)或 Spring Cloud Feign(基于 HTTP)实现。
    • 示例:
      • 用户服务:管理用户注册、登录、个人信息。
      • 商品服务:管理商品信息、库存。
      • 订单服务:处理订单创建、查询、状态更新。
      • 支付服务:对接第三方支付接口(如支付宝、微信)。
  4. 数据层:
    • 使用 MyBatis 作为 ORM 框架,连接分布式数据库(如 MySQL 分库分表)。
    • 数据库中间件(如 ShardingSphere)实现分库分表,提升数据处理能力。
    • 缓存层使用 Redis 存储热点数据(如商品详情、用户 Session)。
    • 示例:订单服务通过 MyBatis 执行 SQL 查询订单表,Redis 缓存热门商品数据。
  5. 消息队列:
    • 使用 RabbitMQ 或 Kafka 实现异步通信。
    • 示例:订单创建后,通过消息队列通知支付服务和库存服务进行后续处理。
  6. 分布式协调与配置:
    • 使用 Zookeeper 或 Spring Cloud Config 管理服务注册与发现、配置中心。
    • 示例:订单服务启动时向 Zookeeper 注册,网关通过 Zookeeper 获取服务地址。
  7. 日志与监控:
    • 使用 ELK(Elasticsearch + Logstash + Kibana)收集和分析日志。
    • 使用 Prometheus + Grafana 监控服务性能和健康状态。

2.2 技术选型

| 层级 | 技术选型 | 作用 | |—————|———————————-|—————————————–| | 前端层 | Vue.js / React + CDN | 用户界面、静态资源加速 | | 网关层 | Spring Cloud Gateway | 路由、负载均衡、认证授权 | | 服务层 | Spring Boot + SpringMVC + Dubbo | 微服务开发、RESTful API、RPC 通信 | | 数据层 | MyBatis + MySQL + ShardingSphere| 数据库操作、分库分表 | | 缓存层 | Redis | 热点数据缓存、Session 管理 | | 消息队列 | RabbitMQ / Kafka | 异步通信、解耦 | | 配置与协调 | Zookeeper / Spring Cloud Config | 服务注册与发现、分布式配置管理 | | 日志与监控 | ELK + Prometheus + Grafana | 日志收集、性能监控 |


3. 代码示例

以下是一个简单的订单服务模块,展示 Spring + SpringMVC + MyBatis 的实现。

3.1 数据库表(MySQL)

CREATE TABLE t_order (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    user_id BIGINT NOT NULL,
    product_id BIGINT NOT NULL,
    quantity INT NOT NULL,
    total_amount DECIMAL(10, 2) NOT NULL,
    status VARCHAR(20) DEFAULT 'PENDING',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

3.2 MyBatis Mapper(OrderMapper.xml)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.ecommerce.mapper.OrderMapper">
    <select id="findById" resultType="com.example.ecommerce.entity.Order">
        SELECT * FROM t_order WHERE id = #{id}
    </select>

    <insert id="createOrder" parameterType="com.example.ecommerce.entity.Order">
        INSERT INTO t_order (user_id, product_id, quantity, total_amount, status)
        VALUES (#{userId}, #{productId}, #{quantity}, #{totalAmount}, #{status})
    </insert>
</mapper>

3.3 Spring Service(OrderService.java)

@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;
    
    @Autowired
    private RestTemplate restTemplate; // 用于调用其他服务

    public Order findById(Long id) {
        return orderMapper.findById(id);
    }

    @Transactional
    public void createOrder(Order order) {
        // 调用商品服务检查库存
        String productServiceUrl = "http://product-service/api/product/checkStock?productId=" + order.getProductId();
        Boolean hasStock = restTemplate.getForObject(productServiceUrl, Boolean.class);
        if (!hasStock) {
            throw new RuntimeException("库存不足");
        }

        // 保存订单
        order.setStatus("PENDING");
        orderMapper.createOrder(order);

        // 异步通知支付服务(通过消息队列)
        rabbitTemplate.convertAndSend("orderQueue", order.getId());
    }
}

3.4 SpringMVC Controller(OrderController.java)

@RestController
@RequestMapping("/api/order")
public class OrderController {
    @Autowired
    private OrderService orderService;

    @GetMapping("/{id}")
    public Order getOrder(@PathVariable Long id) {
        return orderService.findById(id);
    }

    @PostMapping("/create")
    public String createOrder(@RequestBody Order order) {
        orderService.createOrder(order);
        return "订单创建成功";
    }
}

3.5 配置(application.yml)

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/ecommerce?useSSL=false
    username: root
    password: password
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
mybatis:
  mapper-locations: classpath:mapper/*.xml
dubbo:
  registry:
    address: zookeeper://127.0.0.1:2181
  protocol:
    name: dubbo
    port: 20880

4. 分布式特性实现

  1. 服务注册与发现:
    • 使用 Zookeeper 或 Eureka 实现服务注册。
    • 示例:订单服务启动后向 Zookeeper 注册,网关通过 Zookeeper 获取订单服务的地址。
  2. 负载均衡:
    • 网关层使用 Spring Cloud Gateway 内置的负载均衡(基于 Ribbon)。
    • 示例:订单服务部署多个实例,网关自动分发请求到空闲实例。
  3. 分布式事务:
    • 使用 Seata 或消息队列最终一致性方案处理分布式事务。
    • 示例:订单创建后,通过消息队列异步扣减库存和发起支付,确保数据一致性。
  4. 缓存优化:
    • 使用 Redis 缓存商品详情、用户 Session。
    • 示例:商品服务查询热门商品时,先查 Redis,若无数据再查 MySQL 并写入 Redis。
  5. 异步通信:
    • 使用 RabbitMQ 实现订单创建后异步通知支付服务和库存服务。
    • 示例:订单服务发送订单 ID 到队列,支付服务消费消息后发起支付请求。

5. 敏捷开发实践

  1. Scrum 流程:
    • 每两周一个 Sprint,明确需求(如新增支付功能)。
    • 每日站会,跟踪开发进度。
    • 使用 JIRA 或 Trello 管理任务。
  2. 持续集成与部署 (CI/CD):
    • 使用 Jenkins 或 GitLab CI 自动化构建、测试和部署。
    • 示例:代码提交后,Jenkins 自动运行单元测试,测试通过后部署到 Docker 容器。
  3. 模块化开发:
    • 每个微服务由独立团队开发,基于 API 契约协作。
    • 示例:用户服务团队和订单服务团队并行开发,通过 Swagger 定义 API 接口。
  4. 快速迭代:
    • 使用 Spring Boot 快速搭建服务,减少配置时间。
    • 示例:新增支付服务只需复制现有服务模板,调整业务逻辑即可上线。

6. 部署与运行


7. 总结

通过 Spring + SpringMVC + MyBatis 构建的分布式电商系统,结合分布式技术和敏捷开发实践,可以实现高性能、可扩展、快速迭代的系统架构。核心要点包括: