当前位置: 首页 > news >正文

springCload快速入门

原作者:3. SpringCloud - 快速通关

前置知识:

  1. Java17及以上、Maven
  2. SpringBoot、SpringMVC、MyBatis
  3. Linux、Docker

1. 分布式基础

1.1. 微服务

微服务架构风格,就像是把一个单独的应用程序开发为一套小服务,每个小服务运行在自己进程中,并使用轻量级机制通信,通常是 HTTP API。这些服务围绕业务能力来构建, 并通过完全自动化部署机制来独立部署。这些服务使用不同的编程语言书写,以及不同数据存储技术,并保持最低限度的集中式管理。

简而言之:拒绝大型单体应用,基于业务边界进行服务微化拆分,各个服务独立部署运行。

1.2. 集群&分布式&节点

集群是个物理形态,分布式是个工作方式。

只要是一堆机器,就可以叫集群,他们是不是一起协作着干活,这个谁也不知道;

《分布式系统原理与范型》定义:

  • “分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统”
  • 分布式系统(distributed system)是建立在网络之上的软件系统。

分布式是指将不同的业务分布在不同的地方。

集群指的是将几台服务器集中在一起,实现同一业务。

例如:京东是一个分布式系统,众多业务运行在不同的机器,所有业务构成一个大型的业务集群。每一个小的业务,比如用户系统,访问压力大的时候一台服务器是不够的。我们就应该将用户系统部署到多个服务器,也就是每一个业务系统也可以做集群化

分布式中的每一个节点,都可以做集群。 而集群并不一定就是分布式的。

节点:集群中的一个服务器

1.3. 远程调用

在分布式系统中,各个服务可能处于不同主机,但是服务之间不可避免的需要互相调用,我们称为远程调用。 SpringCloud 中使用 HTTP+JSON 的方式完成远程调用

1.4. 负载均衡

分布式系统中,A 服务需要调用 B 服务,B 服务在多台机器中都存在,A 调用任意一个服务器均可完成功能。 为了使每一个服务器都不要太忙或者太闲,我们可以负载均衡的调用每一个服务器,提升网站的健壮性。

常见的负载均衡算法:

  • 轮询:为第一个请求选择健康池中的第一个后端服务器,然后按顺序往后依次选择,直到最后一个,然后循环。
  • 最小连接:优先选择连接数最少,也就是压力最小的后端服务器,在会话较长的情况下可以考虑采取这种方式。
  • 散列:根据请求源的 IP 的散列(hash)来选择要转发的服务器。这种方式可以一定程度上保证特定用户能连接到相同的服务器。如果你的应用需要处理状态而要求用户能连接到和之前相同的服务器,可以考虑采取这种方式。

1.5. 服务注册/发现&注册中心

A 服务调用 B 服务,A 服务并不知道 B 服务当前在哪几台服务器有,哪些正常的,哪些服务已经下线。解决这个问题可以引入注册中心;

如果某些服务下线,我们其他人可以实时的感知到其他服务的状态,从而避免调用不可用的服务

1.6. 配置中心

每一个服务最终都有大量的配置,并且每个服务都可能部署在多台机器上。我们经常需要变更配置,我们可以让每个服务在配置中心获取自己的配置。

配置中心用来集中管理微服务的配置信息

1.7. 服务熔断&服务降级

在微服务架构中,微服务之间通过网络进行通信,存在相互依赖,当其中一个服务不可用时,有可能会造成雪崩效应。要防止这样的情况,必须要有容错机制来保护服务。

1)、服务熔断

设置服务的超时,当被调用的服务经常失败到达某个阈值,我们可以开启断路保护机制,后来的请求不再去调用这个服务。本地直接返回默认的数据

2)、服务降级

在运维期间,当系统处于高峰期,系统资源紧张,我们可以让非核心业务降级运行。降级:某些服务不处理,或者简单处理【抛异常、返回 NULL、调用 Mock 数据、调用 Fallback 处理逻辑】

1.8. API 网关

在微服务架构中,API Gateway 作为整体架构的重要组件,它抽象了微服务中都需要的公共功能,同时提供了客户端负载均衡服务自动熔断灰度发布统一认证限流流控日志统计等丰富的功能,帮助我们解决很多 API 管理难题。

2. Spring Cloud

2.1. 技术配置

Spring Cloud 系列

  • 官网:Spring Cloud
  • 远程调用:OpenFeign
  • 网关:Gateway

Spring Cloud Alibaba 系列

  • 官网:Spring Cloud Alibaba官网_基于Springboot的微服务教程-阿里云
  • 注册中心/配置中心:Nacos
  • 服务保护:Sentinel
  • 分布式事务:Seata

2.2. 版本

2.3. 实践

创建父项目引入公共依赖

<?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>

3. Nacos - 注册/配置中心

3.1. 基础入门

3.1.1. 简介

官网:Nacos 快速开始 | Nacos 官网

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

3.1.2. 安装

  • Docker 安装
docker run -d -p 8848:8848 -p 9848:9848 -e MODE=standalone --name nacos nacos/nacos-server:v2.4.3
  • 下载软件包:📎nacos-server-2.4.3.zip
  • 启动:startup.cmd -m standalone

3.2. 注册中心

3.2.1. 依赖引入

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

3.2.2. 整合配置

1、在 application.properties中配置如下

spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848#暂未用到配置中心功能,需要关闭配置检查
#spring.cloud.nacos.config.import-check.enabled=false

2、开启服务注册/发现功能

@EnableDiscoveryClient //核心注解
@SpringBootApplication
public class OrderMainApplication {public static void main(String[] args) {SpringApplication.run(OrderMainApplication.class, args);}}

3.2.3. 服务注册

3.2.3.1. 查看效果

访问:http://localhost:8848/nacos 可以看到服务已经注册上来;

3.2.3.2. 注册更多
  1. 创建 service-product服务
  2. 引入 nacos依赖
  3. 配置 nacos地址信息
    1. 注意:每个微服务端口不一样
  1. 启动应用,查看是否注册成功

3.2.3.3. 启动集群

service-order为例,启动 movie 的三个服务。

  1. idea 搜索 services面板,添加 SpringBoot 项目。
  1. 复制 OrderMainApplication三份,每个启动命令重新指定端口

3.2.3.4. 查看集群

3.2.4. 服务发现

3.2.4.1. DiscoveryClient
@Autowired
DiscoveryClient discoveryClient;
@Test
void discoveryClientTest(){for (String service : discoveryClient.getServices()) {System.out.println("service = " + service);//获取ip+portList<ServiceInstance> instances = discoveryClient.getInstances(service);for (ServiceInstance instance : instances) {System.out.println("ip:"+instance.getHost()+";"+"port = " + instance.getPort());}}
}

3.2.4.2. NacosServiceDiscovery
@Autowired
NacosServiceDiscovery nacosServiceDiscovery;
@Test
void  nacosServiceDiscoveryTest() throws NacosException {for (String service : nacosServiceDiscovery.getServices()) {System.out.println("service = " + service);List<ServiceInstance> instances = nacosServiceDiscovery.getInstances(service);for (ServiceInstance instance : instances) {System.out.println("ip:"+instance.getHost()+";"+"port = " + instance.getPort());}}
}

3.2.4.3. 模拟掉线

随机中断一个服务,运行代码或在界面查看效果

3.2.5. 远程调用

3.2.5.1. 配置 RestTemplate
@Configuration
public class UserConfiguration {@BeanRestTemplate restTemplate() {return new RestTemplate();}
}

3.2.5.2. 测试调用
	@AutowiredRestTemplate restTemplate;@Testvoid testRestTemplate() {String forObject = restTemplate.getForObject("http://localhost:8080/movie", String.class);System.out.println(forObject);System.out.println("-----------------------------");}

3.2.5.3. 小结
  1. 使用 RestTemplate 可以获取到远程数据
  2. 必须精确指定地址和端口
  3. 如果远程宕机将不可用

期望:可以负载均衡调用,不用担心远程宕机

3.2.6. 负载均衡

3.2.6.1. 依赖导入
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

3.2.6.2. LoadBalancerClient
    // 进阶2:完成负载均衡发送请求private Product getProductFromRemoteWithLoadBalance(Long productId){//1、获取到商品服务所在的所有机器IP+portServiceInstance choose = loadBalancerClient.choose("service-product");//远程URLString url = "http://"+choose.getHost() +":" +choose.getPort() +"/product/"+productId;log.info("远程请求:{}",url);//2、给远程发送请求Product product = restTemplate.getForObject(url, Product.class);return product;}

3.2.6.3. 注解式负载均衡
@Configuration
public class UserConfiguration {@LoadBalanced@BeanRestTemplate restTemplate() {return new RestTemplate();}}

    // 进阶3:基于注解的负载均衡private Product getProductFromRemoteWithLoadBalanceAnnotation(Long productId){String url = "http://service-product/product/"+productId;//2、给远程发送请求; service-product 会被动态替换Product product = restTemplate.getForObject(url, Product.class);return product;}
3.2.6.4. 小结
  1. 负载均衡调用只需要传入服务名
  2. 请求发起之前会自动去注册中心确定微服务地址
  3. 如果微服务宕机,会自动剔除在线名单,请求将不会发过去

3.2.7. 深入探索

经典面试题:

如果注册中心宕机,远程调用是否可以成功?

  1. 从未调用过,如果宕机,调用会立即失败
  2. 调用过,如果宕机,因为会缓存名单,调用会成功
  3. 调用过,如果注册中心和对方服务宕机,因为会缓存名单,调用会阻塞后失败(Connection Refused)

3.3. 配置中心

主要提示:

3.3.1. 整合配置

3.3.1.1. 依赖引入
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
3.3.1.2. 配置文件

application.properties

# 指定配置中心地址
spring.cloud.nacos.server-addr=localhost:8848
spring.config.import=nacos:service-order.properties

3.3.1.3. 配置集-dataId

3.3.2. 动态刷新

3.3.2.1. @RefreshScope
@RefreshScope//自动刷新
@RestController
public class OrderController {@AutowiredOrderService orderService;@Value("${order.timeout}")String orderTimeout;@Value("${order.auto-confirm}")String orderAutoConfirm;@AutowiredOrderProperties orderProperties;@GetMapping("/config")public String config(){return "order.timeout="+orderProperties.getTimeout()+"; " +"order.auto-confirm="+orderProperties.getAutoConfirm() +";"+"order.db-url="+orderProperties.getDbUrl();}
}

3.3.2.2. ConfigurationProperties

无需 @RefreshScope,自动绑定配置,动态更新

@Component
@ConfigurationProperties(prefix = "order") //配置批量绑定在nacos下,可以无需@RefreshScope就能实现自动刷新
@Data
public class OrderProperties {String timeout;String autoConfirm;String dbUrl;
}

3.3.3. NacosConfigManager

	@BeanApplicationRunner applicationRunner(NacosConfigManager manager){return args -> {ConfigService configService = manager.getConfigService();configService.addListener("service-order.properties", "DEFAULT_GROUP", new Listener() {@Overridepublic Executor getExecutor() {return Executors.newFixedThreadPool(4);}@Overridepublic void receiveConfigInfo(String configInfo) {System.out.println("configInfo = " + configInfo);}});};}

3.3.4. namespace、dataId、group

3.3.4.1. namespace

命名空间:实现多环境隔离,如:开发、测试、预发、生产等

3.3.4.2. dataId

数据集id:就是以前配置文件的名字。完整写法:名字.后缀 如:common.properties

3.3.4.3. groupId

分组id:一般可以用微服务的名字作为自己的组。

3.3.4.4. 推荐用法

4. OpenFeign - 远程调用

4.1. 基础入门

官网:Spring Cloud OpenFeign Features :: Spring Cloud Openfeign

4.1.1. 简介

OpenFeign 是一个声明式远程调用客户端

4.1.2. 引入依赖

由于大型项目中,每个项目都可能需要使用远程调用。所以我们可以在父项目中统一引入

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

4.1.3. 开启功能

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

4.1.4. 远程调用

@FeignClient("stores")
public interface StoreClient {@RequestMapping(method = RequestMethod.GET, value = "/stores")List<Store> getStores();@GetMapping("/stores")Page<Store> getStores(Pageable pageable);@PostMapping(value = "/stores/{storeId}", consumes = "application/json",params = "mode=upsert")Store update(@PathVariable("storeId") Long storeId, Store store);@DeleteMapping("/stores/{storeId:\\d+}")void delete(@PathVariable Long storeId);
}

注意用法:

@EnableFeignClients

@EnableFeignClients(basePackages = "com.example.clients")

4.2. 进阶配置

4.2.1. 开启日志

logging:level:com.atguigu.order.feign: debug
@Bean
Logger.Level feignLoggerLevel() {return Logger.Level.FULL;
}

4.2.2. 超时控制

spring:cloud:openfeign:client:config:default:logger-level: fullconnect-timeout: 1000read-timeout: 2000service-product:logger-level: fullconnect-timeout: 3000read-timeout: 5000

4.2.3. 重试机制

@Bean
Retryer retryer(){return new Retryer.Default();
}

4.2.4. fallback - 兜底返回

  1. 引入 sentinel
        <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>
  1. 开启熔断
feign:sentinel:enabled: true

  1. 编写 fallback 函数
@FeignClient(value = "service-product",fallback = ProductFeignClientFallback.class) // feign客户端
public interface ProductFeignClient {//mvc注解的两套使用逻辑//1、标注在Controller上,是接受这样的请求//2、标注在FeignClient上,是发送这样的请求@GetMapping("/product/{id}")Product getProductById(@PathVariable("id") Long id);}

@Component
public class ProductFeignClientFallback implements ProductFeignClient {@Overridepublic Product getProductById(Long id) {System.out.println("兜底回调....");Product product = new Product();product.setId(id);product.setPrice(new BigDecimal("0"));product.setProductName("未知商品");product.setNum(0);return product;}
}

5. Sentinel - 流量保护

5.1. 介绍

官网:home | Sentinel

wiki:https://github.com/alibaba/Sentinel/wiki

下载控制台:📎sentinel-dashboard-1.8.8.jar

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、流量路由、熔断降级、系统自适应过载保护、热点流量防护等多个维度保护服务的稳定性。

Sentinel 具有以下特征:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Apache Dubbo、gRPC、Quarkus 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。同时 Sentinel 提供 Java/Go/C++ 等多语言的原生实现。
  • 完善的 SPI 扩展机制:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

5.2. 架构

5.3. 资源&规则

定义资源:

  • 主流框架自动适配(Web Servlet、Dubbo、Spring Cloud、gRPC、Spring WebFlux、Reactor);所有Web接口均为资源
  • 编程式:SphU API
  • 声明式:@SentinelResource

定义规则:

  • 流量控制规则
  • 熔断降级规则
  • 系统保护规则
  • 来源访问控制规则
  • 热点参数规则

5.4. 环境搭建

5.4.1. 依赖

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

5.4.2. 启动控制台

java -jar sentinel.jar

5.4.3. 配置连接

spring:cloud:sentinel:transport:dashboard: localhost:8080

5.5. 异常处理

5.5.1. 自定义 BlockExceptionHandler

@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {private ObjectMapper objectMapper = new ObjectMapper();@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response,String resourceName, BlockException e) throws Exception {response.setStatus(429); //too many requestsresponse.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();}
}

5.5.2. blockHandler

 @SentinelResource(value = "createOrder",blockHandler = "createOrderFallback")@Overridepublic Order createOrder(Long productId, Long userId) {
//        Product product = getProductFromRemoteWithLoadBalanceAnnotation(productId);//使用Feign完成远程调用Product product = productFeignClient.getProductById(productId);Order order = new Order();order.setId(1L);// 总金额order.setTotalAmount(product.getPrice().multiply(new BigDecimal(product.getNum())));order.setUserId(userId);order.setNickName("zhangsan");order.setAddress("尚硅谷");//远程查询商品列表order.setProductList(Arrays.asList(product));return order;}//兜底回调public Order createOrderFallback(Long productId, Long userId, BlockException e){Order order = new Order();order.setId(0L);order.setTotalAmount(new BigDecimal("0"));order.setUserId(userId);order.setNickName("未知用户");order.setAddress("异常信息:"+e.getClass());return order;}

5.5.3. OpenFeign - 兜底回调

@FeignClient(value = "service-product",fallback = ProductFeignClientFallback.class) // feign客户端
public interface ProductFeignClient {//mvc注解的两套使用逻辑//1、标注在Controller上,是接受这样的请求//2、标注在FeignClient上,是发送这样的请求@GetMapping("/product/{id}")Product getProductById(@PathVariable("id") Long id);}

@Component
public class ProductFeignClientFallback implements ProductFeignClient {@Overridepublic Product getProductById(Long id) {System.out.println("兜底回调....");Product product = new Product();product.setId(id);product.setPrice(new BigDecimal("0"));product.setProductName("未知商品");product.setNum(0);return product;}
}

5.6. 规则 - 流量控制

5.6.1. 阈值类型

QPS:统计每秒请求数

并发线程数:统计并发线程数

5.6.2. 流控模式

5.6.3. 流控效果

5.7. 规则 - 熔断降级

5.7.1. 断路器

5.7.2. 工作原理

5.7.3. 熔断与兜底

5.8. 规则 - 热点参数

5.8.1. 环境搭建

 @GetMapping("/seckill")@SentinelResource(value = "seckill-order",fallback = "seckillFallback")public Order seckill(@RequestParam(value = "userId",required = false) Long userId,@RequestParam(value = "productId",defaultValue = "1000") Long productId){Order order = orderService.createOrder(productId, userId);order.setId(Long.MAX_VALUE);return order;}public Order seckillFallback(Long userId,Long productId, BlockException exception){System.out.println("seckillFallback....");Order order = new Order();order.setId(productId);order.setUserId(userId);order.setAddress("异常信息:"+exception.getClass());return order;}

6. Gateway - 网关

官网:Spring Cloud Gateway

6.1. 基础入门

6.1.1. 功能

6.1.2. HelloWorld

/api/order/**路由给订单

/api/product/**路由给商品

测试负载均衡

6.1.2.1. 创建项目

引入 spring-cloud-starter-gatewayspring-cloud-starter-alibaba-nacos-discovery

<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>

6.1.2.2. 改造微服务
  • 为 service-order、service-prduct 添加 /api基础路径

6.1.2.3. 配置网关

创建 application.yml编写如下配置

spring:cloud:gateway:routes:- id: orderuri: lb://service-orderpredicates:- Path=/api/order/**- id: producturi: lb://service-productpredicates:- Path=/api/product/**   

6.1.3. 原理

6.2. Predicate - 断言

spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- After=2017-01-20T17:42:47.789-07:00[America/Denver]

参数(个数/类型)

作用

After

1/datetime

在指定时间之后

Before

1/datetime

在指定时间之前

Between

2/datetime

在指定时间区间内

Cookie

2/string,regexp

包含cookie名且必须匹配指定值

Header

2/string,regexp

包含请求头且必须匹配指定值

Host

N/string

请求host必须是指定枚举值

Method

N/string

请求方式必须是指定枚举值

Path

2/List<String>,bool

请求路径满足规则,是否匹配最后的/

Query

2/string,regexp

包含指定请求参数

RemoteAddr

1/List<String>

请求来源于指定网络域(CIDR写法)

Weight

2/string,int

按指定权重负载均衡

XForwardedRemoteAddr

1/List<string>

从X-Forwarded-For请求头中解析请求来源,并判断是否来源于指定网络域

6.3. Filter - 过滤器

参数(个数/类型)

作用

AddRequestHeader

2/string

添加请求头

AddRequestHeadersIfNotPresent

1/List<string>

如果没有则添加请求头,key:value方式

AddRequestParameter

2/string、string

添加请求参数

AddResponseHeader

2/string、string

添加响应头

CircuitBreaker

1/string

仅支持forward:/inCaseOfFailureUseThis方式进行熔断

CacheRequestBody

1/string

缓存请求体

DedupeResponseHeader

1/string

移除重复响应头,多个用空格分割

FallbackHeaders

1/string

设置Fallback头

JsonToGrpc

请求体Json转为gRPC

LocalResponseCache

2/string

响应数据本地缓存

MapRequestHeader

2/string

把某个请求头名字变为另一个名字

ModifyRequestBody

仅 Java 代码方式

修改请求体

ModifyResponseBody

仅 Java 代码方式

修改响应体

PrefixPath

1/string

自动添加请求前缀路径

PreserveHostHeader

0

保护Host头

RedirectTo

3/string

重定向到指定位置

RemoveJsonAttributesResponseBody

1/string

移除响应体中的某些Json字段,多个用,分割

RemoveRequestHeader

1/string

移除请求头

RemoveRequestParameter

1/string

移除请求参数

RemoveResponseHeader

1/string

移除响应头

RequestHeaderSize

2/string

设置请求大小,超出则响应431状态码

RequestRateLimiter

1/string

请求限流

RewriteLocationResponseHeader

4/string

重写Location响应头

RewritePath

2/string

路径重写

RewriteRequestParameter

2/string

请求参数重写

RewriteResponseHeader

3/string

响应头重写

SaveSession

0

session保存,配合spring-session框架

SecureHeaders

0

安全头设置

SetPath

1/string

路径修改

SetRequestHeader

2/string

请求头修改

SetResponseHeader

2/string

响应头修改

SetStatus

1/int

设置响应状态码

StripPrefix

1/int

路径层级拆除

Retry

7/string

请求重试设置

RequestSize

1/string

请求大小限定

SetRequestHostHeader

1/string

设置Host请求头

TokenRelay

1/string

OAuth2的token转发

6.4. CORS - 跨域处理

全局跨域

spring:cloud:gateway:globalcors:cors-configurations:'[/**]':allowedOrigins: "https://docs.spring.io"allowedMethods:- GET

局部跨域

spring:cloud:gateway:routes:- id: cors_routeuri: https://example.orgpredicates:- Path=/service/**metadata:cors:allowedOrigins: '*'allowedMethods:- GET- POSTallowedHeaders: '*'maxAge: 30

6.5. GlobalFilter

@Bean
public GlobalFilter customFilter() {return new CustomGlobalFilter();
}public class CustomGlobalFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info("custom global filter");return chain.filter(exchange);}@Overridepublic int getOrder() {return -1;}
}

7. Seata - 分布式事务

官网:Apache Seata

7.1. 环境搭建

7.1.1. 微服务

下载 seata 工程文件,导入到项目中,并在 services中添加module聚合

📎seata-demo.zip

7.1.2. SQL

启动一个数据库,然后运行如下sql文件

CREATE DATABASE IF NOT EXISTS `storage_db`;
USE  `storage_db`;
DROP TABLE IF EXISTS `storage_tbl`;
CREATE TABLE `storage_tbl` (`id` int(11) NOT NULL AUTO_INCREMENT,`commodity_code` varchar(255) DEFAULT NULL,`count` int(11) DEFAULT 0,PRIMARY KEY (`id`),UNIQUE KEY (`commodity_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO storage_tbl (commodity_code, count) VALUES ('P0001', 100);
INSERT INTO storage_tbl (commodity_code, count) VALUES ('B1234', 10);-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log
DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`branch_id` bigint(20) NOT NULL,`xid` varchar(100) NOT NULL,`context` varchar(128) NOT NULL,`rollback_info` longblob NOT NULL,`log_status` int(11) NOT NULL,`log_created` datetime NOT NULL,`log_modified` datetime NOT NULL,`ext` varchar(100) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;CREATE DATABASE IF NOT EXISTS `order_db`;
USE  `order_db`;
DROP TABLE IF EXISTS `order_tbl`;
CREATE TABLE `order_tbl` (`id` int(11) NOT NULL AUTO_INCREMENT,`user_id` varchar(255) DEFAULT NULL,`commodity_code` varchar(255) DEFAULT NULL,`count` int(11) DEFAULT 0,`money` int(11) DEFAULT 0,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log
DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`branch_id` bigint(20) NOT NULL,`xid` varchar(100) NOT NULL,`context` varchar(128) NOT NULL,`rollback_info` longblob NOT NULL,`log_status` int(11) NOT NULL,`log_created` datetime NOT NULL,`log_modified` datetime NOT NULL,`ext` varchar(100) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;CREATE DATABASE IF NOT EXISTS `account_db`;
USE  `account_db`;
DROP TABLE IF EXISTS `account_tbl`;
CREATE TABLE `account_tbl` (`id` int(11) NOT NULL AUTO_INCREMENT,`user_id` varchar(255) DEFAULT NULL,`money` int(11) DEFAULT 0,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO account_tbl (user_id, money) VALUES ('1', 10000);
-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log
DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`branch_id` bigint(20) NOT NULL,`xid` varchar(100) NOT NULL,`context` varchar(128) NOT NULL,`rollback_info` longblob NOT NULL,`log_status` int(11) NOT NULL,`log_created` datetime NOT NULL,`log_modified` datetime NOT NULL,`ext` varchar(100) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

7.1.3. seata-server

  1. 下载:Seata Java Download | Apache Seata

📎apache-seata-2.1.0-incubating-bin.tar.gz

  1. 解压并启动:seata-server.bat

7.1.4. 微服务配置

7.1.4.1. 依赖
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
7.1.4.2. 配置

每个微服务创建 file.conf文件,完整内容如下;

【微服务只需要复制 service 块配置即可】

#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#transport {# tcp, unix-domain-sockettype = "TCP"#NIO, NATIVEserver = "NIO"#enable heartbeatheartbeat = true# the tm client batch send request enableenableTmClientBatchSendRequest = false# the rm client batch send request enableenableRmClientBatchSendRequest = true# the rm client rpc request timeoutrpcRmRequestTimeout = 2000# the tm client rpc request timeoutrpcTmRequestTimeout = 30000# the rm client rpc request timeoutrpcRmRequestTimeout = 15000#thread factory for nettythreadFactory {bossThreadPrefix = "NettyBoss"workerThreadPrefix = "NettyServerNIOWorker"serverExecutorThread-prefix = "NettyServerBizHandler"shareBossWorker = falseclientSelectorThreadPrefix = "NettyClientSelector"clientSelectorThreadSize = 1clientWorkerThreadPrefix = "NettyClientWorkerThread"# netty boss thread sizebossThreadSize = 1#auto default pin or 8workerThreadSize = "default"}shutdown {# when destroy server, wait secondswait = 3}serialization = "seata"compressor = "none"
}
service {#transaction service group mappingvgroupMapping.default_tx_group = "default"#only support when registry.type=file, please don't set multiple addressesdefault.grouplist = "127.0.0.1:8091"#degrade, current not supportenableDegrade = false#disable seatadisableGlobalTransaction = false
}client {rm {asyncCommitBufferLimit = 10000lock {retryInterval = 10retryTimes = 30retryPolicyBranchRollbackOnConflict = true}reportRetryCount = 5tableMetaCheckEnable = falsetableMetaCheckerInterval = 60000reportSuccessEnable = falsesagaBranchRegisterEnable = falsesagaJsonParser = "fastjson"sagaRetryPersistModeUpdate = falsesagaCompensatePersistModeUpdate = falsetccActionInterceptorOrder = -2147482648 #Ordered.HIGHEST_PRECEDENCE + 1000sqlParserType = "druid"branchExecutionTimeoutXA = 60000connectionTwoPhaseHoldTimeoutXA = 10000}tm {commitRetryCount = 5rollbackRetryCount = 5defaultGlobalTransactionTimeout = 60000degradeCheck = falsedegradeCheckPeriod = 2000degradeCheckAllowTimes = 10interceptorOrder = -2147482648 #Ordered.HIGHEST_PRECEDENCE + 1000}undo {dataValidation = trueonlyCareUpdateColumns = truelogSerialization = "jackson"logTable = "undo_log"compress {enable = true# allow zip, gzip, deflater, lz4, bzip2, zstd default is ziptype = zip# if rollback info size > threshold, then will be compress# allow k m g tthreshold = 64k}}loadBalance {type = "XID"virtualNodes = 10}
}
log {exceptionRate = 100
}
tcc {fence {# tcc fence log table namelogTableName = tcc_fence_log# tcc fence log clean periodcleanPeriod = 1h}
}

7.2. 事务模式

7.2.1. AT

二阶提交协议原理

7.2.2. XA

7.2.3. TCC

7.2.4. Saga

8. 总结

相关文章:

springCload快速入门

原作者&#xff1a;3. SpringCloud - 快速通关 前置知识&#xff1a; Java17及以上、MavenSpringBoot、SpringMVC、MyBatisLinux、Docker 1. 分布式基础 1.1. 微服务 微服务架构风格&#xff0c;就像是把一个单独的应用程序开发为一套小服务&#xff0c;每个小服务运行在自…...

从 HTTP/1.1 到 HTTP/3:如何影响网页加载速度与性能

一、前言 在最近使用Apipost时&#xff0c;突然注意到了http/1.1和http/2&#xff0c;如下图&#xff1a; 在我根深蒂固的记忆中&#xff0c;对于http的理解还停留在TCP协议、三次握手。由于我的好奇心&#xff0c;于是触发了我被动“开卷”&#xff0c;所以有了这篇文章&…...

人工智能导论-第3章-知识点与学习笔记

参考教材3.2节的内容&#xff0c;介绍什么是自然演绎推理&#xff1b;解释“肯定后件”与“否定前件”两类错误的演绎推理是什么意义&#xff0c;给出具体例子加以阐述。参考教材3.3节的内容&#xff0c;介绍什么是文字&#xff08;literal&#xff09;&#xff1b;介绍什么是子…...

游戏引擎 Unity - Unity 下载与安装

Unity Unity 首次发布于 2005 年&#xff0c;属于 Unity Technologies Unity 使用的开发技术有&#xff1a;C# Unity 的适用平台&#xff1a;PC、主机、移动设备、VR / AR、Web 等 Unity 的适用领域&#xff1a;开发中等画质中小型项目 Unity 适合初学者或需要快速上手的开…...

鼠标拖尾特效

文章目录 鼠标拖尾特效一、引言二、实现原理1、监听鼠标移动事件2、生成拖尾元素3、控制元素生命周期 三、代码实现四、使用示例五、总结 鼠标拖尾特效 一、引言 鼠标拖尾特效是一种非常酷炫的前端交互效果&#xff0c;能够为网页增添独特的视觉体验。它通常通过JavaScript和C…...

4 前置技术(下):git使用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 前言...

从零开始:用Qt开发一个功能强大的文本编辑器——WPS项目全解析

文章目录 引言项目功能介绍1. **文件操作**2. **文本编辑功能**3. **撤销与重做**4. **剪切、复制与粘贴**5. **文本查找与替换**6. **打印功能**7. **打印预览**8. **设置字体颜色**9. **设置字号**10. **设置字体**11. **左对齐**12. **右对齐**13. **居中对齐**14. **两侧对…...

解决国内服务器 npm install 卡住的问题

在使用国内云服务器时&#xff0c;经常会遇到 npm install 命令执行卡住的情况。本文将分享一个典型案例以及常见的解决方案。 问题描述 在执行以下命令时&#xff1a; mkdir test-npm cd test-npm npm init -y npm install lodash --verbose安装过程会卡在这个状态&#xf…...

DeepSeek 的含金量还在上升

大家好啊&#xff0c;我是董董灿。 最近 DeepSeek 越来越火了。 网上有很多针对 DeepSeek 的推理测评&#xff0c;除此之外&#xff0c;也有很多人从技术的角度来探讨 DeepSeek 带给行业的影响。 比如今天就看到了一篇文章&#xff0c;探讨 DeepSeek 在使用 GPU 进行模型训练…...

使用 Docker(Podman) 部署 MongoDB 数据库及使用详解

在现代开发环境中&#xff0c;容器化技术&#xff08;如 Docker 和 Podman&#xff09;已成为部署和管理应用程序的标准方式。本文将详细介绍如何使用 Podman/Docker 部署 MongoDB 数据库&#xff0c;并确保其他应用程序容器能够通过 Docker 网络成功连接到 MongoDB。我们将逐步…...

大模型训练(6):张量并行

0 英文缩写 Pipeline Parallelism&#xff08;PP&#xff09;流水线并行Tensor Parallel&#xff08;TP&#xff09;张量并行Data Parallelism&#xff08;DP&#xff09;数据并行Distributed Data Parallelism&#xff08;DDP&#xff09;分布式数据并行Zero Redundancy Opti…...

【力扣】238.除自身以外数组的乘积

AC截图 题目 思路 前缀积 前缀积指的是对于一个给定的数组arr&#xff0c;构建一个新的数组prefixProduct&#xff0c;其中prefixProduct[i]表示原数组从第一个元素到第i个元素&#xff08;包括i&#xff09;的所有元素的乘积。形式化来说&#xff1a; prefixProduct[0] ar…...

Nacos 的介绍和使用

1. Nacos 的介绍和安装 与 Eureka 一样&#xff0c;Nacos 也提供服务注册和服务发现的功能&#xff0c;Nacos 还支持更多元数据的管理&#xff0c; 同时具备配置管理功能&#xff0c;功能更丰富。 1.1. windows 下的安装和启动方式 下载地址&#xff1a;Release 2.2.3 (May …...

DeepSeek最新图像模型Janus-Pro论文阅读

目录 论文总结 摘要 1. 引言 2. 方法 2.1 架构 2.2 优化的训练策略 2.4 模型扩展 3. 实验 3.1 实施细节 3.2 评估设置 3.3 与最新技术的比较 3.4 定性结果 4. 结论 论文总结 Janus-Pro是DeepSeek最新开源的图像理解生成模型&#xff0c;Janus-Pro在多模态理解和文…...

【仿12306项目】基于SpringCloud,使用Sentinal对抢票业务进行限流

文章目录 一. 常见的限流算法1. 静态窗口限流2. 动态窗口限流3. 漏桶限流4. 令牌桶限流5. 令牌大闸 二. Sentinal简介三. 代码演示0. 限流场景1. 引入依赖2. 定义资源3. 定义规则4. 启动测试 四. 使用Sentinel控台监控流量1. Sentinel控台1.8.6版本下载地址2. 文档说明&#xf…...

【赵渝强老师】Spark RDD的依赖关系和任务阶段

Spark RDD彼此之间会存在一定的依赖关系。依赖关系有两种不同的类型&#xff1a;窄依赖和宽依赖。 窄依赖&#xff1a;如果父RDD的每一个分区最多只被一个子RDD的分区使用&#xff0c;这样的依赖关系就是窄依赖&#xff1b;宽依赖&#xff1a;如果父RDD的每一个分区被多个子RD…...

【B站保姆级视频教程:Jetson配置YOLOv11环境(六)PyTorchTorchvision安装】

Jetson配置YOLOv11环境&#xff08;6&#xff09;PyTorch&Torchvision安装 文章目录 1. 安装PyTorch1.1安装依赖项1.2 下载torch wheel 安装包1.3 安装 2. 安装torchvisiion2.1 安装依赖2.2 编译安装torchvision2.2.1 Torchvisiion版本选择2.2.2 下载torchvisiion到Downloa…...

Verilog语言学习总结

Verilog语言学习&#xff01; 目录 文章目录 前言 一、Verilog语言是什么&#xff1f; 1.1 Verilog简介 1.2 Verilog 和 C 的区别 1.3 Verilog 学习 二、Verilog基础知识 2.1 Verilog 的逻辑值 2.2 数字进制 2.3 Verilog标识符 2.4 Verilog 的数据类型 2.4.1 寄存器类型 2.4.2 …...

【阅读笔记】LED显示屏非均匀度校正

一、背景 发光二极管&#xff08;LED&#xff09;显示屏具有色彩鲜艳、图像清晰、亮度高、驱动电压低、功耗小、耐震动、价格低廉和使用寿命长等优势。LED显示图像的非均匀度是衡量LED显示屏显示质量的指标&#xff0c;非均匀度过高&#xff0c;会导致LED显示图像出现明暗不均…...

【Java异步编程】CompletableFuture基础(1):创建不同线程的子任务、子任务链式调用与异常处理

文章目录 1. 三种实现接口2. 链式调用&#xff1a;保证链的顺序性与异步性3. CompletableFuture创建CompletionStage子任务4. 处理异常a. 创建回调钩子b. 调用handle()方法统一处理异常和结果 5. 如何选择线程池&#xff1a;不同的业务选择不同的线程池 CompletableFuture是JDK…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...