零基础学Spring Cloud微服务完整指南

梁雨泽
2026-07-18 13:55
阅读 506

开篇:为什么要写这篇教程?

大家好,我是一名211计算机专业的在读研究生,平时喜欢写技术博客帮助新人入门。最近收到很多学弟学妹的私信,说想学Spring Cloud但不知道从哪开始,网上的教程要么太老要么太深,看得一头雾水。

我当初学的时候也是这样,对着官方文档啃了三天三夜,结果连个服务注册都跑不起来。所以今天这篇教程,我会用最通俗的语言,带你从零开始搭建一个完整的Spring Cloud微服务项目。

Spring Cloud是什么?

简单来说,Spring Cloud是一套微服务架构的开发工具包。它基于Spring Boot,提供了一系列开箱即用的组件,帮你解决微服务开发中的各种问题:

问题 Spring Cloud解决方案
服务太多怎么管理? 服务注册与发现(Nacos/Eureka)
服务之间怎么调用? 远程调用(OpenFeign)
流量太大怎么办? 负载均衡(LoadBalancer)
某个服务挂了怎么办? 熔断降级(Sentinel)
配置太多怎么管理? 配置中心(Nacos Config)
请求怎么路由? 网关(Gateway)

一句话总结:Spring Cloud就是帮你把微服务架构中那些麻烦事都解决了的工具箱。


环境准备:工欲善其事,必先利其器

在开始之前,我们需要准备好开发环境。我当初就是环境没配好,折腾了一整天。

1. 基础环境清单

工具 版本要求 说明
JDK 1.8 或 17 推荐JDK 17,但JDK 8兼容性更好
Maven 3.6+ 项目构建工具
IntelliJ IDEA 2022+ 推荐使用Ultimate版
MySQL 5.7 或 8.0 数据库
Nacos 2.1+ 服务注册与配置中心

2. JDK安装与配置

# 验证JDK是否安装成功
java -version

# 验证Maven是否安装成功
mvn -version

3. Nacos下载与启动

Nacos是阿里巴巴开源的服务注册与配置中心,我们用它来替代老版本的Eureka。

# 下载Nacos(以Windows为例)
# 访问 https://github.com/alibaba/nacos/releases
# 下载 nacos-server-2.x.zip

# 解压后,进入bin目录,单机模式启动
# Windows:
startup.cmd -m standalone

# Linux/Mac:
sh startup.sh -m standalone

启动成功后,访问 http://localhost:8848/nacos,默认账号密码都是 nacos

避坑指南:Nacos 2.x版本需要JDK 1.8以上,如果你用的是JDK 17,可能会遇到兼容性问题,建议先用JDK 8或11。


核心概念:用大白话理解微服务

在动手写代码之前,我们先搞清楚几个核心概念。我当初就是概念没搞清,代码写得一塌糊涂。

什么是微服务?

想象你在开一家大餐厅:

  • 单体架构:所有厨师在一个厨房,所有菜都在一个锅里炒。菜品多了,厨房就乱了。
  • 微服务架构:把厨房分成炒菜区、凉菜区、面点区,每个区域独立运作,互不干扰。

微服务就是把一个大系统拆分成多个小服务,每个服务独立部署、独立运行。

微服务的核心角色

┌─────────────────────────────────────────────────────────┐
│                      客户端请求                          │
└───────────────────────┬─────────────────────────────────┘
                        │
                        ▼
              ┌─────────────────┐
              │   API网关(Gateway) │  ← 统一入口,路由转发
              └────────┬────────┘
                       │
          ┌────────────┼────────────┐
          ▼            ▼            ▼
   ┌──────────┐  ┌──────────┐  ┌──────────┐
   │ 用户服务  │  │ 订单服务  │  │ 商品服务  │  ← 各个微服务
   └────┬─────┘  └────┬─────┘  └────┬─────┘
        │             │             │
        └─────────────┼─────────────┘
                      ▼
            ┌─────────────────┐
            │  Nacos注册中心   │  ← 服务注册与发现
            └─────────────────┘

用表格来对比一下各个组件的作用:

组件 作用 通俗比喻
Nacos 服务注册与发现 通讯录,记录每个服务在哪
OpenFeign 服务间调用 打电话,服务A找服务B办事
Gateway API网关 前台接待,统一入口
Sentinel 熔断降级 保险丝,防止系统雪崩
LoadBalancer 负载均衡 排队叫号,均匀分配请求

实战项目:手把手搭建微服务

理论讲完了,我们开始动手!今天我们要搭建一个简单的电商微服务项目,包含以下模块:

cloud-demo(父工程)
├── cloud-common        (公共模块)
├── cloud-gateway       (网关服务)
├── cloud-user          (用户服务)
├── cloud-order         (订单服务)
└── cloud-product       (商品服务)

第一步:创建父工程

打开IDEA,创建一个Maven项目作为父工程。

pom.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>cloud-demo</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>

    <!-- 子模块 -->
    <modules>
        <module>cloud-common</module>
        <module>cloud-gateway</module>
        <module>cloud-user</module>
        <module>cloud-order</module>
        <module>cloud-product</module>
    </modules>

    <!-- 版本管理 -->
    <properties>
        <java.version>1.8</java.version>
        <spring-boot.version>2.7.14</spring-boot.version>
        <spring-cloud.version>2021.0.8</spring-cloud.version>
        <spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version>
    </properties>

    <!-- 依赖版本管理 -->
    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- 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>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
            </plugin>
        </plugins>
    </build>
</project>

版本对应关系很重要! Spring Boot、Spring Cloud、Spring Cloud Alibaba三者版本必须匹配,否则会出现各种奇怪的报错。我当初就是版本没对齐,调了一整天bug。

第二步:创建公共模块 cloud-common

公共模块用来存放各个服务共用的代码,比如实体类、工具类等。

cloud-common/pom.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">
    <parent>
        <artifactId>cloud-demo</artifactId>
        <groupId>com.example</groupId>
        <version>1.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-common</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>

创建一个通用的返回结果类:

package com.example.common;

import lombok.Data;

@Data
public class Result<T> {
    private Integer code;
    private String message;
    private T data;

    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.setCode(200);
        result.setMessage("success");
        result.setData(data);
        return result;
    }

    public static <T> Result<T> error(String message) {
        Result<T> result = new Result<>();
        result.setCode(500);
        result.setMessage(message);
        return result;
    }
}

第三步:创建用户服务 cloud-user

这是我们的第一个微服务,提供用户相关的接口。

cloud-user/pom.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">
    <parent>
        <artifactId>cloud-demo</artifactId>
        <groupId>com.example</groupId>
        <version>1.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-user</artifactId>

    <dependencies>
        <!-- 公共模块 -->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>cloud-common</artifactId>
            <version>1.0.0</version>
        </dependency>
        <!-- Spring Boot Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Nacos服务发现 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- OpenFeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- LoadBalancer -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>
</project>

application.yml 配置文件

server:
  port: 8081

spring:
  application:
    name: cloud-user
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

启动类

package com.example.user;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient  // 开启服务发现
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }
}

用户实体类

package com.example.user.entity;

import lombok.Data;

@Data
public class User {
    private Long id;
    private String username;
    private String email;
}

用户Controller

package com.example.user.controller;

import com.example.common.Result;
import com.example.user.entity.User;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/{id}")
    public Result<User> getUserById(@PathVariable Long id) {
        // 模拟从数据库查询
        User user = new User();
        user.setId(id);
        user.setUsername("张三");
        user.setEmail("zhangsan@example.com");
        return Result.success(user);
    }

    @GetMapping("/list")
    public Result<String> getUserList() {
        return Result.success("用户列表数据");
    }
}

启动服务后,访问 http://localhost:8081/user/1,就能看到返回的用户信息了。

同时,打开Nacos控制台 http://localhost:8848/nacos,在「服务管理」-「服务列表」中,你应该能看到 cloud-user 服务已经注册成功了。

第四步:创建商品服务 cloud-product

商品服务提供商品查询接口,后续订单服务会调用它。

cloud-product/pom.xml:与cloud-user类似,不再重复。

application.yml

server:
  port: 8082

spring:
  application:
    name: cloud-product
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

商品实体类

package com.example.product.entity;

import lombok.Data;
import java.math.BigDecimal;

@Data
public class Product {
    private Long id;
    private String name;
    private BigDecimal price;
    private Integer stock;
}

商品Controller

package com.example.product.controller;

import com.example.common.Result;
import com.example.product.entity.Product;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;

@RestController
@RequestMapping("/product")
public class ProductController {

    @GetMapping("/{id}")
    public Result<Product> getProductById(@PathVariable Long id) {
        Product product = new Product();
        product.setId(id);
        product.setName("Java编程思想");
        product.setPrice(new BigDecimal("99.00"));
        product.setStock(100);
        return Result.success(product);
    }
}

第五步:创建订单服务 cloud-order(重点!)

订单服务需要调用用户服务和商品服务,这是微服务间通信的核心场景。

application.yml

server:
  port: 8083

spring:
  application:
    name: cloud-order
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

订单实体类

package com.example.order.entity;

import lombok.Data;
import java.math.BigDecimal;

@Data
public class Order {
    private Long id;
    private Long userId;
    private Long productId;
    private String userName;
    private String productName;
    private BigDecimal totalPrice;
}

使用OpenFeign调用其他服务

首先,定义Feign客户端接口来调用用户服务:

package com.example.order.feign;

import com.example.common.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.Map;

@FeignClient(name = "cloud-user")  // 指定要调用的服务名
public interface UserFeignClient {

    @GetMapping("/user/{id}")
    Result<Map<String, Object>> getUserById(@PathVariable("id") Long id);
}

同样,定义调用商品服务的Feign客户端:

package com.example.order.feign;

import com.example.common.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.Map;

@FeignClient(name = "cloud-product")
public interface ProductFeignClient {

    @GetMapping("/product/{id}")
    Result<Map<String, Object>> getProductById(@PathVariable("id") Long id);
}

订单Controller

package com.example.order.controller;

import com.example.common.Result;
import com.example.order.entity.Order;
import com.example.order.feign.ProductFeignClient;
import com.example.order.feign.UserFeignClient;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Map;

@RestController
@RequestMapping("/order")
public class OrderController {

    @Resource
    private UserFeignClient userFeignClient;

    @Resource
    private ProductFeignClient productFeignClient;

    @GetMapping("/{id}")
    public Result<Order> createOrder(@PathVariable Long id,
                                      @RequestParam Long userId,
                                      @RequestParam Long productId) {
        // 1. 调用用户服务获取用户信息
        Result<Map<String, Object>> userResult = userFeignClient.getUserById(userId);
        Map<String, Object> userData = userResult.getData();
        String userName = (String) userData.get("username");

        // 2. 调用商品服务获取商品信息
        Result<Map<String, Object>> productResult = productFeignClient.getProductById(productId);
        Map<String, Object> productData = productResult.getData();
        String productName = (String) productData.get("name");
        BigDecimal price = new BigDecimal(productData.get("price").toString());

        // 3. 组装订单信息
        Order order = new Order();
        order.setId(id);
        order.setUserId(userId);
        order.setProductId(productId);
        order.setUserName(userName);
        order.setProductName(productName);
        order.setTotalPrice(price);

        return Result.success(order);
    }
}

启动类别忘了加@EnableFeignClients

package com.example.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients  // 开启Feign客户端
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

启动所有服务后,访问 http://localhost:8083/order/1?userId=1&productId=1,你会看到订单服务成功调用了用户服务和商品服务,并返回了完整的订单信息。

第六步:创建API网关 cloud-gateway

网关是所有请求的统一入口,负责路由转发。

cloud-gateway/pom.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">
    <parent>
        <artifactId>cloud-demo</artifactId>
        <groupId>com.example</groupId>
        <version>1.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-gateway</artifactId>

    <dependencies>
        <!-- Gateway -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!-- Nacos服务发现 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- LoadBalancer -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>
</project>

注意:Gateway模块不能引入 spring-boot-starter-web,因为Gateway基于WebFlux,和Web模块冲突!这是我踩过的一个大坑。

application.yml

server:
  port: 9000

spring:
  application:
    name: cloud-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      routes:
        # 用户服务路由
        - id: user-route
          uri: lb://cloud-user
          predicates:
            - Path=/api/user/**
          filters:
            - StripPrefix=1
        # 商品服务路由
        - id: product-route
          uri: lb://cloud-product
          predicates:
            - Path=/api/product/**
          filters:
            - StripPrefix=1
        # 订单服务路由
        - id: order-route
          uri: lb://cloud-order
          predicates:
            - Path=/api/order/**
          filters:
            - StripPrefix=1

路由配置解释:

配置项 含义
id 路由唯一标识
uri 目标服务地址,lb:// 表示使用负载均衡
predicates 匹配条件,Path=/api/user/** 表示匹配以/api/user/开头的请求
filters 过滤器,StripPrefix=1 表示去掉第一层路径

启动类

package com.example.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

现在,你可以通过网关来访问所有服务了:

# 原来访问用户服务
http://localhost:8081/user/1

# 现在通过网关访问
http://localhost:9000/api/user/user/1

常见问题:新手踩坑指南

问题1:服务注册不上Nacos

现象:启动服务后,Nacos控制台看不到服务。

排查步骤

  1. 检查Nacos是否启动成功
  2. 检查 application.yml 中的 server-addr 是否正确
  3. 检查是否加了 @EnableDiscoveryClient 注解
  4. 检查依赖是否引入正确
# 正确的配置
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848  # 注意是8848端口

问题2:OpenFeign调用报错

现象:Feign调用时报 No Feign Client for loadBalancing defined

解决方案:引入LoadBalancer依赖。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

Spring Cloud 2020版本之后,Ribbon被移除了,必须手动引入LoadBalancer。

问题3:Gateway路由不生效

现象:通过网关访问接口返回404。

排查步骤

  1. 检查路由配置中的 Path 是否正确
  2. 检查 StripPrefix 的值是否正确
  3. 查看网关启动日志,确认路由是否加载成功
# 错误示例:路径不匹配
predicates:
  - Path=/user/**  # 请求路径是 /api/user/user/1,不匹配

# 正确示例
predicates:
  - Path=/api/user/**  # 匹配 /api/user/ 开头的路径
filters:
  - StripPrefix=1  # 去掉 /api,变成 /user/user/1

问题4:版本冲突

现象:各种 ClassNotFoundExceptionNoSuchMethodError

解决方案:严格按照版本对应关系来配置。

Spring Boot Spring Cloud Spring Cloud Alibaba
2.6.x 2021.0.x 2021.0.4.0
2.7.x 2021.0.x 2021.0.5.0
3.0.x 2022.0.x 2022.0.0.0

学习建议:下一步怎么走?

恭喜你!到这里你已经完成了一个基础的Spring Cloud微服务项目。但这只是开始,微服务的世界还有很多东西要学。

推荐学习路径

第一阶段(已完成):
├── 服务注册与发现(Nacos)
├── 服务间调用(OpenFeign)
├── API网关(Gateway)
└── 负载均衡(LoadBalancer)

第二阶段(建议接下来学):
├── 配置中心(Nacos Config)
├── 熔断降级(Sentinel)
├── 分布式事务(Seata)
└── 链路追踪(SkyWalking/Sleuth)

第三阶段(进阶):
├── Docker容器化部署
├── Kubernetes编排
├── CI/CD自动化部署
└── 微服务监控与运维

我的学习建议

  1. 先跑通再理解:不要一开始就死磕原理,先把项目跑起来,有成就感了再深入。

  2. 多看官方文档:虽然官方文档枯燥,但最权威。遇到不懂的,先查官方文档。

  3. 动手做项目:光看教程没用,一定要自己动手写。可以把我这个项目扩展一下,加上数据库、加上更多的业务逻辑。

  4. 学会看日志:遇到问题不要慌,仔细看报错日志,90%的问题都能自己解决。

  5. 加入社区:遇到问题可以去Spring中文社区、CSDN、掘金等平台提问,也可以看看别人的解决方案。

避坑总结

建议
版本不对齐 严格按照版本对应表配置
Gateway引入Web依赖 Gateway基于WebFlux,不能引入spring-boot-starter-web
忘记加注解 @EnableDiscoveryClient、@EnableFeignClients别忘加
Nacos端口搞错 Nacos主端口是8848,不是8080
Feign调用没引入LB Spring Cloud 2020+必须手动引入LoadBalancer

结语

微服务架构并不神秘,Spring Cloud也只是帮你把复杂的事情简单化了。作为初学者,不要被各种概念吓到,一步一步来,先跑通一个小项目,再慢慢深入。

我当初也是从零开始,踩了无数坑才走到今天。希望这篇教程能帮你少走一些弯路。如果有任何问题,欢迎在评论区留言,我会尽力解答。

最后送大家一句话:编程是一门手艺活,唯手熟尔。 多写代码,多思考,你一定能成为优秀的开发者!

加油!💪

评论 0

最热最新
暂无评论
梁雨泽Lv.1
0
影响力
0
文章
0
粉丝