SpringCloud八股文面试

1.分布式基础:从单体到集群到分布式架构

1.1 单体架构:

单体架构(Monolithic Architecture) 是最传统的软件架构模式,所有功能模块(如用户管理、订单处理、支付服务等)都打包在一个单一的应用程序中,共享同一个代码库、数据库和进程空间。

1.2 集群架构:水平扩展的初步尝试

当单体应用遇到性能瓶颈时,集群架构(Cluster Architecture) 成为自然的解决方案。集群通过在多台服务器上部署相同的应用实例,并使用负载均衡器分发请求,实现水平扩展。

核心组件:

  1. 负载均衡器(Load Balancer):如Nginx、HAProxy,负责将请求分发到不同的应用实例
  2. 应用实例集群:多个完全相同的应用实例运行在不同的服务器上
  3. 共享数据库:所有实例访问同一个数据库,保持数据一致性

挑战:

  • 状态管理困难:用户会话状态需要在实例间共享(需引入Redis等分布式缓存)
  • 数据库成为瓶颈:所有实例共享同一个数据库,容易成为性能瓶颈
  • 配置管理复杂:需要确保所有实例配置一致
  • 资源利用率不均 :静态负载均衡可能无法充分利用资源

1.3 分布式架构:解耦与专业化

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

1.3.1 微服务架构

微服务是分布式架构的一种具体实现,具有以下特征:

  • 服务自治:每个服务拥有独立的数据存储、业务逻辑和部署单元
  • 技术多样性:不同服务可以使用最适合的技术栈
  • 独立扩展:可以根据负载单独扩展某个服务
  • 故障隔离:单个服务故障不会导致整个系统崩溃
1.3.2 分布式系统的核心挑战
  1. 网络通信不可靠

    • 网络延迟、丢包、分区成为常态
    • 需要处理超时、重试、熔断等机制
  2. 数据一致性难题

  3. 分布式事务

    • 两阶段提交(2PC)
    • 三阶段提交(3PC)
    • 基于消息的最终一致性(Saga模式、TCC模式)
  4. 服务发现与治理

    • 服务注册与发现(Consul、Eureka、Nacos)
    • 负载均衡(客户端负载均衡、服务端负载均衡)
    • 熔断降级(Hystrix、Sentinel)
  5. 分布式追踪与监控

    • 调用链追踪(Zipkin、Jaeger、SkyWalking)
    • 指标监控(Prometheus、Grafana)
    • 日志聚合(ELK Stack、Loki)

1.4 架构演进对比

特性 单体架构 集群架构 分布式架构
扩展性 垂直扩展 水平扩展(应用层) 细粒度水平扩展
部署单元 整个应用 整个应用 独立服务
技术栈 统一 统一 多样化
数据存储 共享数据库 共享数据库 独立数据存储
通信方式 本地调用 本地调用+负载均衡 网络调用(RPC/REST)
故障影响 整个系统 部分请求 局部服务
开发复杂度
运维复杂度

1.5 实际演进路径示例

以一个电商系统为例:

  1. 初期(单体):所有功能(用户、商品、订单、支付)在一个Java应用中,使用MySQL数据库
  2. 成长期(集群):应用部署到3台服务器,前端使用Nginx负载均衡,会话状态存入Redis
  3. 成熟期(分布式)
    • 用户服务: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

流程图解读:

  1. SpringBoot微服务:作为基础运行单元,每个服务独立部署
  2. 注册中心:服务启动时注册,消费方通过注册中心发现服务
  3. API网关:统一入口,处理路由、鉴权、限流等横切关注点
  4. 远程调用:服务间通信方式,支持HTTP/RPC等多种协议
  5. 服务熔断:防止雪崩效应,当服务不可用时快速失败
  6. 分布式事务:保证跨多个服务的业务操作一致性

这些组件共同构成了完整的微服务治理体系,确保系统的可用性、可扩展性和一致性。

2、创建微服务项目

2.1 项目规划与需求分析

在创建微服务项目前,首先需要明确业务需求和项目目标:

  1. 业务场景:假设我们要开发一个电商系统,包含用户管理、商品管理、订单管理和支付管理四个核心模块

  2. 服务拆分原则

    • 单一职责:每个服务只负责一个业务领域
    • 独立部署:服务之间可以独立开发、测试、部署
    • 数据自治:每个服务拥有自己的数据库
    • 团队自治:每个服务可以由独立的团队负责
  3. 技术选型考虑

    • 开发语言: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 集成测试
  1. 启动所有基础设施(Nacos、MySQL、Redis)
  2. 按顺序启动服务:common → gateway → user → product → order → payment
  3. 访问Nacos控制台(http://localhost:8848/nacos)确认所有服务已注册
  4. 通过网关访问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

这个项目结构为后续的微服务开发提供了坚实的基础框架,开发者可以在此基础上继续添加业务功能和服务治理组件。

相关推荐
ShineWinsu1 小时前
对于Linux:线程局部存储(TLS)和线程封装的解析
linux·c++·面试·线程·tls·线程封装·线程局部存储
至此流年莫相忘1 小时前
Spring 依赖注入三剑客:@Autowired、@Resource 与 @RequiredArgsConstructor 深度对比与实战指南
java·数据库·spring
shushangyun_2 小时前
批发商城系统源码多少钱?2026最新报价一览
java·开发语言·人工智能·spring·spring cloud
JAVA面经实录9172 小时前
高频算法面试题
java·计算机网络·算法·面试
小易撩挨踢2 小时前
[特殊字符] Spring AI 2.0.0 正式发布:大版本升级,MCP 原生集成 + Anthropic SDK 全线重构
人工智能·spring·重构
山东点狮信息科技有限公司2 小时前
点狮OA-企业级 OA 办公自动化系统架构设计与实践
spring cloud·微服务·性能优化·架构·系统架构
swordbob2 小时前
Nacos vs Eureka
spring cloud·云原生·eureka
柏舟飞流2 小时前
Spring Boot + Spring Security + RBAC:从登录鉴权到权限模型设计
java·spring boot·spring
Jul1en_3 小时前
【SpringCloud】SkyWalking 链路追踪知识详解及部署教程
java·后端·spring·spring cloud·skywalking