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

Spring Cloud 开发入门:环境搭建与微服务项目实战(上)

一、开发环境搭建


1. JDK 安装与版本选择

版本选择解析

Java 是 Spring Cloud 微服务开发的基础,选择合适的 JDK 版本至关重要,特别是在框架兼容性和生产环境稳定性方面。


(1)主流 JDK 版本对比
版本发布年份支持状态特点简述
JDK82014已过高峰期最广泛使用、兼容性强、生态成熟,是旧项目的首选
JDK112018LTS(长期支持)模块系统正式引入,提升性能,支持较新特性,企业应用常用
JDK172021LTS(当前主流)JDK17 是 Spring Boot 3.x 的最低要求,稳定性好,现代语法支持增强
JDK212023LTS最新 LTS,支持更多语言特性(如模式匹配、虚拟线程等),但部分框架支持仍在完善

(2)为何选择 LTS 版本
  • **长期支持(LTS)**版本通常每三年发布一次,官方和社区提供更长周期的安全更新与 bug 修复。

  • 对于企业级微服务系统,LTS 是最佳选择,避免频繁升级带来的风险与成本。

  • 非 LTS 版本(如 JDK9、JDK13)生命周期短,适合尝鲜,不适合生产。


(3)JDK 与 Spring Boot / Spring Cloud 兼容性对照表
Spring Boot 版本支持的最低 JDKSpring Cloud 版本推荐 JDK 版本
2.3.x ~ 2.7.xJDK8Hoxton / 2020.x / 2021.xJDK8 / JDK11
3.0.x ~ 最新JDK172022.x / 2023.x / 2024.xJDK17+
  • Spring Boot 3.x 是一次重大版本升级:

    • 移除对 JDK8 和 JDK11 的支持

    • 依赖 Jakarta EE 9(包名变更),与旧项目不兼容

  • 使用 Spring Boot 3.x + Spring Cloud 202x.x 版本,必须选择 JDK17 或更高版本


总结建议
  • 初学者或新项目推荐直接使用 JDK17(LTS)

  • 有长期维护计划的企业项目建议选择 JDK17 或 JDK21

  • 老项目如使用 Spring Boot 2.x,可继续使用 JDK8 / JDK11,但建议预留升级路径


为何选择 JDK17

1. Spring Boot 3.x 的最低要求

自 Spring Boot 3.0 起,官方已明确要求 最低 JDK 版本为 17,原因包括:

  • Spring Framework 6 基于 Jakarta EE 9+(包名由 javax.* 改为 jakarta.*),需要更现代的 Java 环境支持;

  • JDK8/11 已无法满足 Spring 生态的长期发展需求;

  • Spring Boot 3.0 起全面提升性能、安全标准,需 JDK17 提供底层支持。


2. JDK17 的优势
维度优势说明
语法支持支持 sealed classes、records、switch 增强(preview) 等现代特性
性能优化改进 GC、类数据共享、JIT 编译器等,提升启动速度与运行时效率
安全性更强的默认模块封装和类访问控制,降低依赖泄漏和反射攻击风险
稳定性属于 LTS(长期支持)版本,官方和大多数云平台提供稳定支持
兼容性已被大多数主流框架支持:Spring Boot 3.x、Spring Cloud、MyBatis、Hibernate 等

3. 生产环境成熟度

JDK17 自 2021 年发布以来,已经经过多个版本修复和稳定迭代,适用于大中型微服务系统的生产部署。很多主流云服务平台(如 AWS、Alibaba Cloud)均默认提供 JDK17 运行环境。


实操指南:安装与配置 JDK17

1. 安装方式

可根据操作系统选择合适的方式安装:

  • Windows

    • 推荐使用 Adoptium 提供的 MSI 安装包(Temurin 是开源且稳定的分发版本)

    • 安装过程中可勾选自动配置环境变量选项

  • macOS

    • 使用 Homebrew 安装:

      brew install openjdk@17
      

      然后添加环境变量:

      echo 'export PATH="/opt/homebrew/opt/openjdk@17/bin:$PATH"' >> ~/.zshrc
      echo 'export JAVA_HOME="/opt/homebrew/opt/openjdk@17"' >> ~/.zshrc
      source ~/.zshrc
      
  • Linux(Ubuntu / CentOS)

    • Ubuntu 示例:

      sudo apt update
      sudo apt install openjdk-17-jdk
      
    • CentOS 示例:

      sudo yum install java-17-openjdk-devel
      
2. 官方下载链接
  • OpenJDK 17 官方页面:JDK 17 Releases


3. 环境变量配置(通用说明)
  • 设置 JAVA_HOME 环境变量:

    • Windows:设置为 C:\Program Files\Java\jdk-17

    • macOS/Linux:通常为 /opt/homebrew/opt/openjdk@17/usr/lib/jvm/java-17-openjdk

  • $JAVA_HOME/bin 加入到 PATH

这方面不懂得可以看 第一段代码 (大佬写的博客):

Java基础1-环境篇:JDK安装与环境变量配置-CSDN博客


4. 验证安装成功

打开终端或命令行,执行以下命令验证:

java -version

输出示例:

java version "17.0.9" 2024-04-16 LTS
OpenJDK Runtime Environment (build 17.0.9+9)
OpenJDK 64-Bit Server VM (build 17.0.9+9, mixed mode, sharing)
javac -version

输出示例:

javac 17.0.9

2. MySQL 安装

微服务背景下数据库的角色

在传统的单体应用架构中,所有模块通常共享一个数据库。这种模式虽然方便集中管理,但在 可维护性、可扩展性和部署隔离性 上存在明显短板。

而在微服务架构中,数据库不再是全局共享资源,而是服务内部的组成部分。每个服务不仅是代码独立、部署独立,其数据也应当是独立的,这被称为 服务自治(Service Autonomy)原则


1. 每个微服务拥有独立的数据源
  • 每个微服务拥有自己的数据库实例或数据库 schema,不直接访问其他服务的数据

  • 服务之间通过 API / 消息中间件 进行数据交互,而不是跨库查询;

  • 这种模式可以有效避免服务间耦合、数据一致性强依赖等问题。

优点

  • 数据结构可以根据服务需求灵活调整

  • 服务间无需协调即可独立升级或迁移数据库

  • 降低数据库访问冲突和锁表风险

代价

  • 带来分布式事务、数据同步等额外挑战(需依赖 MQ、事件总线或 Saga 模式等)


2. 数据库按业务模块划分(示例)

假设我们正在开发一个电商系统,其中包含以下服务:

微服务数据库示例说明
用户服务user_service_db存储用户信息、登录凭证、注册信息等
订单服务order_service_db存储订单主表、订单项、支付状态等
商品服务product_service_db商品目录、库存、分类、价格等
支付服务payment_service_db第三方支付记录、交易日志等

这种划分方式能确保每个服务对自己的数据拥有完全控制权,同时提升整体系统的解耦度与可扩展性。


3. 服务间数据同步的正确姿势

若某服务需要依赖另一个服务的数据,不应直接访问其数据库,而应:

  • 调用对方服务提供的 RESTful API / RPC 接口

  • 使用 消息队列(如 Kafka / RabbitMQ) 异步监听数据变更

  • 通过 缓存(如 Redis) 实现数据同步副本供只读访问


MySQL 安装指南

在微服务项目中,MySQL 作为关系型数据库的主流选择,兼具 易用性、稳定性和社区支持,非常适合中小型系统的数据存储需求。


1. 推荐版本:MySQL 8.x
  • 为何推荐 MySQL 8.x?

    • 原生支持 JSON 字段与函数,方便微服务传输结构化数据

    • 更强的性能优化(如更高效的索引、查询计划优化器)

    • 默认字符集为 utf8mb4,支持完整 Unicode(含 Emoji)

    • 安全性提升:默认密码策略、角色权限模型更完善

  • 版本兼容提醒

    • Spring Boot 3.x 默认使用 mysql-connector-j 8.x 驱动,推荐配套使用 MySQL 8.x 服务端

    • 若仍使用 MySQL 5.x,需手动调整 JDBC 配置(如 useSSL, serverTimezone


2. 适配系统安装方式
Windows 系统
  • 安装方式

    • 前往官网下载安装程序:https://dev.mysql.com/downloads/installer/

    • 推荐选择:MySQL Installer (Community Edition),支持一键安装 Server + Workbench + Shell

  • 安装建议

    • 自定义安装路径(避免带空格的目录)

    • 初始配置时设置好 root 密码、默认端口(3306)与字符集(选 utf8mb4_general_ci

  • 自动服务启动

    • 可配置为开机自动启动 MySQL 服务

macOS 系统
  • 推荐方式:使用 Homebrew 安装

    brew update
    brew install mysql
    brew services start mysql
    
  • 初始化与登录

    mysql_secure_installation  # 安全配置向导,设置 root 密码等
    mysql -u root -p           # 登录 MySQL
    
  • Homebrew 路径问题提示

    • 若命令不可用,尝试添加 PATH:

      echo 'export PATH="/opt/homebrew/opt/mysql/bin:$PATH"' >> ~/.zshrc
      source ~/.zshrc
      
Linux 系统
  • Ubuntu / Debian 系

    sudo apt update
    sudo apt install mysql-server
    sudo systemctl start mysql
    sudo mysql_secure_installation
    
  • CentOS / RedHat

    sudo yum install @mysql
    sudo systemctl start mysqld
    sudo grep 'temporary password' /var/log/mysqld.log
    sudo mysql_secure_installation
    
  • 默认安装后使用 mysql -u root -p 登录,建议立即修改 root 密码、禁用匿名用户等。


✅ 小贴士:确认安装成功
mysql --version

示例输出:

mysql  Ver 8.0.36 for Linux on x86_64 (MySQL Community Server - GPL)

 没有安装的可以看博主之前写的博客:

MYSQL_安装与配置(超详细,仅需一篇就能帮你成功安装MYSQL)-CSDN博客


数据库初始化配置

MySQL 安装完成后,为了支持微服务场景中的多语言、Emoji、连接池高并发等需求,需要对数据库进行一定的初始化配置。以下是推荐的配置实践。


1. 设置默认字符集为 utf8mb4
  • utf8mb4 是真正支持完整 Unicode 的字符集,兼容 Emoji 和多国语言字符。

  • 默认字符集在 MySQL 8.x 中已从 latin1 提升为 utf8mb4,但仍建议手动确认或设置:

修改配置文件(通常位于 /etc/my.cnf/etc/mysql/my.cnf):

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci

重启 MySQL 服务后执行:

SHOW VARIABLES LIKE 'character_set%';

确认输出中 character_set_servercharacter_set_databaseutf8mb4


2. 创建数据库用户与权限配置

示例 SQL:为微服务创建独立用户并开放访问权限(仅用于开发环境,生产建议最小权限原则)

-- 创建用户,% 表示可远程访问(建议配合防火墙控制 IP 白名单)
CREATE USER 'microservice_user'@'%' IDENTIFIED BY 'strongpassword';-- 授予所有库所有表的所有权限(仅限开发或测试环境)
GRANT ALL PRIVILEGES ON *.* TO 'microservice_user'@'%';-- 使权限变更生效
FLUSH PRIVILEGES;

提示:在生产环境中,请仅授予最小必要权限,例如:

GRANT SELECT, INSERT, UPDATE, DELETE ON `user_service_db`.* TO 'microservice_user'@'%';

3. 防止常见连接报错的参数配置

在开发和部署过程中,常会遇到如下连接报错或行为异常,可通过以下参数配置优化:

报错 / 问题建议设置
Too many connectionsmax_connections = 200(根据并发需求调整)
SQL 模式太严格(如禁止 null)sql_mode 设为简化版本
默认密码插件导致连接失败使用 caching_sha2_password 替代旧密码插件

示例配置(添加到 my.cnf 中):

[mysqld]
max_connections = 200
sql_mode = STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
default_authentication_plugin = caching_sha2_password

重启 MySQL 生效:

sudo systemctl restart mysql

✅ 最后检查:确认配置生效
SHOW VARIABLES WHERE Variable_name IN ('character_set_server', 'max_connections', 'sql_mode');

示例输出:

character_set_server | utf8mb4
max_connections      | 200
sql_mode             | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION

. 微服务架构核心概念:服务拆分

1. 电商平台案例引入

以京东为例拆解核心功能模块

假设我们正在构建一个类似京东的电商平台,其核心业务功能大致可划分为以下模块:

功能模块说明
用户服务注册、登录、实名认证、账户管理等
商品服务商品发布、上下架、分类、详情、价格、库存等
搜索服务支持关键词搜索、筛选排序、热搜推荐、搜索联想等
订单服务创建订单、订单状态流转、取消订单、售后申请等
支付服务支持多种支付方式(如微信、支付宝、银行卡),支付回调等
评论服务用户对商品的评价内容管理
物流服务订单配送进度查询、快递单号追踪等
营销服务优惠券、满减、积分、秒杀、推荐算法等


传统单体架构的痛点

在早期开发中,这些模块可能会被统一封装在一个大型单体系统中,例如:

电商系统(单体)  
├── user.controller.java  
├── order.controller.java  
├── product.service.java  
├── search.utils.java  
├── 全部模块部署在同一个 WAR 包中

虽然开发初期看起来“方便快速”,但随着业务增长,很快会暴露出一系列问题:

痛点描述
代码臃肿所有业务逻辑集中在一个项目中,类数量剧增,模块边界模糊
维护困难一个小功能的修改可能波及大量模块,容易产生 Bug
部署频繁冲突任一模块改动都需整体打包部署,无法独立发布
扩展受限各模块资源争用严重,难以实现弹性伸缩(如高并发搜索拖慢下单功能)
技术架构难以演进不同模块对技术栈或性能的要求不同,单体架构下难以引入异构技术

为何要拆分成微服务?

通过 服务拆分(Service Decomposition),我们将单体应用中不同领域的业务逻辑,按照职责边界清晰的服务进行重构,每个服务成为独立运行、部署、维护的单元。


一、业务驱动:应对复杂业务的必然选择
1. 业务复杂度失控
  • 场景:传统单体架构中,电商平台的用户、订单、商品、支付等功能耦合在一个代码库中,代码量超百万行,新增 “会员积分” 功能需修改用户、订单、营销等多个模块,开发周期从 2 周延长至 1 个月。
  • 微服务价值
    • 职责隔离:将会员积分独立为 “积分服务”,仅负责积分规则计算与存储,其他服务通过 API 调用,开发周期缩短至 3 天。
    • 试错成本低:新业务(如社交分享功能)可独立部署为 “社交服务”,失败时直接下线,不影响核心交易流程。
2. 业务快速迭代需求
  • 场景:互联网业务需频繁发布新功能(如电商大促期间每日上线促销活动),单体架构每次发布需全量测试,导致凌晨发布窗口延长至 4 小时,影响用户体验。
  • 微服务价值
    • 独立发布:促销相关的 “营销服务” 可每日凌晨快速更新,其他服务(如用户、支付)保持稳定运行。
    • 灰度发布:新功能先在 10% 的用户流量中验证,问题修复不影响全量用户。
二、技术驱动:突破单体架构的技术瓶颈
1. 技术栈僵化与创新受限
  • 场景:传统单体架构使用老旧技术栈(如 Spring Framework 4.x + MyBatis 2.x),难以引入新框架(如 Spring Boot 3.x + Kotlin),技术债务累积导致维护成本激增。
  • 微服务价值
    • 技术异构:新服务可独立采用新技术(如用 Go 重构支付服务,用 Python 开发数据分析服务),老服务逐步迁移,避免 “颠覆性重构” 风险。
    • 性能优化针对性:高并发的 “商品搜索服务” 可采用 Elasticsearch+Reactive 编程模型,低延迟的 “订单服务” 保留传统数据库 + 同步模型。
2. 扩展性与稳定性瓶颈
  • 场景:电商大促期间,商品详情页流量激增 500%,但单体架构无法单独扩容 “商品查询” 功能,只能整体升级服务器,成本增加 3 倍且响应时间仍超时。
  • 微服务价值
    • 按需扩容:仅对 “商品服务” 增加 10 个实例,其他服务(如用户、物流)维持原有资源,成本降低 60% 且响应时间从 500ms 降至 100ms。
    • 故障隔离:商品服务因缓存击穿导致内存溢出时,自动重启该服务实例,用户、订单等其他服务正常运行,系统可用性从 99% 提升至 99.9%。
三、团队驱动:匹配敏捷开发与组织架构
1. 团队协作效率低下
  • 场景:千人开发团队共同维护单体代码库,分支冲突日均超 100 次,代码评审耗时从 2 小时延长至 8 小时,需求交付周期从 2 周延长至 1 个月。
  • 微服务价值
    • 康威定律适配:按服务拆分为独立团队(如用户团队、订单团队),每个团队负责 1-2 个服务,沟通成本降低 70%,分支冲突减少 90%。
    • 自治交付流程:每个团队拥有独立的 CI/CD 流水线,可自主决定发布节奏,需求平均交付周期缩短至 3 天。
2. 技术责任清晰化
  • 场景:单体架构中,“用户登录缓慢” 问题需跨多个模块排查(如认证模块、数据库、缓存),定位问题耗时 2 天,责任归属不明确。
  • 微服务价值
    • 责任边界清晰:登录问题直接归属 “用户服务” 团队,该团队可独立排查服务代码、数据库索引、接口性能,问题定位时间缩短至 2 小时。
    • 技术所有权:团队对所负责的服务技术选型、架构设计完全负责,提升技术决策效率与团队成就感。
四、微服务的核心优势总结
维度单体架构痛点微服务解决方案
复杂度管理模块耦合导致 “牵一发而动全身”单一职责拆分,每个服务逻辑独立
扩展性无法局部扩容,资源浪费严重按需扩展单个服务,支持弹性伸缩
技术演进技术栈固化,难以引入新技术支持异构技术,老服务逐步平滑迁移
团队效率协作成本高,需求交付周期长按服务拆分为小团队,敏捷开发更高效
稳定性单点故障导致全局不可用服务自治与故障隔离,局部失败不扩散
五、何时不适合拆分微服务?

微服务并非银弹,以下场景需谨慎考虑:

  1. 简单小型项目:如内部工具、单业务应用,拆分成本可能高于收益。
  2. 强事务一致性场景:如金融交易核心系统,跨服务事务实现复杂(需引入 TCC/Saga 等模式)。
  3. 团队规模小或技术能力不足:缺乏 DevOps 工具链与分布式系统经验,可能导致 “服务爆炸” 与运维混乱。

2. 服务拆分原则与实践

微服务架构的关键之一在于 合理拆分服务边界,否则将陷入“伪微服务”陷阱——系统虽然看似模块化,实则高度耦合、维护困难。因此,遵循科学的服务拆分原则,是构建稳定微服务体系的前提。


1. 单一职责原则:每个微服务专注一个业务领域
  • 每个微服务应对应一个清晰的业务边界,避免“大而全”或“多而碎”。

  • 拆分参考维度:

    • 业务领域模型(DDD):如用户、订单、库存、营销

    • 组织结构:一个团队负责一个服务,便于治理与协作

    • 生命周期差异:变更频率不同的模块应分开(如搜索 vs 支付)

示例:

  • UserService: 只处理用户注册、认证、账户管理

  • OrderService: 只负责下单、支付流程、订单状态流转


2. 服务自治:独立开发、测试、部署
  • 每个服务应具备“自给自足”的能力,包括:

    • 独立的数据库 Schema(避免跨库 JOIN)

    • 独立的配置文件与依赖管理(Spring Boot 配置分离)

    • 独立部署与版本管理(如通过 Docker、K8s 部署)

🎯 目标:不影响其他服务的前提下,任何服务都能独立上线或回滚。


3. 单向依赖:避免循环依赖,简化调用关系
  • 微服务之间应该建立清晰的调用链条,尽量避免双向调用(A ↔ B)

  • 推荐设计成 单向依赖(A → B) 或通过事件驱动进行解耦。

📌 错误示例:

用户服务 A → 订单服务 B → 用户服务 A   ❌ 形成循环依赖,难以维护

推荐方式:

  • 使用消息队列或事件总线解耦,例如订单服务发布“订单已创建”事件,用户服务异步监听并更新积分。

依赖关系图示意:

正确设计(单向):
A → B → C错误设计(循环):
A → B → A

4. 业界经验:合适优于先进,避免过度设计
  • 微服务不是越小越好,过度拆分会导致:

    • 调用链复杂、调试困难

    • 网络通信成本上升

    • 运维压力加大(每个服务都要部署、监控)

🎯 经验总结

  • 不盲目追求“微粒度”,而应按需拆分,确保每个服务能被有效拥有、维护、监控

  • 拆分标准应结合业务成熟度、团队能力与组织架构。

“架构的第一原则,不是先进,而是合适。”


3. 拆分示例:订单与商品服务

在微服务架构中,“订单服务”与“商品服务”是电商平台中的核心组成部分。二者职责明确、调用频率高,但业务边界清晰,适合做为微服务拆分的典型案例。


1. 订单服务职责:专注订单生命周期管理
  • 处理用户下单请求

  • 管理订单状态(如:已创建、已支付、已发货、已完成、已取消)

  • 与商品服务交互,引用商品 ID,但不直接保存商品详情

  • 与支付服务、物流服务等后续模块协作

✅ 示例:

{"orderId": "ORD2024060001","userId": 10001,"productId": 20009,"quantity": 2,"status": "PAID"
}
2. 商品服务职责:专注商品信息维护与查询
  • 管理商品的基本信息、价格、库存

  • 支持商品详情查询、分类管理、上下架操作

  • 对外提供商品详情接口供订单服务、搜索服务等调用

✅ 示例:

{"productId": 20009,"name": "机械键盘","price": 399.00,"stock": 120,"status": "AVAILABLE"
}
3. 数据库拆分:cloud_order 与 cloud_product 独立建表

按照“服务自治”原则,每个服务拥有自己的数据库,分别命名为:

  • cloud_order(订单服务)

  • cloud_product(商品服务)

📦 订单服务建表语句(cloud_order.orders

-- 建库 
create database if not exists cloud_order charset utf8mb4;
-- 订单表 
DROP TABLE IF EXISTS order;
CREATE TABLE order_detail (`id` INT NOT NULL AUTO_INCREMENT COMMENT '订单id',`user_id` BIGINT ( 20 ) NOT NULL COMMENT '⽤⼾ID',`product_id` BIGINT ( 20 ) NULL COMMENT '产品id',`num` INT ( 10 ) NULL DEFAULT 0 COMMENT '下单数量',`price` BIGINT ( 20 ) NOT NULL COMMENT '实付款',`delete_flag` TINYINT ( 4 ) NULL DEFAULT 0,`create_time` DATETIME DEFAULT now(),`update_time` DATETIME DEFAULT now(),
PRIMARY KEY ( id )) ENGINE = INNODB DEFAULT CHARACTER 
SET = utf8mb4 COMMENT = '订单表';创建数据
INSERT INTO order_detail (user_id, product_id, num, price, delete_flag, create_time, update_time)
VALUES-- 用户1001的有效订单(delete_flag=0)(1001, 2001, 1, 9800, 0, '2024-01-01 10:00:00', '2024-01-01 10:00:00'), -- 购买T恤1件,实付98元(1001, 2003, 2, 24000, 0, '2024-01-03 14:30:00', '2024-01-03 14:30:00'), -- 购买短裤2件,实付240元(单价120元)-- 用户1002的有效订单(delete_flag=0)(1002, 2002, 3, 9000, 0, '2024-01-02 09:15:00', '2024-01-02 09:15:00'), -- 购买短袖3件,实付90元(单价30元)(1002, 2005, 1, 9800, 0, '2024-01-04 16:45:00', '2024-01-04 16:45:00'), -- 购买马甲1件,实付98元-- 用户1003的已删除订单(delete_flag=1)(1003, 2004, 1, 5800, 1, '2024-01-05 11:20:00', '2024-01-05 15:00:00'), -- 购买卫衣1件,实付58元,已删除(1003, 2006, 2, 18800, 1, '2024-01-06 13:00:00', '2024-01-06 17:30:00'), -- 购买羽绒服2件,实付188元,已删除-- 批量测试数据(模拟大促订单)(1004, 2007, 5, 15000, 0, '2024-01-11 08:30:00', '2024-01-11 08:30:00'), -- 冲锋衣5件,实付150元(1005, 2008, 10, 4400, 0, '2024-01-12 14:10:00', '2024-01-12 14:10:00'), -- 袜子10件,实付44元(5双装单价39元,此处模拟优惠后价格)(1001, 2009, 2, 11600, 0, '2024-01-13 11:00:00', '2024-01-13 11:00:00'), -- 鞋子2双,实付116元(1002, 2010, 1, 9800, 0, '2024-01-14 15:40:00', '2024-01-14 15:40:00'); -- 毛衣1件,实付98元

📦 商品服务建表语句(cloud_product.products

create database if not exists cloud_product charset utf8mb4;
-- 产品表 
DROP TABLE IF EXISTS product;
CREATE TABLE product_detail (`id` INT NOT NULL AUTO_INCREMENT COMMENT '产品id',`product_name` varchar ( 128 ) NULL COMMENT '产品名称',`product_price` BIGINT ( 20 ) NOT NULL COMMENT '产品价格',`state` TINYINT ( 4 ) NULL DEFAULT 0 COMMENT '产品状态 0-有效 1-下架',`create_time` DATETIME DEFAULT now(),`update_time` DATETIME DEFAULT now(),
PRIMARY KEY ( id )) ENGINE = INNODB DEFAULT CHARACTER 
SET = utf8mb4 COMMENT = '产品表';数据初始化
INSERT INTO product_detail (product_name, product_price, state, create_time, update_time)
VALUES-- 有效商品(state=0)('纯棉圆领T恤', 9800, 0, '2023-12-01 10:00:00', '2023-12-01 10:00:00'),('冰丝短袖衬衫', 15800, 0, '2023-12-02 14:30:00', '2023-12-05 09:00:00'),('宽松牛仔短裤', 12800, 0, '2023-12-03 16:15:00', '2023-12-03 16:15:00'),('连帽卫衣', 19800, 0, '2023-12-04 08:45:00', '2023-12-04 08:45:00'),('加绒休闲裤', 22800, 0, '2023-12-05 11:20:00', '2023-12-05 11:20:00'),('中长款羽绒服', 89800, 0, '2023-12-06 13:00:00', '2023-12-06 13:00:00'),('防水冲锋衣', 59800, 0, '2023-12-07 15:40:00', '2023-12-07 15:40:00'),('运动老爹鞋', 39800, 0, '2023-12-08 09:30:00', '2023-12-08 09:30:00'),('纯棉袜子(5双装)', 3900, 0, '2023-12-09 14:10:00', '2023-12-09 14:10:00'),('羊毛围巾', 15800, 0, '2023-12-10 11:00:00', '2023-12-10 11:00:00'),-- 下架商品(state=1)('旧款打底衫', 5800, 1, '2023-11-25 09:00:00', '2023-12-01 00:00:00'),('断码运动鞋', 19900, 1, '2023-11-30 14:20:00', '2023-12-02 00:00:00'),('季节性凉鞋', 8800, 1, '2023-11-28 16:30:00', '2023-12-03 00:00:00'),('清仓羽绒服', 49800, 1, '2023-12-01 10:00:00', '2023-12-05 00:00:00'),('样品毛衣', 12800, 1, '2023-12-02 11:15:00', '2023-12-06 00:00:00');

四、Maven 父子工程搭建 

1. 父工程配置

一、父工程核心作用:统一依赖管理

1. 避免依赖冲突

通过父工程集中定义依赖版本,确保子工程使用一致的库版本,避免出现 “同一个依赖不同子工程版本不一致” 导致的类冲突(如 Spring Boot Starter 与 Spring Cloud 组件版本不兼容)。

2. 简化子工程配置

子工程无需重复声明版本号,直接继承父工程的依赖配置,减少冗余代码,提升维护效率。例如:

  • 父工程定义spring-boot.version=3.1.6,子工程只需声明spring-boot-starter-web依赖,无需指定版本。
3. 技术栈统一管理

集中控制项目的技术栈(如 JDK 版本、构建插件、基础框架),确保团队所有成员使用一致的开发环境。

二、pom.xml关键配置解析

1. dependencyManagement vs dependencies
配置项dependencyManagementdependencies
功能定位声明依赖版本(但不实际引入)实际引入依赖到项目
子工程继承行为子工程需显式声明依赖才能使用子工程自动继承并包含依赖
版本覆盖规则子工程可覆盖声明的版本子工程需排除父依赖后再引入新版本
使用场景统一管理依赖版本(如 Spring Boot)明确需要引入的依赖(如 Lombok)
  • 误用dependencyManagement

    • 错误做法:在父工程dependencyManagement中声明所有依赖,但子工程忘记显式声明,导致依赖未引入。
    • 正确做法:仅在dependencyManagement中声明版本,在dependencies中实际引入依赖。
  • 忽略依赖传递性

    • 问题:父工程引入的依赖通过传递性影响子工程,但未显式声明,导致调试困难。
    • 检查方法:使用mvn dependency:tree命令查看依赖树,确认依赖来源。
  • 版本冲突排查

    • 症状:编译时报类找不到或版本不兼容错误。

三 、工程创建

 创建⽗⼯程 : 创建⼀个空的Maven项⽬,删除所有代码,只保留pom.xml
 ⽬录结构:

2. 完善pom⽂件

使⽤properties来进⾏版本号的统⼀管理,使⽤dependencyManagement来管理依赖,声明⽗⼯程的打 包⽅式为pom 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>spring-cloud-demo</artifactId><version>1.0-SNAPSHOT</version><modules><module>order-service</module><module>product-service</module></modules><packaging>pom</packaging><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.6</version><relativePath/> <!-- lookup parent from repository --></parent><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><java.version>17</java.version><mybatis.version>3.0.3</mybatis.version><mysql.version>8.0.33</mysql.version><spring-cloud-alibaba.version>2022.0.0.0-RC2</spring-cloud-alibaba.version><spring-cloud.version>2022.0.3</spring-cloud.version></properties><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.version}</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>${mysql.version}</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter-test</artifactId><version>${mybatis.version}</version><scope>test</scope></dependency></dependencies></dependencyManagement></project>

3. 创建⼦项⽬-订单服务

 声明项⽬依赖和项⽬构建插件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>spring-cloud-demo</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>order-service</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><dependency> <groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-bootstrap --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId><version>3.0.3</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-loadbalancer</artifactId></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency></dependencies><profiles><profile><id>dev</id><properties><profile.name>dev</profile.name></properties></profile><profile><id>prod</id><properties><profile.name>prod</profile.name></properties></profile></profiles><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins><resources><resource><directory>src/main/resources</directory><filtering>true</filtering><includes><include>**/**</include></includes></resource></resources></build></project>

4 创建⼦项⽬-商品服务

 声明项⽬依赖和项⽬构建插件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>spring-cloud-demo</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>product-service</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><dependency> <groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!-- SpringCloud 2020.*之后版本需要引⼊bootstrap--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-loadbalancer</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-bootstrap --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId><version>3.0.3</version></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency></dependencies><profiles><profile><id>dev</id><properties><profile.name>dev</profile.name></properties></profile><profile><id>prod</id><properties><profile.name>prod</profile.name></properties></profile></profiles><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins><resources><resource><directory>src/main/resources</directory><filtering>true</filtering><includes><include>**/**</include></includes></resource></resources></build></project>

5 完善订单服务

完善启动类,配置⽂件
package com.bite.order;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class OrderServiceApplication {public static void main(String[] args) {SpringApplication.run(OrderServiceApplication.class, args);}
}
配置⽂件 application.yml
server:port: 8080
spring:application:name: order-serviceprofiles:active: @profile.name@datasource:url: jdbc:mysql://127.0.0.1:3306/cloud_order?characterEncoding=utf8&useSSL=falseusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver
业务代码

实体类

package com.bite.order.model;import lombok.Data;import java.util.Date;@Data
public class OrderInfo {private Integer id;private Integer userId;private Integer productId;private Integer num;private Integer price;private Integer deleteFlag;private Date createTime;private Date updateTime;private ProductInfo productInfo;
}

Controller  

package com.bite.order.controller;import com.bite.order.model.OrderInfo;
import com.bite.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RequestMapping("/order")
@RestController
public class OrderController {@Autowiredprivate OrderService orderService;@RequestMapping("/{orderId}")public OrderInfo getOrderById(@PathVariable("orderId") Integer orderId){return orderService.selectOrderById(orderId);}
}

Service 

import com.bite.order.mapper.OrderMapper;
import com.bite.order.model.OrderInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;
public OrderInfo selectOrderById(Integer orderId) {OrderInfo orderInfo = orderMapper.selectOrderById(orderId);return orderInfo;}
}

Mapper  

import com.bite.order.model.OrderInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface OrderMapper {@Select("select * from order_detail where id=#{orderId}")OrderInfo selectOrderById(Integer orderId);
}
测试

访问url:http://127.0.0.1:8080/order/1

⻚⾯正常返回结果:

6 完善商品服务  

与上面 完善订单服务 的代码差不多一样 ,可以对照这写,要注意的是端口号不能设一样的,数据库要改一下,实体类的表对照着商品的数据库写,其他的没啥不一样了,这里我就不多写商品服务的代码了

结语:在实践中深化对微服务架构的理解

至此,我们完成了从 Spring Cloud 开发环境搭建到微服务项目实战的全流程探索。这一路径不仅是技术栈的实践,更是对分布式架构思维的系统性训练。以下从核心收获、实践建议和未来方向三个维度,为本次学习之旅做阶段性总结。

一、核心收获:从理论到代码的架构思维升级
  1. 微服务设计原则的落地
    通过电商案例的服务拆分(订单 / 商品服务),我们深入理解了单一职责(每个服务专注独立业务)、服务自治(独立数据库与部署)、单向依赖(避免循环调用)的实践逻辑。例如,订单服务仅通过商品 ID 关联商品服务接口,而非直接操作数据库,确保了服务边界清晰。

  2. Maven 父子工程的依赖管理哲学

    • dependencyManagement 如同 “中央控制室”,统一管理 Spring Boot、Spring Cloud 等核心组件版本,避免子工程依赖冲突。
    • dependencies 则是 “执行器”,按需引入 Lombok、MyBatis 等具体依赖,实现 “版本中央控制,依赖按需加载” 的高效模式。
  3. 跨服务调用的基础实现
    通过 RestTemplate 完成订单服务与商品服务的联动,我们掌握了微服务间通信的基本范式:基于 HTTP 协议的同步调用、数据格式转换(如 JSON 序列化)和接口契约管理(如 URL 路径规范)。

二、实践建议:避坑指南与效率提升
  1. 开发环境的细节把控

    • JDK 版本锁定:务必使用 JDK17+,避免因版本过低导致 Spring Boot 3.x 特性无法使用(如虚拟线程)。
    • 数据库字符集统一:建表时指定utf8mb4字符集,确保对 emoji 等特殊字符的支持,避免乱码问题。
  2. 代码结构的规范化

    • 分层清晰性:严格遵循 “Controller→Service→Mapper” 分层,避免业务逻辑泄漏到 Controller 层。例如,订单服务的OrderController仅负责接收请求和返回结果,具体业务逻辑封装在OrderService中。
    • 实体类轻量化:避免在实体类中添加非必要字段(如冗余的关联数据),保持 POJO 的纯粹性。
  3. 测试与验证的系统性

    • 单服务测试先行:使用 Postman 或 Swagger 验证单个接口(如/product/{id})的正确性,确保返回数据格式与预期一致。
    • 跨服务链路测试:通过组合调用(如订单查询触发商品信息获取),验证数据整合逻辑的可靠性,例如检查订单结果中是否正确嵌套商品名称和价格。
三、未来方向:从基础到进阶的技术图谱

当前项目仅实现了微服务架构的 “Hello World” 级演示,要应对真实生产环境,还需深入探索 Spring Cloud 的核心组件:

  1. 服务治理:从静态到动态的服务管理

    • 服务注册与发现:引入 Nacos 或 Eureka,将订单 / 商品服务注册到注册中心,避免硬编码 IP 和端口(如用product-service服务名替代127.0.0.1:9090)。
    • 负载均衡:通过 Ribbon 或 Spring Cloud LoadBalancer 实现商品服务多实例间的请求分发,提升系统吞吐量。
  2. 分布式基础设施:应对高并发与复杂性

    • 熔断与降级:使用 Hystrix 或 Resilience4j 防止服务雪崩,例如当商品服务不可用时,订单服务可返回缓存数据或友好提示。
    • 配置中心:通过 Spring Cloud Config 统一管理多环境配置(如开发 / 测试 / 生产环境的数据库 URL),避免敏感信息硬编码。
  3. 观测性与可维护性

    • 分布式链路追踪:集成 Sleuth+Zipkin,记录跨服务调用链路(订单服务→商品服务),快速定位性能瓶颈或故障点。
    • 日志聚合:使用 ELK Stack(Elasticsearch+Logstash+Kibana)集中管理各服务日志,支持按关键字、时间范围查询。
四、写在最后:微服务的本质是 “平衡的艺术”

微服务架构并非追求 “绝对的拆分” 或 “最先进的技术”,而是在业务复杂度、团队能力、系统稳定性之间寻找动态平衡点:

  • 初期:采用粗粒度拆分(如将用户与会员功能合并),快速验证业务逻辑;
  • 中期:随着流量增长,逐步细化服务(如拆分为用户服务、会员积分服务),引入负载均衡和熔断机制;
  • 长期:通过容器化(Docker+K8s)和云原生技术,实现服务的弹性扩缩容与自动化运维。

技术的价值始终在于解决实际问题。希望通过本次实战,你不仅掌握了 Spring Cloud 的基础开发流程,更能建立 “从问题出发设计架构” 的思维 —— 这正是应对未来技术挑战的核心能力。

下一步,让我们带着这些经验,深入探索 Spring Cloud 的服务注册与发现机制,开启真正的分布式系统之旅!

欢迎在评论区分享你的实践心得或遇到的问题,我们共同成长! 🌟

下期预告:

远程调用实现:RestTemplate 讲解

项目问题与 Spring Cloud 解决方案前瞻

总结与延伸学习

http://www.xdnf.cn/news/773335.html

相关文章:

  • 学到新的日志方法mp
  • vue router详解和用法
  • Windows10-ltsc-2019 使用 PowerShell 安装安装TranslucentTB教程(不通过微软商店安装)
  • PCA(K-L变换)人脸识别(python实现)
  • 二进制文件配置替换工具:跨平台大小端处理实践
  • 树莓派4B串口通讯
  • 地震资料裂缝定量识别——学习计划
  • hook组件-useEffect、useRef
  • Docker 镜像原理
  • MySQL DDL操作全解析:从入门到精通,包含索引视图分区表等全操作解析
  • <6>, 界面优化
  • 基于Python学习《Head First设计模式》第三章 装饰者模式
  • 线程池详细解析(二)
  • MCP还是A2A?AI未来技术选型深度对比分析报告
  • 程序设计实践期末考试模拟题(1)
  • JAVA核心知识点--元注解详解
  • pbootcms 搜索自定义字段模糊、精准搜索
  • SolidWorks建模(U盘)- 多实体建模拆图案例
  • 网络攻防技术三:网络脆弱性分析
  • 华为OD机试_2025 B卷_小华地图寻宝(Python,100分)(附详细解题思路)
  • 零基础学习计算机网络编程----socket实现UDP协议
  • 功能结构整理
  • python 如何写4或5的表达式
  • 瑞萨CS+ for CC V8.13.00环境安装教程
  • 网络攻防技术五:网络扫描技术
  • 《操作系统真相还原》——完善内核
  • mysql专题上
  • 中科院报道铁电液晶:从实验室突破到多场景应用展望
  • 快捷键插入函数
  • python爬虫:Ruia的详细使用(一个基于asyncio和aiohttp的异步爬虫框架)