Spring Cloud —— Gateway 服务网关

导航

  • 一、什么是服务网关
  • 二、业界常见网关组件
  • 三、Spring Cloud Gateway
  • 四、Gateway 快速入门
    • 4.1 创建 gateway 服务
    • 4.2 添加 gateway 依赖和 nacos 依赖
    • 4.3 配置路由信息
    • 4.4 测试路由转发
  • 五、Gateway 执行流程
  • 六、Gateway 断言
    • 6.1 内置路由断言工厂
    • 6.2 自定义路由断言工厂
  • 七、Gateway 过滤器
    • 7.1 局部过滤器
      • 7.1.1 内置局部过滤器
      • 7.1.2 自定义局部过滤器
    • 7.2 全局过滤器
      • 7.2.1 内置全局过滤器
      • 7.2.2 自定义全局过滤器
  • 八、网关限流
    • 8.1 route纬度的网关限流
    • 8.2 自定义 API 分组的网关限流
    • 8.3 网关流控实现原理
    • 8.4 网关流控控制台
  • 总结

一、什么是服务网关

服务网关也叫 API 网关。

所谓 API 网关,就是指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,如,认证、鉴权、监控、路由转发等等。其本身也是一个可以注册到 Nacos 上的微服务:
在这里插入图片描述

二、业界常见网关组件

  • Nginx + lua脚本
    使用 Nginx 的反向代理和负载均衡可实现对 api 服务器的负载均衡和高可用,lua 是一种脚本语言,可以用来编写简单的逻辑,Nginx 支持 lua 脚本。
  • Kong
    基于 Nginx + lua 开发,性能高、稳定,有多个可用插件(限流、鉴权等),开箱即用。
    但支持 http 协议,二次开发限制较大,缺乏更易用的管控、配置方式。
  • Zuul
    Netflix 开源的网关,功能丰富,使用 Java 开发,易于二次开发。
    但缺乏管控,无法动态配置,依赖组件多,处理 http 请求需要依赖 web 容器,性能不如 Nginx。
  • Spring Cloud Gateway
    Spring 公司为了 替换 Zuul 而开发的网关组件。Spring Cloud 微服务 推荐使用的网关组件。

三、Spring Cloud Gateway

Spring Cloud Gateway 是 Spring 公司基于 Spring 5.0 ,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,旨在为微服务架构提供一种简单、有效、统一的 API 路由管理方式。目标是取代 Netflix Zuul ,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供网关基本功能,例如,安全、监控和限流等。

优点:

  • 性能强劲:是第一代网关 Zuul 的1.6 倍
  • 功能强大:内置了很多实用功能,如转发、监控、限流等
  • 设计优雅,易扩展

缺点

  • 依赖 Netty 和 WebFlux,不是传统的 Servlet 编程模型,学习成本高
  • 不能将其部署在 Tomcat 、Jetty 等 Servlet 容器中,只能打 jar 包执行
  • Spring Boot 2.0 以上才支持

四、Gateway 快速入门

使用 Spring Cloud Gateway 实现最简单的请求路由。

4.1 创建 gateway 服务

首先创建一个全新的 api-gateway 服务。
在这里插入图片描述

4.2 添加 gateway 依赖和 nacos 依赖

注意,gateway 项目一定不要引入 web-starter 依赖,因为 Gateway 本身不是基于 Servlet 实现。

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
</dependency>
@Slf4j
@EnableDiscoveryClient
@SpringBootApplication
public class ApiGatewayApplication {public static void main(String[] args) {SpringApplication.run(ApiGatewayApplication.class);log.info("-------------------启动成功--------------------");}
}

4.3 配置路由信息

先配置一些必须元素,如端口号,网关微服务的服务名称,以及 nacos 注册地址:

server:port: 7000
spring:application:name: shop-api-gatewaynacos:discovery:server-addr: localhost:8848

然后,再配置路由信息:

spring:cloud:nacos:discovery:server-addr: localhost:8848 # 企业应用中一般也要把网关服务注册到 nacos 上gateway:discovery:locator:enabled: true # 开启网关服务发现定位器,可以令 gateway 从nacos上定位具体的微服务地址routes: # 路由数组(路由就是指当请求满足什么样的条件的时候转发到哪台服务器上)- id: product_route # 当前路由的标识,要求唯一,默认UUID,# uri: http:// localhost:8081  # 请求最终要被转发的地址uri: lb://service-product  # 若使用 nacos 可以写微服务名称,lb->loadbalance调用服务order: 1  # 指的是路由的优先级,数字小优先级高predicates: # 断言,条件判断,返回值 boolean,转发请求要满足的条件- Path=/product-serv/**   # 当请求路径满足 Path 指定的规则时,此路由信息才会正常转发filters: # 过滤器,在请求传递过程中,对请求做一些手脚- StripPrefix=1  # 在请求转发之前去掉一层路径,

对于 routes 配置,如果想简单配置,可直接忽略,因为 Spring Cloud Gateway 提供了默认的路由规则,用户可以直接在网关ip:port 地址和具体请求路径之间加入微服务名称就可以实现路由转发,例如:

http://localhost:7000/service-product/product/1

但是企业级应用中,往往会处于灵活的考虑,配置 routes 选项。

4.4 测试路由转发

启动 shop-api-gateway 和 shop-product 微服务,测试路由功能

网关服务启动在 7000 端口上,服务也成功注册到 Nacos 上:
在这里插入图片描述
在这里插入图片描述
请求网关服务,获取商品信息:
在这里插入图片描述
在这里插入图片描述
可以看到,网关服务从 Nacos 上获取商品微服务的 ip 信息成功,并且路由成功转发,并返回了商品信息。

五、Gateway 执行流程

路由(route)是 gateway 中最基本的组件之一,表示一个具体的路由信息载体。主要定义下面几个信息:

  • id ,路由标识,区别其他 route
  • uri , 路由指向的目的 uri,即客户端请求最终转发到的微服务
  • order,用于多个 route 之间的排序,数值越小匹配的优先级越高
  • predicate, 断言的作用是进行条件判断,只有断言都返回 true ,才能真正的执行路由
  • filter,过滤器用于修改请求和响应信息

路由的执行流程

  1. 客户端向 Gateway Server 发起请求
  2. 请求首先被 HttpWebHandlerAdapter 进行提取,组装成网关上下文
  3. 然后网关的上下文会传递到 DispatcherHandler,它负责将请求分发给 RoutePredicateHandlerMapping
  4. RoutePredicateHandlerMapping 负责路由查找,并根据路由断言判断路由是否可用
  5. 若断言成功,由FilteringWebHandler 创建过滤器链并调用
  6. 请求会依次经过 PreFilter --> 微服务–> PostFilter 的方法,最终响应回客户端

在这里插入图片描述

六、Gateway 断言

Predicate 断言,用于进行条件判断,只有断言都返回真,才会真正的执行路由。
简单的说,断言就是用来判断在什么条件下才能进行路由转发

6.1 内置路由断言工厂

1、 基于 Datetime 类型的断言工厂
此类型断言根据时间做判断,主要有三个:
AfterRoutePredicateFactory:接收一个日期参数,判断请求日期是否晚于指定日期
BeforeRoutePredicateFactory:接收一个日期参数,判断请求日期是否早于指定日期
BetweenRoutePredicateFactory:接收两个日期参数,判断请求日期是否在指定日期之间

-After=2019-12-31T23:59:59.789+08:00[Asia/Shanghai]

2、基于远程地址的断言工厂
RemoteAddrRoutePredicateFactory: 接收一个IP 地址,判断请求主机地址是否在地址段中

-RemoteAddr=192.168.1.1/24

3、基于 Cookie 的断言工厂
CookieRoutePredicateFactory:接收两个参数,cookie 名字和一个正则表达式,判断请求 cookie 是否具有给定名称且值与正则表达式匹配

-Cookie=chocolate, ch.

4、基于 Header 的断言工厂
HeaderRoutePredicateFactory :接收两个参数,标题名称和正则表达式。判断请求 header 中是否具有给定名称且值与正则表达式匹配。

-Header=X-Request-Id,\d+

5、基于权重的断言工厂
WeightRoutePredicateFactory:接收一个[组名, 权重],然后对于同一个组内的路由按照权重转发,例如下面的例子中,有两个路由规则 weight_route1和weight_route2,根据 Weight 的配置信息,两个路由位于 同一group3中,根据权重,按照 1:9 的比例转发请求。

routes:
-id:weight_route1
uri:host1
predicates:
-Path=/product/**
-Weight=group3,1
-id:weight_route2
uri:host2
predicates:
-Path=/product/**
-Weight=group3,9

6、其他类型的断言工厂
篇幅有限,以下是 Gateway 内置的全部断言工厂,它们都继承自 AbstractRoutePredicateFactory,从命名就可以大体猜出它们的使用场景:

HeaderRoutePredicateFactory
PathRoutePredicateFactory
BeforeRoutePredicateFactory
CloudFoundryRouteServiceRoutePredicateFactory
QueryRoutePredicateFactory
RemoteAddrRoutePredicateFactory
MethodRoutePredicateFactory
CookieRoutePredicateFactory
WeightRoutePredicateFactory
AfterRoutePredicateFactory
BetweenRoutePredicateFactory
HostRoutePredicateFactory
ReadBodyPredicateFactory

6.2 自定义路由断言工厂

自定义一个路由断言,要求实现只允许年龄在 18 ~ 60 的请求访问。

1、声明一个断言
在这里插入图片描述
2、自定义断言工厂
创建一个专用的 predicates 包,用于存放各种断言工厂类,然后创建 AgeRoutePredicateFactory:
在这里插入图片描述

@Component
public class AgeRoutePredicateFactory extends AbstractRoutePredicateFactory<AgeRoutePredicateFactory.Config> {public AgeRoutePredicateFactory() {super(AgeRoutePredicateFactory.Config.class);}public List<String> shortcutFieldOrder() {return Arrays.asList("minAge", "maxAge");}public Predicate<ServerWebExchange> apply(AgeRoutePredicateFactory.Config config) {return new Predicate<ServerWebExchange>() {@Overridepublic boolean test(ServerWebExchange serverWebExchange) {String ageStr = serverWebExchange.getRequest().getQueryParams().getFirst("age");if (!StringUtils.isEmpty(ageStr)) {Integer age = Integer.valueOf(ageStr);return age >= config.getMinAge() && age <= config.getMaxAge();}return false;}};}@Data@NoArgsConstructorpublic static class Config {private int minAge;private int maxAge;}
}

代码逻辑基本可以参考已有的 AbstractRoutePredicateFactory 的内置实现类,apply 方法是主要返回一个函数接口 Predicate,可以使用Lambda表达式, ServerWebExchange 是一个可以从中取出 请求Request 的对象,剩下的,就是进行 Request 中的各种判断逻辑了,上述代码示例中只是简单的从请求中取出 age 属性,判断年龄区间是否符合配置条件。

3、测试
启动 nacos,将 gateway 和 product 微服务都注册上去,然后分别尝试请求 不同的 age 属性:
在这里插入图片描述
在这里插入图片描述
只要在 18 ~ 60 之间的 age 属性,都可以请求成功,反之则路由拦截,说明我们的 断言生效了。

七、Gateway 过滤器

过滤器的作用,就是在请求的传递过程中,对请求和响应对象做一些手脚。
在 Gateway 中,过滤器的生命周期只有两个:pre 和 post。

  • pre:这种过滤器在请求被真正转发之前调用,可以利用这种过滤器实现身份验证、在集群中选择请求的微服务(负载均衡)、记录调试信息等。

  • post:这种过滤器在gateway 收到微服务的响应之后执行,这种过滤器可用来为响应添加标准的 http header、收集统计信息和指标、将响应从微服务发送到客户端等。
    在这里插入图片描述
    Gateway 的 Filter 从作用范围可分为 GatewayFilter 和 GlobalFilter。

  • GatewayFilter :应用到单个路由或一个分组的路由上

  • GlobalFilter:应用到所有路由上

7.1 局部过滤器

7.1.1 内置局部过滤器

过滤器的用法和断言类似,所有的内置过滤器名称都遵循 :配置 + GatewayFilterFactory ,这样的格式。

内置局部过滤器有很多,都继承自 AbstractGatewayFilterFactory,以 SetStatusGatewayFilterFactory 为例,演示一下 SetStatus 过滤器的用法。

使用 SetStatus 可以修改响应码:

spring:cloud:gateway:routes:- id:uri: ## 其他属性...filters: # 过滤器,在请求传递过程中,对请求做一些手脚- SetStatus=222 # 将响应码改为 222

在这里插入图片描述

7.1.2 自定义局部过滤器

1、添加一个日志级别过滤器
该过滤器并没有什么实质的意义,只是用于演示过滤器的自定义逻辑:

spring:cloud:gateway:routes:- id:uri: ## 其他属性...filters: # 过滤器,在请求传递过程中,对请求做一些手脚- Log=true,false # Log=consoleLog,cacheLog 开启consoleLog,不开启cacheLog

2、编写过滤器工厂类

@Component
public class LogGatewayFilterFactory extends AbstractGatewayFilterFactory<LogGatewayFilterFactory.Config> {public LogGatewayFilterFactory() {super(LogGatewayFilterFactory.Config.class);}public List<String> shortcutFieldOrder() {return Arrays.asList("consoleLog", "cacheLog");}public GatewayFilter apply(LogGatewayFilterFactory.Config config) {return new GatewayFilter() {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {if (config.isConsoleLog()) {System.out.println("consoleLog 开启了");} else if (config.isCacheLog()) {System.out.println("cacheLog 开启了");}// 将过滤器链传递下去return chain.filter(exchange);}};}@Data@NoArgsConstructorpublic static class Config {private boolean consoleLog;private boolean cacheLog;}
}

3、测试
请求网关路由接口,后台观察日志:
在这里插入图片描述
在这里插入图片描述

7.2 全局过滤器

全局过滤器作用于所有路由,无需配置。通过全局过滤器可以实现对权限的统一校验,安全性验证等功能。

7.2.1 内置全局过滤器

在这里插入图片描述

7.2.2 自定义全局过滤器

自定义全局鉴权过滤器。
在这里插入图片描述
如上图所示,当客户端第一次访问的时候,网关服务会先去授权中心请求登录授权,并颁发token凭证,然后客户端每次访问微服务的时候,就携带 token 进行请求。那么在网关中,我们就可以自定义一个全局的鉴权过滤器,来完成第一次请求的鉴权工作。

这里简单实现鉴权的逻辑,颁发凭证等更细节的内容不做展开。

1、自定义全局过滤器类

@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String token = exchange.getRequest().getQueryParams().getFirst("token");if (!StringUtils.equals("admin", token)) {System.out.println("鉴权失败!");exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}// 调用 chain.filter 继续向下执行return chain.filter(exchange);}@Overridepublic int getOrder() {return 0;}
}

2、测试鉴权过滤
全局过滤器无需配置,自动生效,我们写好 AuthGlobalFilter 之后,将其注册到 Spring 容器中即可。打开浏览器访问路由接口,发现,返回结果为 401:
在这里插入图片描述
若添加 token=admin,则可以访问成功:
在这里插入图片描述

八、网关限流

官方文档:网关限流

网关是所有请求的公共入口,所以可以在网关进行限流,本节采用 Sentinel 组件来实现网关限流。Sentinel 支持对 Spring Cloud Gateway、Zuul 等主流网关进行限流。

在这里插入图片描述
从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源纬度的限流:

  1. route 纬度:即在Spring 配置文件中配置路由条目,资源名为对应的 routeId
  2. 自定义API纬度:用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组

8.1 route纬度的网关限流

1、在服务网关模块加入 sentinel 的网关适配依赖

 <dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-spring-cloud-gateway-adapter</artifactId></dependency>

2、编写配置类
基于 Sentinel 的 Gateway 限流是通过其提供的 Filter 来完成的,使用时只需要注入对应的 SentinelGatewayFilter 实例以及 SentinelGatewayBlockExceptionHandler 实例即可。

@Configuration
public class GatewayConfiguration {private final List<ViewResolver> viewResolvers;private final ServerCodecConfigurer serverCodecConfigurer;public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider,ServerCodecConfigurer serverCodecConfigurer) {this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);this.serverCodecConfigurer = serverCodecConfigurer;}@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {// Register the block exception handler for Spring Cloud Gateway.return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);}@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public GlobalFilter sentinelGatewayFilter() {return new SentinelGatewayFilter();}
}

8.2 自定义 API 分组的网关限流

官方参考文档:网关限流

8.3 网关流控实现原理

当通过 GatewayRuleManager 加载网关流控规则(GatewayFlowRule)时,无论是否针对请求属性进行限流,Sentinel 底层都会将网关流控规则转化为热点参数规则(ParamFlowRule),存储在 GatewayRuleManager 中,与正常的热点参数规则相隔离。转换时 Sentinel 会根据请求属性配置,为网关流控规则设置参数索引(idx),并同步到生成的热点参数规则中。

外部请求进入 API Gateway 时会经过 Sentinel 实现的 filter,其中会依次进行 路由/API 分组匹配、请求属性解析和参数组装。Sentinel 会根据配置的网关流控规则来解析请求属性,并依照参数索引顺序组装参数数组,最终传入 SphU.entry(res, args) 中。Sentinel API Gateway Adapter Common 模块向 Slot Chain 中添加了一个 GatewayFlowSlot,专门用来做网关规则的检查。GatewayFlowSlot 会从 GatewayRuleManager 中提取生成的热点参数规则,根据传入的参数依次进行规则检查。若某条规则不针对请求属性,则会在参数最后一个位置置入预设的常量,达到普通流控的效果。
在这里插入图片描述

8.4 网关流控控制台

Sentinel 1.6.3 引入了网关流控控制台的支持,用户可以直接在 Sentinel 控制台上查看 API Gateway 实时的 route 和自定义 API 分组监控,管理网关规则和 API 分组配置。

在 API Gateway 端,用户只需要在原有启动参数的基础上添加如下启动参数即可标记应用为 API Gateway 类型:

# 注:通过 Spring Cloud Alibaba Sentinel 自动接入的 API Gateway 整合则无需此参数
-Dcsp.sentinel.app.type=1

添加正确的启动参数并有访问量后,我们就可以在 Sentinel 上面看到对应的 API Gateway 了。我们可以查看实时的 route 和自定义 API 分组的监控和调用信息,并针对其配置规则:
在这里插入图片描述

总结

api 服务网关提供统一的服务入口,通过路由、断言、过滤器,可以实现诸如负载均衡、路由判定、网关限流、鉴权等功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558622.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图形显卡_选核芯显卡还是独立显卡?这才是决定笔记本电脑性能的关键

买笔记本电脑的时候&#xff0c;选核芯显卡还是独立显卡是很多朋友纠结的问题。核芯显卡是建立在和处理器同一内核芯片上的图形处理单元&#xff0c;而独立显卡拥有单独的图形核心和独立的显存。那么具体哪个更好呢&#xff1f;这里就来介绍一下。两者各自的特点核芯显卡和传统…

Spring Cloud —— 链路追踪技术

导航一、什么是链路追踪二、Spring Cloud Sleuth2.1 相关概念三、Sleuth 入门案例四、Zipkin 的集成4.1 Zipkin 介绍4.2 Zipkin 服务端安装4.3 Zipkin 客户端安装五、Zipkin 数据持久化5.1 MySQL 数据持久化5.2 Elasticsearch 数据持久化一、什么是链路追踪 在大型系统的微服务…

使用vim的重不重要_VIM高级操作,经常用vim的应该多学习。多开发效率很有大帮助!...

Vim是号称“编辑器之神”的文本编辑软件&#xff0c;自从接触Vim以来&#xff0c;基本上都是用Vim来修改和编写代码和配置文件的。但是我一直只会用最基本的命令&#xff0c;虽然把HJKL的定位键已操纵地很熟练。但是Vim其他强大的地方却几乎没有触及过。学一样东西&#xff0c;…

bool类型数组转换成一个整数_「PHP」常用的数组键值操作函数,面试重点

数组键值操作函数1、array_values ( array $array ) : array返回数组中所有的值的数组$a[name>jikeshiguangji,age>26];print_r(array_values($a));运行结果&#xff1a;$aarray("name">"jikeshiguangji","age">"26");pri…

Spring Cloud —— 消息队列与 RocketMQ

导航一、什么是 MQ二、常见的 MQ 产品三、RocketMQ 概念与架构设计3.1 基本概念1、消息模型&#xff08;Message Model&#xff09;2、生产者与消费者&#xff08;Producer & Consumer&#xff09;3、主题&#xff08;Topic&#xff09;4、代理服务器与名称服务&#xff08…

python 读取pdf中的文本

摘要 常常需要针对pdf进行文本分析&#xff0c;以下给出了两种方法用来读取pdf中的文字 方法一 pypdf2 pip install pypdf2 import PyPDF2 filename xxx.pdfwith open(filename, rb) as file:# 创建一个PDF阅读器对象reader PyPDF2.PdfReader(file)# 遍历PDF中的每一页for…

惠普打印机只打印一半_惠普打印机如何安装 惠普打印机加墨方法【介绍】

对于多数上班族和学生党来说&#xff0c;平时办公和学习不仅仅离不开 电脑 &#xff0c;与此同时还需要 打印机 起到辅助作用。目前市场上的打印机品牌较多&#xff0c;惠普就是其中知名度较高的一个牌子&#xff0c;拥有大批的消费群体。但是有些人在将打印机买回来之后&#…

Spring Cloud —— RocketMQ 的消息类型

导航引言一、普通消息1.1 可靠同步发送1.2 可靠异步发送1.3 单向发送二、顺序消息三、事务消息3.1 什么是事务消息3.2 事务消息示例1、编写本地事务逻辑2、发送半事务消息3、注册本地事务监听器4、测试引言 本文承接《Spring Cloud —— 消息队列与 RocketMQ》 RocketMQ 提供…

城市运行一网统管_全国率先!“一屏观天下、一网管全城”,临港城市运行“一网统管”平台启动建设...

景区里是否出现了大客流&#xff1f;渣土车是否有违规&#xff1f;工地上有没有安全隐患&#xff1f;……8月12日&#xff0c;临港新片区城市运行“一网统管”平台正式启动建设&#xff0c;临港新片区城市运行“一网统管”中长期规划也正式发布&#xff0c;通过构建具有临港新片…

Spring Cloud Alibaba —— Nacos Config 配置中心

导航引言一、什么是配置中心二、常见的配置中心组件三、Nacos Config 入门四、Nacos Config 动态配置4.1 硬编码方式&#xff08;默认支持动态生效&#xff09;4.2 属性注入五、配置共享5.1 相同微服务不同环境间共享5.2 不同微服务配置共享六、Nacos Config 的几个概念总结引言…

codesys com库_CODESYS在线库,酷德网镜像站启用

近期由于国内网络问题&#xff0c;造成 stroe.codesys.com 网站无法访问。在线库无法下载。为了不影响广大CODESYS用户的正常使用&#xff0c;酷德网建立stroe.codesys.com的国内镜像站:主站&#xff1a; https://store.hicodesys.com:8421/CODESYSLibs/备用站&#xff1a; …

分布式事务的解决思路与方案

导航一、事务的种类与场景二、分布式事务解决方案2.1 全局事务2.2 可靠消息事务2.3 最大努力通知2.4 TCC 事务三、TCC 模式常见问题3.1 二阶段幂等3.2 空回滚3.3 资源悬挂一、事务的种类与场景 本地事务实际上就是指数据库的事务&#xff0c;参考《MySQL —— 事务与隔离级别总…

css3 下边框缓缓划过_干货来袭!web前端开发工程师必看之如何使用CSS3实现瀑布流效果?...

首先,我们来看一下什么是瀑布流布局效果,比如电商网站 蘑菇街原理图:在一个大盒子里&#xff0c;放置多个小盒子&#xff0c;小盒子的大小可以不一致&#xff0c;长短不一样&#xff0c;呈现一种瀑布流的效果。使用CSS3S实现只需要如下4步:1. 准备图片素材2. 书写相应HTML结构3…

Spring Cloud Alibaba —— Seata 分布式事务框架

导航一、Seata 介绍二、Seata 的工作原理2.1 三个角色2.2 工作流程三、Seata AT 工作机制3.1 一阶段3.2 二阶段四、案例演示&#xff08;待补充&#xff09;一、Seata 介绍 官网&#xff1a;Seata 官网 Seata 是2019 年阿里巴巴中间件团队发起的开源项目&#xff0c;其前身是…

云麦体脂秤华为体脂秤_华为、小米和有品体脂秤哪个品牌好?三款智能体脂秤横评结果排行...

如今生活水平的提高&#xff0c;也让更多人开始关注健康问题。由于大部分时间都忙于工作&#xff0c;本身就运动少、体重超标等等。如果长期得不到控制的话&#xff0c;会造成日后脂性肝炎、肝纤维化、肝癌&#xff0c;想想都可怕&#xff0c;在意识到这样的严重性&#xff0c;…

Guava常用工具类的使用

导航引言一、Lists.partition引言 本文用于记录工作中常用到的 Guava 工具类的使用。 依赖引入&#xff1a; <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>20.0</version></depend…

idea 调用c#接口_Dubbo 接口测试方法

一.直接通telnet然后用dubbo协议调用方法&#xff08;1&#xff09;在项目的配置文件中可以看到dubbo.protocol.port10022说明dubbo对外暴漏的端口为10022&#xff0c;直接用telnet访问此端口。telnet lcoalhost 10022然后就能看到说明连接成功。用ls查看服务查看服务下有那些方…

MySQL 面试问答

导航一、什么是回表查询&#xff1f;如何避免回表查询&#xff1f;二、为什么MySQL建议使用自增主键&#xff1f;什么是代理主键、业务主键&#xff1f;三、为什么MySQL建议单表不超过2000W数据&#xff1f;四、MySQL自增id用完了怎么办&#xff1f;五、MySQL自增主键是连续的吗…

tcs标准编写软件_【公益培训】知你所需 | 标准编写格式及TCS模板应用线上公益培训...

企业标准编写的水平及TCS工具使用的能力是实施企业标准化工作的基础。TCS标准编写软件是辅助标准编写的工具性软件&#xff0c;方便标准编写人员快捷准确的编写标准草案&#xff0c;有效提升标准供给质量。为贯彻落实疫情防控和助力企业复工复产工作&#xff0c;山东标准化协会…

Linux进阶之路——常用命令总结

一、帮助命令 help man type区分内建、外建命令 【扩展】关于内建命令与外建命令。 内建命令属于shell程序的一部分&#xff0c;包含一些比较简单的Linux命令。这些命令被写在/bin/bash 文件的 builtins 里面&#xff0c;由shell程序识别并在shell程序内部完成运行。通常在Li…