SpringCloud微服务入门教程

Spring Cloud 微服务入门实战教程

一、什么是微服务架构?

1.1 从单体架构说起

传统单体应用将所有功能模块打包在一起部署,例如一个电商系统包含用户、商品、订单、支付等功能,全部写在一个项目中。

单体架构的痛点:

  • 代码臃肿,启动慢,维护成本高
  • 一个小功能修改需要整个项目重新部署
  • 无法针对高并发的模块单独扩容
  • 技术栈固定,无法异构
  • 团队协作困难,合并代码冲突频繁

1.2 微服务架构定义

微服务架构(Microservices Architecture)是一种将单一应用程序划分为一组小服务的设计模式,每个服务运行在自己的进程中,服务之间通过轻量级通信机制(如 HTTP/REST)协作。

核心特征:

  • 单一职责:每个服务只做一件事
  • 独立部署:服务可以独立开发、测试、部署
  • 去中心化:每个服务可选择最适合的技术栈
  • 轻量通信:通常使用 HTTP/REST 或消息队列
  • 数据独立:每个服务拥有自己的数据库

二、Spring Cloud 概述

2.1 什么是 Spring Cloud

Spring Cloud 基于 Spring Boot 构建,为微服务架构提供了一站式解决方案,涵盖了服务注册与发现、配置管理、负载均衡、熔断降级、网关路由、分布式追踪等开箱即用的组件。

2.2 版本说明

Spring Cloud 版本以伦敦地铁站命名(按字母顺序):

Spring Cloud 版本 对应的 Spring Boot 版本
Hoxton.SR12 2.2.x / 2.3.x
2020.0.x (Ilford) 2.4.x / 2.5.x
2021.0.x (Jubilee) 2.6.x / 2.7.x
2022.0.x (Kilburn) 3.0.x
2023.0.x (Leyton) 3.2.x

2.3 核心组件生态

组件 说明 选型(主流)
服务注册中心 管理所有微服务的地址列表 Nacos / Eureka / Consul
配置中心 统一管理配置文件 Nacos Config / Apollo
远程调用 服务间通信 OpenFeign + RestTemplate
负载均衡 分发请求到多个实例 Spring Cloud LoadBalancer
网关 统一入口,路由转发 Spring Cloud Gateway
熔断降级 防止服务雪崩 Sentinel / Resilience4j
链路追踪 全链路调用监控 Sleuth + Zipkin / SkyWalking

三、环境准备

3.1 开发环境

text 复制代码
JDK 17+
Maven 3.8+
IDE:IntelliJ IDEA
Docker(可选,用于部署中间件)

3.2 创建父工程

创建一个 Maven 项目作为父工程,统一管理依赖版本。

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

    <properties>
        <java.version>17</java.version>
        <spring-cloud.version>2023.0.3</spring-cloud.version>
        <spring-boot.version>3.2.10</spring-boot.version>
        <nacos.version>2023.0.1.2</nacos.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <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>${nacos.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

四、服务注册与发现 ------ Nacos

4.1 安装 Nacos

方式一:使用 Docker

bash 复制代码
docker run -d \
  --name nacos \
  -p 8848:8848 \
  -p 9848:9848 \
  -e MODE=standalone \
  nacos/nacos-server:v2.3.2

方式二:本地安装

  1. Nacos 官网 下载安装包
  2. 解压后执行 bin/startup.cmd -m standalone(Windows)
  3. 访问控制台:http://localhost:8848/nacos,默认用户名密码 nacos/nacos

4.2 创建服务提供者

子模块:cloud-provider

pom.xml:

xml 复制代码
<dependencies>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

application.yml:

yaml 复制代码
server:
  port: 8081

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

logging:
  level:
    com.example: debug

启动类:

java 复制代码
package com.example.provider;

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

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

接口:

java 复制代码
package com.example.provider.controller;

import org.springframework.web.bind.annotation.*;

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

    @GetMapping("/{id}")
    public String getUser(@PathVariable Long id) {
        return "用户信息,ID:" + id + ",端口:8081";
    }

    @GetMapping("/list")
    public String listUsers() {
        return "用户列表";
    }
}

4.3 验证

启动后访问 http://localhost:8848/nacos,在"服务列表"中可以看到 user-service 已注册。

五、远程调用 ------ OpenFeign

OpenFeign 是一个声明式的 HTTP 客户端,让服务间调用像调用本地方法一样简单。

5.1 创建服务消费者

子模块:cloud-consumer

pom.xml:

xml 复制代码
<dependencies>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

application.yml:

yaml 复制代码
server:
  port: 8082

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

Feign 客户端:

java 复制代码
package com.example.consumer.feign;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(name = "user-service")
public interface UserFeignClient {

    @GetMapping("/users/{id}")
    String getUser(@PathVariable("id") Long id);

    @GetMapping("/users/list")
    String listUsers();
}

启动类:

java 复制代码
package com.example.consumer;

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
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}

Controller 调用:

java 复制代码
package com.example.consumer.controller;

import com.example.consumer.feign.UserFeignClient;
import org.springframework.web.bind.annotation.*;

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

    private final UserFeignClient userFeignClient;

    public OrderController(UserFeignClient userFeignClient) {
        this.userFeignClient = userFeignClient;
    }

    @GetMapping("/user/{id}")
    public String getUser(@PathVariable Long id) {
        return userFeignClient.getUser(id);
    }
}

5.2 Feign 核心配置

yaml 复制代码
spring:
  cloud:
    openfeign:
      client:
        config:
          default:
            connect-timeout: 5000
            read-timeout: 5000
            logger-level: FULL
      compression:
        request:
          enabled: true
        response:
          enabled: true

六、负载均衡

Spring Cloud 2020 弃用了 Ribbon,官方推荐使用 Spring Cloud LoadBalancer。

工作流程:

  1. @FeignClient(name = "user-service") 声明调用名为 user-service 的服务
  2. LoadBalancer 从 Nacos 拉取 user-service 的实例列表
  3. 按策略(默认轮询)选择一个实例进行调用

启动两个 provider 实例(不同端口),Feign 会自动负载均衡。

切换负载均衡策略

java 复制代码
package com.example.consumer.config;

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

@Configuration
public class LoadBalancerConfig {

    @Bean
    public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(
            Environment environment,
            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(
                loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),
                name);
    }
}

七、配置中心 ------ Nacos Config

7.1 引入依赖

xml 复制代码
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

7.2 在 Nacos 创建配置

登录 Nacos 控制台 → "配置管理" → "配置列表" → 点击 "+" 创建配置:

  • Data ID: user-service-dev.yml
  • Group: DEFAULT_GROUP
  • 配置格式: YAML
  • 配置内容:
yaml 复制代码
user:
  nickname: 张三
  age: 25

7.3 加载配置

bootstrap.yml(注意不是 application.yml):

yaml 复制代码
spring:
  application:
    name: user-service
  cloud:
    nacos:
      config:
        server-addr: localhost:8848
        file-extension: yml
        group: DEFAULT_GROUP
  profiles:
    active: dev

7.4 动态刷新配置

java 复制代码
package com.example.provider.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RefreshScope
public class ConfigController {

    @Value("${user.nickname}")
    private String nickname;

    @Value("${user.age}")
    private Integer age;

    @GetMapping("/config")
    public String getConfig() {
        return "nickname:" + nickname + ",age:" + age;
    }
}

修改 Nacos 中的配置后,调用 /config 接口即可看到已生效,无需重启服务。

八、网关 ------ Spring Cloud Gateway

8.1 创建网关模块

子模块:cloud-gateway

pom.xml:

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
</dependencies>

application.yml:

yaml 复制代码
server:
  port: 80

spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/users/**
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/orders/**
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true

8.2 启动类

java 复制代码
package com.example.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

8.3 验证

启动 gateway,访问 http://localhost/users/1 即可路由到 user-service

九、熔断降级 ------ Sentinel

9.1 安装 Sentinel 控制台

bash 复制代码
docker run -d \
  --name sentinel \
  -p 8858:8080 \
  bladex/sentinel-dashboard:1.8.8

访问 http://localhost:8858,默认用户名密码 sentinel/sentinel

9.2 引入依赖

xml 复制代码
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>

9.3 配置 Sentinel

yaml 复制代码
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8858
      eager: true

9.4 Feign 整合 Sentinel

yaml 复制代码
spring:
  cloud:
    openfeign:
      circuitbreaker:
        enabled: true

创建 Fallback 工厂:

java 复制代码
package com.example.consumer.feign.fallback;

import com.example.consumer.feign.UserFeignClient;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;

@Component
public class UserFeignFallbackFactory implements FallbackFactory<UserFeignClient> {

    @Override
    public UserFeignClient create(Throwable cause) {
        return new UserFeignClient() {
            @Override
            public String getUser(Long id) {
                return "服务降级:无法获取用户信息," + cause.getMessage();
            }

            @Override
            public String listUsers() {
                return "服务降级:无法获取用户列表";
            }
        };
    }
}

修改 Feign 客户端:

java 复制代码
@FeignClient(name = "user-service", fallbackFactory = UserFeignFallbackFactory.class)
public interface UserFeignClient {
    // ...
}

十、链路追踪 ------ Micrometer Tracing

Spring Cloud Sleuth 在 2023.x 版本中被 Micrometer Tracing 替代。

10.1 引入依赖

xml 复制代码
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-reporter-brave</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

10.2 安装 Zipkin

bash 复制代码
docker run -d \
  --name zipkin \
  -p 9411:9411 \
  openzipkin/zipkin:latest

10.3 配置

yaml 复制代码
spring:
  application:
    name: user-service
logging:
  pattern:
    level: "%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]"

发送请求后,访问 http://localhost:9411 查看链路追踪详情。

十一、项目结构一览

复制代码
cloud-demo/
├── pom.xml                              # 父工程,统一版本管理
├── cloud-common/                        # 公共模块
│   └── src/main/java/com/example/common
│       ├── result/Result.java           # 统一返回结果
│       └── constant/ApiConstant.java    # 常量
├── cloud-provider/                      # 服务提供者
│   └── src/main/java/com/example/provider
│       ├── ProviderApplication.java
│       ├── controller/UserController.java
│       └── service/UserService.java
├── cloud-consumer/                      # 服务消费者
│   └── src/main/java/com/example/consumer
│       ├── ConsumerApplication.java
│       ├── controller/OrderController.java
│       ├── feign/UserFeignClient.java
│       └── feign/fallback/UserFeignFallbackFactory.java
├── cloud-gateway/                       # 网关
│   └── src/main/java/com/example/gateway
│       ├── GatewayApplication.java
│       └── config/GatewayConfig.java
└── cloud-auth/                          # 认证授权(扩展)
    └── src/main/java/com/example/auth
        └── AuthApplication.java

十二、配套 SQL(示例)

sql 复制代码
CREATE DATABASE IF NOT EXISTS cloud_demo DEFAULT CHARSET utf8mb4;

USE cloud_demo;

-- 用户表
CREATE TABLE `user` (
    `id` bigint NOT NULL AUTO_INCREMENT,
    `username` varchar(50) NOT NULL COMMENT '用户名',
    `password` varchar(255) NOT NULL COMMENT '密码',
    `phone` varchar(20) DEFAULT NULL COMMENT '手机号',
    `email` varchar(100) DEFAULT NULL COMMENT '邮箱',
    `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    UNIQUE KEY `uk_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

-- 订单表
CREATE TABLE `order` (
    `id` bigint NOT NULL AUTO_INCREMENT,
    `user_id` bigint NOT NULL COMMENT '用户ID',
    `order_no` varchar(32) NOT NULL COMMENT '订单号',
    `amount` decimal(10,2) NOT NULL COMMENT '金额',
    `status` tinyint NOT NULL DEFAULT '0' COMMENT '0-待支付 1-已支付 2-已取消',
    `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';

十三、常见问题

13.1 启动报错 Failed to bind to port

端口被占用,修改 application.yml 中的 server.port,或检查对应端口是否已被其他进程占用。

13.2 Feign 调用报错 LoadBalancer 异常

确认服务名是否注册到 Nacos,FeignClient 中的 name 是否与目标服务的 spring.application.name 一致。

13.3 Nacos 连接失败

确认 Nacos 是否已启动,server-addr 配置是否正确,防火墙是否放行 8848 端口。

13.4 Spring Cloud 版本兼容问题

严格对照版本对应关系,使用 BOM(spring-cloud-dependencies)统一管理版本,避免自行指定子组件版本。

十四、总结

通过本教程,我们完成了一个完整的 Spring Cloud 微服务入门项目:

组件 功能
Nacos 服务注册与发现 + 配置中心
OpenFeign 声明式远程调用
Spring Cloud Gateway 统一路由网关
Sentinel 熔断降级与流量控制
Micrometer + Zipkin 分布式链路追踪

微服务不是银弹,引入微服务的同时也带来了网络延迟、数据一致性、运维复杂度等挑战。建议根据实际业务场景合理拆分,不要为了微服务而微服务。

相关推荐
Java爱好狂.17 分钟前
Redis高级笔记:原理+集群+应用+拓展+源码
java·数据库·redis·spring·java面试·后端开发·java八股文
直奔標竿22 分钟前
Java开发者AI转型第九课!突破知识边界!企业级 RAG (检索增强生成) 核心架构与 ETL 管道初探
java·开发语言·人工智能·后端·spring
剩下了什么26 分钟前
微服务入门介绍
微服务·云原生·架构
Boop_wu33 分钟前
[Java EE进阶] 图书管理系统(2)
spring·java-ee·maven·mybatis·状态模式
Sam_Deep_Thinking1 小时前
适合中小型企业的出口入口网关微服务
java·微服务·架构
小张小张爱学习1 小时前
Mybatis高频面试题
java·spring·mybatis
直奔標竿1 小时前
Java开发者AI转型第十三课!知识库终局方案:Spring AI Vector Store架构演进与ETL全链路入库实战
java·人工智能·后端·spring
星轨zb2 小时前
什么是Spring设计模式:单例、工厂与代理
java·spring·设计模式