参考视频:尚硅谷SpringCloud教程,springcloud从入门到大牛哔哩哔哩bilibili
一、分布式基础
1.1架构演进
单体架构(All in One):
一句话理解:所有功能都塞在一个项目里,跑在一台服务器上
❌ 缺点:
-
无法应对高并发,一台服务器扛不住就全挂。
-
代码耦合严重,改一个模块可能影响其他功能。
集群架构:
一句话理解 :把同一个单体应用复制多份,部署到多台服务器上,通过网关把请求分发到不同节点
❌ 缺点:
-
本质还是单体,代码耦合问题没解决。
-
模块升级困难(重启整个应用)
-
多语言团队协作困难(比如直播模块用 C++,无法和 Java 单体集成)
分布式 / 微服务架构:
一句话理解 :把单体应用按业务领域拆分成多个独立的微服务 ,服务之间通过远程调用通信。
用户 → 域名 → 网关 → 到对应微服务 → 微服务之间远程调用 → 各自独立数据库
1.2常用组件
-
这么多小服务,如何管理他们?⭐(服务治理 注册中心 ) nacos
-
这么多小服务,他们之间如何通讯?⭐ feign
-
这么多小服务,客户端怎么访问他们?⭐(网关) gateway
-
这么多小服务,一旦出现问题了,应该如何自处理?(容错) sentinel
-
这么多小服务,一旦出现问题了,应该如何排错?(链路追踪) skywalking
-
这么多小服务,怎么保证同一组事务一的致性?⭐ seata
1.3环境准备
1、新建顶级父工程(整个项目的 "总管家" + 版本控制器)
它不写业务代码、不运行、不打包,
只负责一件事:统一管理所有模块的依赖版本,让整个项目不冲突、不乱套!
-
继承 Spring Boot 官方父工程:让所有子模块自动拥有 Spring Boot 环境**
-
管理所有子模块:告诉 Maven:可以一键编译、清理、打包整个项目
-
定义全局版本号 :整个项目统一用同一个版本
-
dependencyManagement:全局版本锁(最重要)
<dependencyManagement>
<dependencies>
<!-- Spring Cloud 版本 -->
<!-- Spring Cloud Alibaba 版本(包含 Nacos) -->
</dependencies>
</dependencyManagement>
作用:所有子模块引入依赖时,不用写版本号! 因为父工程已经锁死了!
以下是具体代码:
官网:版本发布说明-阿里云Spring Cloud Alibaba官网
引入对应的Spring Cloud、Spring Cloud Alibaba依赖,注意以下版本适配
<?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>
<parent>
<groupId>com.xing</groupId>
<artifactId>services</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>message-service</artifactId>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>
2、新建services模块为中间聚合模块(services 就是个 "文件夹",只用来分组,不放依赖!)
<!--作为框架-->
<packaging>pom</packaging>
3、新建5个普通maven项目(业务子模块 = 写代码、加依赖、运行)
微服务(普通Maven)
↓ 继承
services(服务父工程)
↓ 继承
CloudStudy(根父工程)
↓ 继承
spring-boot-starter-parent(官方SpringBoot父)
二、Nacos注册中心
下载Nacos(见主页博客另有笔记)
2.1注册微服务
-
业务模块引入依赖
<dependencies> <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> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies> -
编写主启动类
@SpringBootApplication public class JobMainApplication { public static void main(String[] args) { SpringApplication.run(JobMainApplication.class, args); } } -
编写配置文件
spring: application: name: job-service cloud: nacos: # 服务注册 discovery: server-addr: 127.0.0.1:8848 # 配置中心(从Nacos拉取配置) config: server-addr: 127.0.0.1:8848 file-extension: yaml server: port: 8000三个端口的真正作用(最重要)
① 8848 = Nacos 服务器端口(你要连接的目标)
② 8080 = Nacos 网页控制台端口(浏览器看页面用的)
③ 8000 = 你的微服务端口(可以随便写和 Nacos 无关)
-
启动微服务
-
查看注册中心效果,访问
http://localhost:8080 -
测试集群模式启动:单机情况下通过改变端口号模拟微服务集群


在程序实参输入代码,修改端口号
--server.port=8001
2.2服务发现功能
服务注册:每个微服务启动时,主动把自己的服务名、IP、端口注册上报给 Nacos 注册中心
服务发现 :消费者服务需要调用别的服务时,去 Nacos 查询目标服务的可用实例列表,拿到真实 IP / 端口再发起调用。
(这里是编程式的远程调用,可以不看,先看后面的注解式远程调用)
三、OpenFeign远程调用
声明式的通过注解实现远程调用
2.1 简介与使用
OpenFeign 由注解驱动:
-
指定远程地址:
@FeignClient -
指定请求方式:
@GetMapping、@PostMapping、@DeleteMapping... -
指定携带数据:
@RequestHeader、@RequestParam、@RequestBody... -
指定返回结果:响应模式
其中的 @GetMapping 等注解可以沿用 Spring MVC:
-
当它们标记在 Controller 上时,用于接收请求
-
当他们标记在 FeignClien 上时,用于发送请求
1、使用时引入以下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、在主启动类上使用以下注解:
@EnableFeignClients
3、编写接口
@FeignClient(value = "service-product") //指定要调用的服务名
public interface ProductFeignClient {
//mvc注解的两套使用逻辑
//1、标注在Controller上,是接受这样的请求
//2、标注在FeignClient上,是发送这样的请求到目标服务
//返回的 JSON 反序列化为 Product 对象
@GetMapping("/product/{id}")
Product getProductById(@PathVariable("id") Long id);
}
在 Controller = 别人调用我
在 Feign = 我调用别人
4、使用方法
Spring 自动生成远程调用实现类 →在其他实现层@Autowired 注入→调用方法自动发送 HTTP 请求到远程服务
在你的service业务类里注入并使用
@Service
public class OrderService {
// 直接注入 Feign 接口,Spring 会自动给你一个实现类
@Autowired
private ProductFeignClient productFeignClient;
// 业务方法:创建订单时需要先查询商品信息
public void createOrder(Long productId, Integer num) {
System.out.println("1. 开始查询商品信息...");
// ✅ 这里就是远程调用!
// 看起来像调用本地方法,实际是发 HTTP 请求到 service-product
Product product = productFeignClient.getProductById(productId);
// ... 后续订单业务逻辑
}
}
5、第三步:Controller 层调用 Service
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService;
@PostMapping("/create")
public String createOrder(@RequestParam Long productId,
@RequestParam Integer num) {
orderService.createOrder(productId, num);
return "订单创建成功";
}
}