SpringCloud-尚硅谷2025最新SpringCloud速通
springcloud简介
springcloud是分布式系统一站式解决方案。
分布式架构(模拟用户访问)
1.通过网关来发送各个微服务的请求(请求路由)。用gateway。网关需要对请求进行分发,所以要注册到注册中心。
2.将各微服务布置到各服务器,即微服务(自治) 独立部署、数据隔离、语言无关,将不同模块部署到多个服务器,每个模块都要有副本服务器。不能让每个模块只部署到一个服务器,会出现单点故障问题:如果这个服务器崩了,那应用就不能提供完整服务了
3.如果模块跨服务器之间调用会遇到什么问题?远程调用RPC。如果远程调用怎么让应用知道调用哪个服务器的微服务。此时就需要用到nacos注册中心和配置中心,注册中心有两个功能:服务注册(监控服务上下线)和服务发现(远程调用之前要发现对方在哪)。配置中心:统一管理配置文件+推送配置的变更。Nacos+OpenFeign
4.如果模块之间调用失败导致服务调用链整体阻塞甚至雪崩,怎么办?服务熔断(快速失败机制),及时释放资源,防止资源耗尽。Sentinal
5.如果有一个操作需要多个数据库合作,而不同数据库部署在不同服务器,这就需要用到分布式事务。Seata

前期准备项目创建
要注意springboot-spirngcloud-springalibabad三个模块的版本是要相互适配
参考链接
https://blog.csdn.net/weixin_56884174/article/details/145573890
1、建springcloud-demo项目(建springboot项目,这样他的父类就是springboot
2、导依赖
pom父模块
注意:springboot, springcloud, springcloud-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">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.atguigu</groupId>
<artifactId>spring-cloud-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-cloud.version>2023.0.3</spring-cloud.version>
<spring-cloud-alibaba.version>2023.0.3.2</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<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>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
注意一个问题,父模块的pom中加了 <dependencyManagement> 后,就限定了后面子模块pom中用<dependencies>下载依赖时springcloud和springcloudalibaba的版本,但是父模块中的<dependencyManagement>在外面
3、在sevice模块加入依赖
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
4、建service-order/product模块
注意父模块是services
Nacos
安装与注册

如何快速复制服务



服务发现
第一步,在springboot主程序加上@EnableDiscoverClient
package com;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient//开启服务发现功能
@SpringBootApplication
public class ProductMainApplication {
public static void main(String[] args) {
SpringApplication.run(ProductMainApplication.class, args);
}
}
第二步,测试服务发现API(DiscoveryClient或NacosServiceDiscovery
写test文件
package com.atguigu.product;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.client.discovery.DiscoveryClient;
@SpringBootTest
public class DiscoveryTest {
@Autowired
DiscoveryClient discoveryClient;
@Test
void discoveryClient() {
for (String serviceId : discoveryClient.getServices()) {
System.out.println(serviceId);
}
}
}
远程调用


1、创建两个服务
2、两个服务实现相互调用
负载均衡

思考:注册中心宕机,远程调用还能成功吗?

可以进行实验
实验一:五个服务启动,在nacos中有注册,但是没有执行http://localhost:8000/create?userId=2&productId=23测试,也就是没有经过远程调用,然后将nacos关闭,再调用请求测试
结论:不能调用,因为远程调用由于nacos宕机找不到地址
实验一:五个服务启动,在nacos中有注册,但是执行http://localhost:8000/create?userId=2&productId=23测试,已经经过远程调用,然后将nacos关闭,再调用请求测试
结论:可以调用,因为缓存中有地址。但如果对方服务宕机则也调不通。
原理 (关键是存不存在缓存)
第一次远程调用要经过两个步骤:1.拿到nacos服务地址列表 2.给对方服务的某个地址发送请求。
第二次及后续:就会将步骤1省略,已经将地址列表放到缓存中了,即使nacos宕机也能远程调用,并且能负载均衡。
配置中心
1、引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2、service-order的配置文件application.properties
导入了配置中心的依赖但是没设置(用到)配置中心就会报错,解决办法,关闭自动检查
server.port=8000
spring.application.name=service-order
spring.cloud.nacos.server-addr=127.0.0.1:8848
spring.config.import=nacos:service-order.properties
#暂未用到配置中心功能,需要关闭配置检查
spring.cloud.nacos.config.import-check.enabled=false
3、在nacos服务端进行配置


4代码测试
order: controller
@RestController
public class OrderController {
@Autowired
OrderService orderService;
@Value("${order.timeout}")
String orderTimeout;
@Value("${order.auto-confirm}")
String orderAutoConfirm;
@GetMapping("/config")
public String getConfig() {
return "OrderTimeout+OrderAutoConfirm = " + orderTimeout+" : " + orderAutoConfirm;
}
@GetMapping(value = "/create")
public Order createOrder(@RequestParam("userId") Long userId, @RequestParam("productId") Long productId) {
Order order = orderService.createOrder(userId, productId);
return order;
}
}
自动刷新配置中心的内容
第一种方法
实时更新配置显示的办法:在@RestController上加@RefreshScope即可
第二种方法
@ConfigurationProperties 无感自动刷新
加com.atguigu.order.properties.OrderProperties
@Component
@ConfigurationProperties(value = "order")//配置批量绑定在nacos下,可以无需@RefreshScope就能实现自动刷新
@Data
public class OrderProperties {
String timeout;
String autoConfirm;
}
service-order: controller
//@RefreshScope
@RestController
public class OrderController {
@Autowired
OrderService orderService;
// @Value("${order.timeout}")
// String orderTimeout;
// @Value("${order.auto-confirm}")
// String orderAutoConfirm;
@Autowired
OrderProperties orderProperties;
@GetMapping("/config")
public String getConfig() {
return "OrderTimeout+OrderAutoConfirm = " + orderProperties.getTimeout() + " : " + orderProperties.getAutoConfirm();
}
@GetMapping(value = "/create")
public Order createOrder(@RequestParam("userId") Long userId, @RequestParam("productId") Long productId) {
Order order = orderService.createOrder(userId, productId);
return order;
}
}
第三种方法
NacosConfigManager 监听配置变化
在启动类中添加ApplicationRunner实例,是一个一次性任务,项目启动其他他就会执行
@SpringBootApplication
public class OrderMainApplication {
public static void main(String[] args) {
SpringApplication.run(OrderMainApplication.class, args);
}
//1、项目启动就监听配置文件变化
//2、发生变化后拿到变化值
//3、发送邮件
@Bean
ApplicationRunner applicationRunner(NacosConfigManager nacosConfigManager) {
// return new ApplicationRunner() {
// @Override
// public void run(ApplicationArguments args) throws Exception {
//
// }
// }
return args -> {
//这个监听的服务和application.yml中naocs的配置中心有关
ConfigService configService = nacosConfigManager.getConfigService();
configService.addListener("service-order.properties", "DEFAULT_GROUP", new Listener() {
@Override
public Executor getExecutor() {
return Executors.newFixedThreadPool(4);
}
@Override
public void receiveConfigInfo(String s) {
System.out.println("变化的配置信息:" + s);
System.out.println("邮件通知....");
}
});
System.out.println("=========");
};
}
}
思考: Nacos中的数据集 和 application.properties 有相同的 配置项,哪个生效?
以配置中心(nacos)为准,不然要配置中心干什么
数据隔离

在nacos通过命名空间区别环境的区别

设置application.yml
server:
port: 8000
spring:
profiles:
active: prod//按需激活下面哪个空间
application:
name: service-order
cloud:
nacos:
server-addr: 127.0.0.1:8848
config:
import-check:
enabled: false
namespace: ${spring.profiles.active:public}
---
spring:
config:
import:
- nacos:common.properties?group=order
- nacos:database.properties?group=order
activate:
on-profile: dev
---
spring:
config:
import:
- nacos:common.properties?group=order
- nacos:database.properties?group=order
- nacos:haha.properties?group=order
activate:
on-profile: test
---
spring:
config:
import:
- nacos:common.properties?group=order
- nacos:database.properties?group=order
- nacos:hehe.properties?group=order
activate:
on-profile: prod
OpenFeign

1、引入依赖
<!--openfeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、启动类加注解
@EnableFeignClients(value = "com.atguigu.order.feign")
3、编写FeignClient接口
@FeignClient(value = "service-product")
public interface ProductFeignClient {
@GetMapping(value = "/productId/{id}")
public Product getProductById(@PathVariable("id") Long productId);
}
4、改造service-order OrderServiceImpl
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
DiscoveryClient discoveryClient;
@Autowired
RestTemplate restTemplate;
@Autowired
LoadBalancerClient loadBalancerClient;
@Autowired
ProductFeignClient productFeignClient;
@Override
public Order createOrder(Long productId, Long userId) {
// Product product = getProductFromRemoteWithLoadBalancer(productId);
Product product = productFeignClient.getProduct(productId);
Order order = new Order();
order.setId(1L);
order.setTotalAmount(product.getPrice().multiply(new BigDecimal(product.getNum())));
order.setUserId(userId);
order.setNickName("zhangsang");
order.setAddress("尚尚");
//远程查询商品列表
order.setProductList(Arrays.asList(product));
return order;
}
private Product getProductFromRemoteWithLoadBalancer(Long productId) {
//1、获取到商品服务所在的所有机器IP+port
ServiceInstance choose = loadBalancerClient.choose("service-product");
//远程URL
String url = "http://" + choose.getHost() + ":" + choose.getPort() + "/product/" + productId;
log.info("url:{}", url);
//2、给远程发送请求
Product product = restTemplate.getForObject(url, Product.class);
return product;
}
}
第三方APi,服务不用注册到注册中心
像支付宝API,天气API,feign也可以做到
Authorization 与 Token 的配合逻辑
在绝大多数 API 场景中,二者是 “载体” 与 “内容” 的关系,配合完成认证 / 授权,流程通常是:
用户申请 Token:用户通过账号密码、验证码等方式登录,服务器验证通过后,生成一个有效 Token(如 access_token)返回给客户端;
客户端携带 Token:客户端后续调用 API 时,将 Token 放入 Authorization 请求头(如 Bearer Token 格式),或少数情况下放入请求体;
服务器验证:服务器读取 Authorization 头中的 Token,验证其有效性(是否过期、签名是否正确、权限是否匹配),验证通过则允许请求,否则拒绝。
简单说:用 Authorization 头来 “装” Token,用 Token 来 “完成” 认证—— 二者协同实现 API 的安全访问。
不知为什么墨迹要设计两个地方都要放token

feign接口
@FeignClient(value = "weather-client", url = "http://aliv18.data.moji.com")
public interface WeatherFeignClient {
@PostMapping("/whapi/json/alicityweather/condition")
String getWeather(@RequestHeader("Authorization") String auth,
@RequestParam("token") String token,
@RequestParam("cityId") String cityId);
}
测试方法
@SpringBootTest
public class WeatherTest {
@Autowired
WeatherFeignClient weatherFeignClient;
@Test
public void test() {
String weather = weatherFeignClient.getWeather("自己的AppCode",
"50b53ff8dd7d9fa320d3d3ca32cf8ed1","2182");
System.out.println("weather = " + weather);
}
}
客户端负载均衡和服务端负载均衡的区别?

客户端负载均衡:客户端在选择服务地址进行调用,例如service-order掉哟个service-product
服务端负载均衡:服务端进行负载均衡,客户端只要发请求即可,例如调用墨迹天气API
进阶用法
开启日志
1、application.yml中开启日志
说明: 这行配置是 Spring Boot 的日志配置,用于设置 com.atguigu.order.feign 这个包下的 日志级别 为 DEBUG。
logging:
level:
com.atguigu.order.feign: debug
2、在OrderConfig中设置日志信息
说明:这是 Feign 提供的日志级别配置,它控制 Feign 请求和响应的详细日志,Logger.Level.FULL 代表 打印所有请求和响应的详细信息
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
请求方法(GET、POST等)
请求URL
请求头
请求体
响应状态码
响应头
响应体
请求的执行时间
超时控制


在application.yml引入application-feign.yml
添加application-feign.yml
spring:
cloud:
openfeign:
client:
config:
default:
logger-level: full
connect-timeout: 1000
read-timeout: 2000
service-product:
logger-level: full
connect-timeout: 3000
read-timeout: 5000
重试机制
在service-order 的OrderConfig中加入重试机制
@Bean
Retryer retryer() {
return new Retryer.Default();
}
源码:默认重试5次,初始间隔100毫秒,后续每次乘1.5,最多间隔1秒
拦截器

全局拦截器——拦截所有远程调用请求
1、在service-order 的包下 com.atguigu.order.interceptor
@Component
public class XTokenRequestIntercepter implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
requestTemplate.header("X-Token", UUID.randomUUID().toString());
}
}
2、改造service-product的ProductController
@RestController
public class ProductController {
@Autowired
ProductService productService;
@GetMapping(value = "/productId/{id}")
public Product getProductById(@PathVariable("id") Long productId, HttpServletRequest httpServletRequest) {
String XToken = httpServletRequest.getHeader("X-Token");
System.out.println("XToken = " + XToken);
System.out.println("正在远程调用service-product...");
// int i = 10 / 0;
Product product = productService.getProductById(productId);
return product;
}
}
fallback - 兜底返回

1、引入sentinel依赖(熔断依赖)
<!--sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2、开启熔断
在application-feign.yml加配置
feign:
sentinel:
enabled: true
3、ProductFeignClient加上回调实现
@FeignClient(value = "service-product", fallback = ProductFeignClientFallback.class)
public interface ProductFeignClient {
@GetMapping(value = "/productId/{id}")
public Product getProductById(@PathVariable("id") Long productId);
}
4、ProductFeignClientFallback
@Component
public class ProductFeignClientFallback implements ProductFeignClient {
@Override
public Product getProductById(Long productId) {
System.out.println("兜底回调....");
Product product = new Product();
product.setId(productId);
product.setPrice(new BigDecimal("0"));
product.setProductName("未知商品");
product.setNum(0);
return product;
}
}
Sentinel(服务保护,限流,熔断降级)
限流,通过sentinel服务限制请求各微服务的流量,提前控制太多请求
熔断,如果发现在一定规则下某个微服务请求不了,通过sentinel服务提前触发熔断,不请求该服务,直接返回错误信息,避免下个服务还在等待


环境搭建
1、下载sentinel dashboard
📎sentinel-dashboard-1.8.8.jar
启动:
cmd输入:java -jar sentinel.jar
2、配置连接+热加载(服务启动就加载)
spring.cloud.sentinel.transport.dashboard=localhost:8080
spring.cloud.sentinel.eager=true
3、 对应的controller加入注解 @SentinelResource("createOrder")
里面createOrder是对应的方法,其实就是对应链接,这个链接可以设置熔断机制
4、如果设置了流控规则,设置为1就是每秒只能通过1个,太快了就会显示 Blocked by Sentinel (flow limiting)
![熔断界面]
(https://img2024.cnblogs.com/blog/3548872/202508/3548872-20250831135529790-254529803.png)
异常处理
什么样的异常对应什么样的异常处理(不自定义就会显示默认的)
web接口对应请求链接
@sentineresource是对应链接中的方法
opnefeign是对应方法中请求的链接,就看异常显示的颗粒度到什么程度

Web接口 出现异常
model模块写异常类
模拟异常处理
@Data
public class R {
private Integer code;
private String msg;
private Object data;
public static R ok() {
R r = new R();
r.setCode(200);
return r;
}
public static R ok(String msg,Object data) {
R r = new R();
r.setCode(200);
r.setMsg(msg);
r.setData(data);
return r;
}
public static R error() {
R r = new R();
r.setCode(500);
return r;
}
public static R error(Integer code,String msg) {
R r = new R();
r.setCode(code);
r.setMsg(msg);
return r;
}
}
实现BlockExceptionHandler接口
在service-order的 com.atguigu.order.exception包中写一个BlockExceptionHandler的实现类
@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
String resourceName, BlockException e) throws Exception {
response.setStatus(429); //too many requests
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
R error = R.error(500, resourceName + " 被Sentinel限制了,原因:" + e.getClass());
String json = objectMapper.writeValueAsString(error);
writer.write(json);
writer.flush();
writer.close();
}
}

流量控制

流控模式
直接、关联,链路的策略具体怎么用再看这个博客
流程模式
流控效果
也是看上面的博客
熔断降级


热点规则(比流控更为精细,可以控制参数)

Gateway(网关)

1、建module: gateway微服务
2、改pom
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>annotationProcessor</scope>
</dependency>
</dependencies>
3、写yml
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
profiles:
include: route
server:
port: 80
路由规则配置
写application-route.yml,后期前端请求网关时只要路径是/api/order/**就是由网关转发至service-order服务,过去是前端从nacos拿到服务的IP后,由前端直接和服务对接
spring:
cloud:
gateway:
routes:
- id: order
uri: lb://service-order
predicates:
- Path=/api/order/**
- id: product
uri: lb://service-product
predicates:
- Path=/api/product/**
同时业务类ordercontroller也要加@RequestMapping("/api/order")
断言,长短写法
短写法
这里根据不同服务的predicates条件,将请求执行不同服务的uri
order:代表predicates执行顺序,越下越优先
spring:
cloud:
gateway:
routes:
- id: order
uri: lb://service-order
predicates:
- Path=/api/order/**
- id: product
uri: lb://service-product
predicates:
- Path=/api/product/**
长写法

predicates可选列表

自定义predicates
略
上面predicates作用就是只有满足什么路径或携带什么参数才能访问指定的服务
过滤器

写法
也有长写法和短写法
在配置文件上写,例如要做路径重写
- RewritePath=/api/order/?(?
.*), /$
这条规则的作用是:将路径 /api/order/{任意内容} 重写为 /{任意内容}。换句话说,它去掉了 /api/order/ 前缀,保留了后面的路径部分。
例如:
/api/order/123 会被重写为 /123
/api/order/abc/xyz 会被重写为 /abc/xyz
这类配置通常用于将请求从一个路径重定向到另一个路径,或者将路径中的某些部分移除。
在此处的作用是不用在各微服务加前缀,这里可以统一管理。
自定义Filter
可以用于响应时自定义响应头
vue,gateway,nginx一般是怎么用的,三者都能做代理转发,在解决跨域问题时,一般是怎么选择的?
- 开发环境:Vue 用代理,Nginx 暂作 “测试入口”
开发阶段,Vue 通常通过 npm run serve 启动本地开发服务(端口 8080),此时前端资源还未打包,无法直接由 Nginx 托管;Gateway 独立启动(端口 9000)。
为了模拟生产环境的 “统一入口” 并解决跨域,可通过 Vue 开发代理 + Nginx 转发 配合
- 生产环境:Nginx 托管 Vue 资源 + 转发接口
生产环境中,Vue 会先执行 npm run build 打包成静态资源(dist 目录),然后由 Nginx 直接托管这些资源;Gateway 正常运行(端口 9000)。此时 Nginx 是唯一的外部入口,所有请求(前端资源 + 后端接口)都通过 Nginx 进入,跨域问题在 Nginx 或 Gateway 层彻底解决。
关键总结
1、统一入口是核心:无论开发还是生产环境,都通过 Nginx 作为唯一入口,前端只和 Nginx 交互,从根源避免跨域。
2、开发 / 生产环境差异:开发阶段用 Vue 代理模拟 Nginx 入口,生产阶段 Nginx 直接托管 Vue 静态资源,减少请求链路。
3、跨域配置二选一:推荐在 Nginx 层配置(更靠前,性能更好),若需动态调整则在 Gateway 层配置,避免重复配置。
4、路由规则统一:前端接口请求统一用 /api 前缀,Nginx 和 Gateway 围绕该前缀配置转发,避免路径混乱。
常见架构组合:Nginx + Spring Cloud Gateway(各司其职)
在实际项目中,二者并非 “非此即彼”,而是常结合使用,发挥各自优势,典型架构如下:
plaintext
用户请求 → Nginx(第一层网关) → 分两种流向:
1. 静态资源请求(如Vue的JS/CSS/图片)→ Nginx直接返回(利用Nginx静态资源高性能优势)
2. API请求(如/api/xxx)→ 转发到 Spring Cloud Gateway(第二层网关)→ 由Gateway完成:
- 服务名路由(如/api/user → 用户服务)
- 鉴权(JWT验证)、限流、熔断
- 转发到具体微服务实例
这种组合的优势:
Nginx 扛住静态资源和第一层流量转发,减轻 Gateway 压力;
Gateway 专注于微服务 API 治理,无需处理静态资源;
跨域可在 Nginx 或 Gateway 中配置(推荐在 Gateway 中统一配置,更灵活)。
Seata 分布式事务
1、seata有服务器端和客户端,客户端要连上服务器才能使用。
2、TC(事务协调者)在服务器端 得官网下载: 全局事务的管理者。用于维护全局和分支事务的状态,驱动TM的全局提交和回滚。TM和RM通过TC注册分支和汇报状态。
3、TM(事务管理器)在客户端:发起全局事务,定义全局事务的范围,操作全局事务的提交和回滚。
4、RM(资源管理器)在客户端:操作自己分支的事务提交和回滚。
注意:seata的稳定性非常重要,如果TC崩了,那所有的事务管控都失效。

使用步骤
下载seata服务端:Seata Java Download | Apache Seata
解压并启动:seata-server.bat 访问:http://localhost:7091/ 账号密码都是seata
在微服务中导入spring-cloud-starter-alibaba-seata依赖
在resources里配置file.conf文件,每个seata服务都配置
service {
#transaction service group mapping
vgroupMapping.default_tx_group = "default"
#only support when registry.type=file, please don't set multiple addresses
default.grouplist = "127.0.0.1:8091"
#degrade, current not support
enableDegrade = false
#disable seata
disableGlobalTransaction = false
}
1、在RM分支事务微服务中启动类上加入@EnableTransactionManagement,在具体事务service方法上加@Transactional
2、在TM全局事务微服务中启动类上不加@EnableTransactionManagement,但在事务service方法上要加上@GlobalTransactional。这个注解是核心
3、测试结果

浙公网安备 33010602011771号