专业苏州房产网站建设/北京最新消息今天
原作者:3. SpringCloud - 快速通关
前置知识:
- Java17及以上、Maven
- SpringBoot、SpringMVC、MyBatis
- 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. 注册更多
- 创建
service-product
服务 - 引入
nacos依赖
- 配置
nacos地址信息
-
- 注意:每个微服务端口不一样
- 启动应用,查看是否注册成功
3.2.3.3. 启动集群
以 service-order
为例,启动 movie 的三个服务。
- idea 搜索
services
面板,添加 SpringBoot 项目。
- 复制
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. 小结
- 使用 RestTemplate 可以获取到远程数据
- 必须精确指定地址和端口
- 如果远程宕机将不可用
期望:可以负载均衡调用,不用担心远程宕机
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. 小结
- 负载均衡调用只需要传入
服务名
- 请求发起之前会自动去注册中心确定微服务地址
- 如果微服务宕机,会自动剔除在线名单,请求将不会发过去
3.2.7. 深入探索
经典面试题:
如果注册中心宕机,远程调用是否可以成功?
- 从未调用过,如果宕机,调用会立即失败
- 调用过,如果宕机,因为会缓存名单,调用会成功
- 调用过,如果注册中心和对方服务宕机,因为会缓存名单,调用会阻塞后失败(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 - 兜底返回
- 引入 sentinel
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>
- 开启熔断
feign:sentinel:enabled: true
- 编写 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-gateway
、spring-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
- 下载:Seata Java Download | Apache Seata
📎apache-seata-2.1.0-incubating-bin.tar.gz
- 解压并启动:
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快速入门
原作者:3. SpringCloud - 快速通关 前置知识: Java17及以上、MavenSpringBoot、SpringMVC、MyBatisLinux、Docker 1. 分布式基础 1.1. 微服务 微服务架构风格,就像是把一个单独的应用程序开发为一套小服务,每个小服务运行在自…...

从 HTTP/1.1 到 HTTP/3:如何影响网页加载速度与性能
一、前言 在最近使用Apipost时,突然注意到了http/1.1和http/2,如下图: 在我根深蒂固的记忆中,对于http的理解还停留在TCP协议、三次握手。由于我的好奇心,于是触发了我被动“开卷”,所以有了这篇文章&…...

人工智能导论-第3章-知识点与学习笔记
参考教材3.2节的内容,介绍什么是自然演绎推理;解释“肯定后件”与“否定前件”两类错误的演绎推理是什么意义,给出具体例子加以阐述。参考教材3.3节的内容,介绍什么是文字(literal);介绍什么是子…...

游戏引擎 Unity - Unity 下载与安装
Unity Unity 首次发布于 2005 年,属于 Unity Technologies Unity 使用的开发技术有:C# Unity 的适用平台:PC、主机、移动设备、VR / AR、Web 等 Unity 的适用领域:开发中等画质中小型项目 Unity 适合初学者或需要快速上手的开…...

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

4 前置技术(下):git使用
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 前言...

从零开始:用Qt开发一个功能强大的文本编辑器——WPS项目全解析
文章目录 引言项目功能介绍1. **文件操作**2. **文本编辑功能**3. **撤销与重做**4. **剪切、复制与粘贴**5. **文本查找与替换**6. **打印功能**7. **打印预览**8. **设置字体颜色**9. **设置字号**10. **设置字体**11. **左对齐**12. **右对齐**13. **居中对齐**14. **两侧对…...

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

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

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

大模型训练(6):张量并行
0 英文缩写 Pipeline Parallelism(PP)流水线并行Tensor Parallel(TP)张量并行Data Parallelism(DP)数据并行Distributed Data Parallelism(DDP)分布式数据并行Zero Redundancy Opti…...

【力扣】238.除自身以外数组的乘积
AC截图 题目 思路 前缀积 前缀积指的是对于一个给定的数组arr,构建一个新的数组prefixProduct,其中prefixProduct[i]表示原数组从第一个元素到第i个元素(包括i)的所有元素的乘积。形式化来说: prefixProduct[0] ar…...

Nacos 的介绍和使用
1. Nacos 的介绍和安装 与 Eureka 一样,Nacos 也提供服务注册和服务发现的功能,Nacos 还支持更多元数据的管理, 同时具备配置管理功能,功能更丰富。 1.1. windows 下的安装和启动方式 下载地址: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最新开源的图像理解生成模型,Janus-Pro在多模态理解和文…...

【仿12306项目】基于SpringCloud,使用Sentinal对抢票业务进行限流
文章目录 一. 常见的限流算法1. 静态窗口限流2. 动态窗口限流3. 漏桶限流4. 令牌桶限流5. 令牌大闸 二. Sentinal简介三. 代码演示0. 限流场景1. 引入依赖2. 定义资源3. 定义规则4. 启动测试 四. 使用Sentinel控台监控流量1. Sentinel控台1.8.6版本下载地址2. 文档说明…...

【赵渝强老师】Spark RDD的依赖关系和任务阶段
Spark RDD彼此之间会存在一定的依赖关系。依赖关系有两种不同的类型:窄依赖和宽依赖。 窄依赖:如果父RDD的每一个分区最多只被一个子RDD的分区使用,这样的依赖关系就是窄依赖;宽依赖:如果父RDD的每一个分区被多个子RD…...

【B站保姆级视频教程:Jetson配置YOLOv11环境(六)PyTorchTorchvision安装】
Jetson配置YOLOv11环境(6)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语言学习! 目录 文章目录 前言 一、Verilog语言是什么? 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显示屏非均匀度校正
一、背景 发光二极管(LED)显示屏具有色彩鲜艳、图像清晰、亮度高、驱动电压低、功耗小、耐震动、价格低廉和使用寿命长等优势。LED显示图像的非均匀度是衡量LED显示屏显示质量的指标,非均匀度过高,会导致LED显示图像出现明暗不均…...

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

ESXI虚拟机中部署docker会降低服务器性能
在 8 核 16GB 的 ESXi 虚拟机中部署 Docker 的性能影响分析 在 ESXi 虚拟机中运行 Docker 容器时,性能影响主要来自以下几个方面: 虚拟化开销:ESXi 虚拟化层和 Docker 容器化层的叠加。资源竞争:虚拟机与容器之间对 CPU、内存、…...

ASP.NET Core与配置系统的集成
目录 配置系统 默认添加的配置提供者 加载命令行中的配置。 运行环境 读取方法 User Secrets 注意事项 Zack.AnyDBConfigProvider 案例 配置系统 默认添加的配置提供者 加载现有的IConfiguration。加载项目根目录下的appsettings.json。加载项目根目录下的appsettin…...

中间件的概念及基本使用
什么是中间件 中间件是ASP.NET Core的核心组件,MVC框架、响应缓存、身份验证、CORS、Swagger等都是内置中间件。 广义上来讲:Tomcat、WebLogic、Redis、IIS;狭义上来讲,ASP.NET Core中的中间件指ASP.NET Core中的一个组件。中间件…...

SpringBoot 整合 Mybatis:注解版
第一章:注解版 导入配置: <groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.1</version> </dependency> 步骤: 配置数据源见 Druid…...

18.[前端开发]Day18-王者荣耀项目实战(一)
01-06 项目实战 1 代码规范 2 CSS编写顺序 3 组件化开发思想 组件化开发思路 项目整体思路 – 各个击破 07_(掌握)王者荣耀-top-整体布局完成 完整代码 01_page_top1.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8…...

Kafka 使用说明(kafka官方文档中文)
文章来源:kafka -- 南京筱麦软件有限公司 第 1 步:获取 KAFKA 下载最新的 Kafka 版本并提取它: $ tar -xzf kafka_{{scalaVersion}}-{{fullDotVersion}}.tgz $ cd kafka_{{scalaVersion}}-{{fullDotVersion}} 第 2 步:启动 KAFKA 环境 注意:您的本地环境必须安装 Java 8+。…...

基于多智能体强化学习的医疗AI中RAG系统程序架构优化研究
一、引言 1.1 研究背景与意义 在数智化医疗飞速发展的当下,医疗人工智能(AI)已成为提升医疗服务质量、优化医疗流程以及推动医学研究进步的关键力量。医疗 AI 借助机器学习、深度学习等先进技术,能够处理和分析海量的医疗数据,从而辅助医生进行疾病诊断、制定治疗方案以…...

Airflow:深入理解Apache Airflow Task
Apache Airflow是一个开源工作流管理平台,支持以编程方式编写、调度和监控工作流。由于其灵活性、可扩展性和强大的社区支持,它已迅速成为编排复杂数据管道的首选工具。在这篇博文中,我们将深入研究Apache Airflow 中的任务概念,探…...

multisim入门学习设计电路
文章目录 1.软件的安装2.电路基本设计2.1二极管的简介2.2最终的设计效果2.3设计流程介绍 3.如何测试电路 1.软件的安装 我是参考的下面的这个文章,文章的链接放在下面,亲测是有效的,如果是小白的话,可以参考一下: 【…...

【算法精练】二分查找算法总结
目录 前言 1. 二分查找(基础版) 2. 寻找左右端点 循环判断条件 求中间点 总结 前言 说起二分查找,也是一种十分常见的算法,最常听说的就是:二分查找只能在数组有序的场景下使用;其实也未必,…...