1.分布式基础:从单体到集群到分布式架构
1.1 单体架构:
单体架构(Monolithic Architecture) 是最传统的软件架构模式,所有功能模块(如用户管理、订单处理、支付服务等)都打包在一个单一的应用程序中,共享同一个代码库、数据库和进程空间。
1.2 集群架构:水平扩展的初步尝试
当单体应用遇到性能瓶颈时,集群架构(Cluster Architecture) 成为自然的解决方案。集群通过在多台服务器上部署相同的应用实例,并使用负载均衡器分发请求,实现水平扩展。
核心组件:
- 负载均衡器(Load Balancer):如Nginx、HAProxy,负责将请求分发到不同的应用实例
- 应用实例集群:多个完全相同的应用实例运行在不同的服务器上
- 共享数据库:所有实例访问同一个数据库,保持数据一致性
挑战:
- 状态管理困难:用户会话状态需要在实例间共享(需引入Redis等分布式缓存)
- 数据库成为瓶颈:所有实例共享同一个数据库,容易成为性能瓶颈
- 配置管理复杂:需要确保所有实例配置一致
- 资源利用率不均 :静态负载均衡可能无法充分利用资源

1.3 分布式架构:解耦与专业化
分布式架构(Distributed Architecture) 将单体应用拆分为多个独立的、松耦合的服务,每个服务专注于特定的业务能力,可以独立开发、部署和扩展。

1.3.1 微服务架构
微服务是分布式架构的一种具体实现,具有以下特征:
- 服务自治:每个服务拥有独立的数据存储、业务逻辑和部署单元
- 技术多样性:不同服务可以使用最适合的技术栈
- 独立扩展:可以根据负载单独扩展某个服务
- 故障隔离:单个服务故障不会导致整个系统崩溃
1.3.2 分布式系统的核心挑战
-
网络通信不可靠
- 网络延迟、丢包、分区成为常态
- 需要处理超时、重试、熔断等机制
-
数据一致性难题
-
分布式事务
- 两阶段提交(2PC)
- 三阶段提交(3PC)
- 基于消息的最终一致性(Saga模式、TCC模式)
-
服务发现与治理
- 服务注册与发现(Consul、Eureka、Nacos)
- 负载均衡(客户端负载均衡、服务端负载均衡)
- 熔断降级(Hystrix、Sentinel)
-
分布式追踪与监控
- 调用链追踪(Zipkin、Jaeger、SkyWalking)
- 指标监控(Prometheus、Grafana)
- 日志聚合(ELK Stack、Loki)
1.4 架构演进对比
| 特性 | 单体架构 | 集群架构 | 分布式架构 |
|---|---|---|---|
| 扩展性 | 垂直扩展 | 水平扩展(应用层) | 细粒度水平扩展 |
| 部署单元 | 整个应用 | 整个应用 | 独立服务 |
| 技术栈 | 统一 | 统一 | 多样化 |
| 数据存储 | 共享数据库 | 共享数据库 | 独立数据存储 |
| 通信方式 | 本地调用 | 本地调用+负载均衡 | 网络调用(RPC/REST) |
| 故障影响 | 整个系统 | 部分请求 | 局部服务 |
| 开发复杂度 | 低 | 中 | 高 |
| 运维复杂度 | 低 | 中 | 高 |
1.5 实际演进路径示例
以一个电商系统为例:
- 初期(单体):所有功能(用户、商品、订单、支付)在一个Java应用中,使用MySQL数据库
- 成长期(集群):应用部署到3台服务器,前端使用Nginx负载均衡,会话状态存入Redis
- 成熟期(分布式) :
- 用户服务:Go语言,MongoDB存储
- 商品服务:Java,Elasticsearch索引
- 订单服务:Java,MySQL分库分表
- 支付服务:Python,PostgreSQL
- 服务间通过gRPC通信,使用Consul服务发现,Prometheus监控

1.6 分布式架构知识点演进流程图
以下以电商系统(包含商品、物流、用户、订单、直播、支付等功能)为例,展示分布式架构中关键知识点的演进路径、触发条件和核心变化:
#mermaid-svg-omq99llkO7lgmi8c{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-omq99llkO7lgmi8c .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-omq99llkO7lgmi8c .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-omq99llkO7lgmi8c .error-icon{fill:#552222;}#mermaid-svg-omq99llkO7lgmi8c .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-omq99llkO7lgmi8c .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-omq99llkO7lgmi8c .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-omq99llkO7lgmi8c .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-omq99llkO7lgmi8c .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-omq99llkO7lgmi8c .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-omq99llkO7lgmi8c .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-omq99llkO7lgmi8c .marker{fill:#333333;stroke:#333333;}#mermaid-svg-omq99llkO7lgmi8c .marker.cross{stroke:#333333;}#mermaid-svg-omq99llkO7lgmi8c svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-omq99llkO7lgmi8c p{margin:0;}#mermaid-svg-omq99llkO7lgmi8c .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-omq99llkO7lgmi8c .cluster-label text{fill:#333;}#mermaid-svg-omq99llkO7lgmi8c .cluster-label span{color:#333;}#mermaid-svg-omq99llkO7lgmi8c .cluster-label span p{background-color:transparent;}#mermaid-svg-omq99llkO7lgmi8c .label text,#mermaid-svg-omq99llkO7lgmi8c span{fill:#333;color:#333;}#mermaid-svg-omq99llkO7lgmi8c .node rect,#mermaid-svg-omq99llkO7lgmi8c .node circle,#mermaid-svg-omq99llkO7lgmi8c .node ellipse,#mermaid-svg-omq99llkO7lgmi8c .node polygon,#mermaid-svg-omq99llkO7lgmi8c .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-omq99llkO7lgmi8c .rough-node .label text,#mermaid-svg-omq99llkO7lgmi8c .node .label text,#mermaid-svg-omq99llkO7lgmi8c .image-shape .label,#mermaid-svg-omq99llkO7lgmi8c .icon-shape .label{text-anchor:middle;}#mermaid-svg-omq99llkO7lgmi8c .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-omq99llkO7lgmi8c .rough-node .label,#mermaid-svg-omq99llkO7lgmi8c .node .label,#mermaid-svg-omq99llkO7lgmi8c .image-shape .label,#mermaid-svg-omq99llkO7lgmi8c .icon-shape .label{text-align:center;}#mermaid-svg-omq99llkO7lgmi8c .node.clickable{cursor:pointer;}#mermaid-svg-omq99llkO7lgmi8c .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-omq99llkO7lgmi8c .arrowheadPath{fill:#333333;}#mermaid-svg-omq99llkO7lgmi8c .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-omq99llkO7lgmi8c .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-omq99llkO7lgmi8c .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-omq99llkO7lgmi8c .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-omq99llkO7lgmi8c .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-omq99llkO7lgmi8c .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-omq99llkO7lgmi8c .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-omq99llkO7lgmi8c .cluster text{fill:#333;}#mermaid-svg-omq99llkO7lgmi8c .cluster span{color:#333;}#mermaid-svg-omq99llkO7lgmi8c div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-omq99llkO7lgmi8c .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-omq99llkO7lgmi8c rect.text{fill:none;stroke-width:0;}#mermaid-svg-omq99llkO7lgmi8c .icon-shape,#mermaid-svg-omq99llkO7lgmi8c .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-omq99llkO7lgmi8c .icon-shape p,#mermaid-svg-omq99llkO7lgmi8c .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-omq99llkO7lgmi8c .icon-shape .label rect,#mermaid-svg-omq99llkO7lgmi8c .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-omq99llkO7lgmi8c .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-omq99llkO7lgmi8c .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-omq99llkO7lgmi8c :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 电商微服务拆分
用户服务
商品服务
订单服务
支付服务
物流服务
直播服务
单体架构
(电商系统初期)
业务增长触发
性能瓶颈
集群架构
水平扩展
负载均衡
(Nginx/HAProxy)
会话共享
(Redis/Session集群)
业务复杂度增加
团队协作需求
分布式架构
服务拆分
服务注册与发现
(Consul/Nacos/Eureka)
远程调用
(RPC/REST/gRPC)
数据库分库分表
(Sharding/读写分离)
分布式事务
(Seata/TCC)
配置中心
(Apollo/Nacos)
链路追踪
(SkyWalking/Jaeger)
云原生架构
(容器化/服务网格)
1.7 微服务核心组件关联流程图
以下展示微服务架构中SpringBoot应用与各核心组件(注册中心、网关、远程调用、服务熔断、分布式事务)之间的关联关系:
#mermaid-svg-rEelO3RTGEswHRyI{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rEelO3RTGEswHRyI .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rEelO3RTGEswHRyI .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rEelO3RTGEswHRyI .error-icon{fill:#552222;}#mermaid-svg-rEelO3RTGEswHRyI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rEelO3RTGEswHRyI .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rEelO3RTGEswHRyI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rEelO3RTGEswHRyI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rEelO3RTGEswHRyI .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rEelO3RTGEswHRyI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rEelO3RTGEswHRyI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rEelO3RTGEswHRyI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rEelO3RTGEswHRyI .marker.cross{stroke:#333333;}#mermaid-svg-rEelO3RTGEswHRyI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rEelO3RTGEswHRyI p{margin:0;}#mermaid-svg-rEelO3RTGEswHRyI .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-rEelO3RTGEswHRyI .cluster-label text{fill:#333;}#mermaid-svg-rEelO3RTGEswHRyI .cluster-label span{color:#333;}#mermaid-svg-rEelO3RTGEswHRyI .cluster-label span p{background-color:transparent;}#mermaid-svg-rEelO3RTGEswHRyI .label text,#mermaid-svg-rEelO3RTGEswHRyI span{fill:#333;color:#333;}#mermaid-svg-rEelO3RTGEswHRyI .node rect,#mermaid-svg-rEelO3RTGEswHRyI .node circle,#mermaid-svg-rEelO3RTGEswHRyI .node ellipse,#mermaid-svg-rEelO3RTGEswHRyI .node polygon,#mermaid-svg-rEelO3RTGEswHRyI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rEelO3RTGEswHRyI .rough-node .label text,#mermaid-svg-rEelO3RTGEswHRyI .node .label text,#mermaid-svg-rEelO3RTGEswHRyI .image-shape .label,#mermaid-svg-rEelO3RTGEswHRyI .icon-shape .label{text-anchor:middle;}#mermaid-svg-rEelO3RTGEswHRyI .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rEelO3RTGEswHRyI .rough-node .label,#mermaid-svg-rEelO3RTGEswHRyI .node .label,#mermaid-svg-rEelO3RTGEswHRyI .image-shape .label,#mermaid-svg-rEelO3RTGEswHRyI .icon-shape .label{text-align:center;}#mermaid-svg-rEelO3RTGEswHRyI .node.clickable{cursor:pointer;}#mermaid-svg-rEelO3RTGEswHRyI .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rEelO3RTGEswHRyI .arrowheadPath{fill:#333333;}#mermaid-svg-rEelO3RTGEswHRyI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rEelO3RTGEswHRyI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rEelO3RTGEswHRyI .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rEelO3RTGEswHRyI .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rEelO3RTGEswHRyI .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rEelO3RTGEswHRyI .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rEelO3RTGEswHRyI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rEelO3RTGEswHRyI .cluster text{fill:#333;}#mermaid-svg-rEelO3RTGEswHRyI .cluster span{color:#333;}#mermaid-svg-rEelO3RTGEswHRyI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rEelO3RTGEswHRyI .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rEelO3RTGEswHRyI rect.text{fill:none;stroke-width:0;}#mermaid-svg-rEelO3RTGEswHRyI .icon-shape,#mermaid-svg-rEelO3RTGEswHRyI .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rEelO3RTGEswHRyI .icon-shape p,#mermaid-svg-rEelO3RTGEswHRyI .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rEelO3RTGEswHRyI .icon-shape .label rect,#mermaid-svg-rEelO3RTGEswHRyI .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rEelO3RTGEswHRyI .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rEelO3RTGEswHRyI .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rEelO3RTGEswHRyI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 服务治理层
微服务集群
API网关层
客户端/前端
远程调用
远程调用
远程调用
触发熔断
触发熔断
触发熔断
触发熔断
参与分布式事务
参与分布式事务
远程调用层
Feign/OpenFeign
(声明式HTTP客户端)
gRPC/Dubbo
(高性能RPC)
REST Template
(传统HTTP调用)
服务注册与发现
Nacos/Eureka/Consul
注册中心
用户请求
Spring Cloud Gateway
或 Zuul
SpringBoot
用户服务
SpringBoot
商品服务
SpringBoot
订单服务
SpringBoot
支付服务
服务熔断
Hystrix/Sentinel
负载均衡
Ribbon/LoadBalancer
分布式事务
Seata/TCC/Saga
流程图解读:
- SpringBoot微服务:作为基础运行单元,每个服务独立部署
- 注册中心:服务启动时注册,消费方通过注册中心发现服务
- API网关:统一入口,处理路由、鉴权、限流等横切关注点
- 远程调用:服务间通信方式,支持HTTP/RPC等多种协议
- 服务熔断:防止雪崩效应,当服务不可用时快速失败
- 分布式事务:保证跨多个服务的业务操作一致性
这些组件共同构成了完整的微服务治理体系,确保系统的可用性、可扩展性和一致性。

2、创建微服务项目
2.1 项目规划与需求分析
在创建微服务项目前,首先需要明确业务需求和项目目标:
-
业务场景:假设我们要开发一个电商系统,包含用户管理、商品管理、订单管理和支付管理四个核心模块
-
服务拆分原则:
- 单一职责:每个服务只负责一个业务领域
- 独立部署:服务之间可以独立开发、测试、部署
- 数据自治:每个服务拥有自己的数据库
- 团队自治:每个服务可以由独立的团队负责
-
技术选型考虑:
- 开发语言:Java(Spring Boot)
- 服务框架:Spring Cloud
- 注册中心:Nacos/Eureka
- 配置中心:Nacos Config
- 网关:Spring Cloud Gateway
- 通信方式:RESTful API + Feign
- 数据库:MySQL + Redis缓存
- 消息队列:RabbitMQ/Kafka
2.2 环境准备与工具配置
2.2.1 开发环境要求
- JDK 11+
- Maven 3.6+
- Docker(可选,用于容器化部署)
- IDE:IntelliJ IDEA 或 VS Code
2.2.2 基础设施搭建
bash
# 1. 安装并启动Nacos(注册中心+配置中心)
docker run --name nacos -e MODE=standalone -p 8848:8848 -d nacos/nacos-server:2.0.3
# 2. 安装MySQL
docker run --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql:8.0
# 3. 安装Redis
docker run --name redis -p 6379:6379 -d redis:6.2
2.3 创建父工程与公共模块
2.3.1 创建父工程(pom.xml)
xml
<?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>com.example</groupId>
<artifactId>ecommerce-microservices</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/>
</parent>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2021.0.3</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version>
</properties>
<modules>
<module>ecommerce-common</module>
<module>ecommerce-gateway</module>
<module>ecommerce-user</module>
<module>ecommerce-product</module>
<module>ecommerce-order</module>
<module>ecommerce-payment</module>
</modules>
<dependencyManagement>
<dependencies>
<!-- Spring Cloud 版本控制 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud Alibaba 版本控制 (关键!) -->
<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>
</dependencies>
</dependencyManagement>
</project>
2.3.2 创建公共模块(ecommerce-common)
公共模块包含所有微服务共享的组件:
- 统一响应封装(Result)
- 全局异常处理
- 工具类(DateUtils、StringUtils等)
- 公共DTO和VO对象
- 自定义注解
2.4 创建网关服务(ecommerce-gateway)
网关作为所有请求的入口,负责路由转发、鉴权、限流等:
java
// GatewayApplication.java
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
yaml
# application.yml
server:
port: 8080
spring:
application:
name: ecommerce-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
routes:
- id: user-service
uri: lb://ecommerce-user
predicates:
- Path=/api/user/**
filters:
- StripPrefix=1
- id: product-service
uri: lb://ecommerce-product
predicates:
- Path=/api/product/**
filters:
- StripPrefix=1
2.5 创建业务微服务
2.5.1 用户服务(ecommerce-user)
java
// UserController.java
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/register")
public Result<UserVO> register(@RequestBody @Valid UserRegisterDTO dto) {
return Result.success(userService.register(dto));
}
@GetMapping("/{id}")
public Result<UserVO> getUserById(@PathVariable Long id) {
return Result.success(userService.getUserById(id));
}
}
yaml
# application.yml
server:
port: 8081
spring:
application:
name: ecommerce-user
datasource:
url: jdbc:mysql://localhost:3306/user_db
username: root
password: 123456
cloud:
nacos:
discovery:
server-addr: localhost:8848
config:
server-addr: localhost:8848
file-extension: yaml
2.5.2 商品服务(ecommerce-product)
- 端口:8082
- 数据库:product_db
- 功能:商品CRUD、库存管理、分类管理
2.5.3 订单服务(ecommerce-order)
- 端口:8083
- 数据库:order_db
- 功能:订单创建、状态管理、订单查询
2.5.4 支付服务(ecommerce-payment)
- 端口:8084
- 数据库:payment_db
- 功能:支付处理、退款、交易记录
2.6 服务间通信与集成
2.6.1 使用OpenFeign进行服务调用
java
// 在订单服务中调用用户服务
@FeignClient(name = "ecommerce-user", path = "/users")
public interface UserFeignClient {
@GetMapping("/{id}")
Result<UserVO> getUserById(@PathVariable Long id);
@PostMapping("/batch")
Result<List<UserVO>> getUsersByIds(@RequestBody List<Long> ids);
}
2.6.2 使用Ribbon实现负载均衡
yaml
# 在调用方的配置中
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
ConnectTimeout: 1000
ReadTimeout: 3000
2.7 配置管理与服务发现
2.7.1 Nacos配置中心使用
yaml
# 在Nacos控制台创建配置
Data ID: ecommerce-user-dev.yaml
Group: DEFAULT_GROUP
配置格式: YAML
配置内容:
spring:
datasource:
url: jdbc:mysql://localhost:3306/user_db
redis:
host: localhost
port: 6379
2.7.2 服务注册与发现
java
// 在每个微服务的主类上添加注解
@SpringBootApplication
@EnableDiscoveryClient // 启用服务发现
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
2.8 测试与验证
2.8.1 单元测试
java
@SpringBootTest
@AutoConfigureMockMvc
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void testRegister() throws Exception {
UserRegisterDTO dto = new UserRegisterDTO();
dto.setUsername("testuser");
dto.setPassword("123456");
dto.setEmail("test@example.com");
mockMvc.perform(post("/users/register")
.contentType(MediaType.APPLICATION_JSON)
.content(JsonUtils.toJson(dto)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(200));
}
}
2.8.2 集成测试
- 启动所有基础设施(Nacos、MySQL、Redis)
- 按顺序启动服务:common → gateway → user → product → order → payment
- 访问Nacos控制台(http://localhost:8848/nacos)确认所有服务已注册
- 通过网关访问API进行测试
2.9 部署与运维考虑
2.9.1 Docker容器化
dockerfile
# Dockerfile示例
FROM openjdk:11-jre-slim
VOLUME /tmp
COPY target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
2.9.2 Kubernetes部署
yaml
# deployment.yaml示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: ecommerce-user
spec:
replicas: 2
selector:
matchLabels:
app: ecommerce-user
template:
metadata:
labels:
app: ecommerce-user
spec:
containers:
- name: user-service
image: ecommerce-user:1.0.0
ports:
- containerPort: 8081
这个项目结构为后续的微服务开发提供了坚实的基础框架,开发者可以在此基础上继续添加业务功能和服务治理组件。