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

SpringCloud Alibaba Demo(Nacos,OpenFeign,Gatway,Sentinel)

开源地址:

ma/springcloud-alibaba-demo

简介

参考:https://www.cnblogs.com/zys2019/p/12682628.html

SpringBoot、SpringCloud 、SpringCloud Alibaba 以及各种组件存在版本对应关系。可参考下面

版本对应

项目前期准备

启动nacos.   ./startup.cmd -m standalone 

登陆nacos官方 localhost:8848   nacos/nacos

创建父工程spring-cloud-alibaba

pom.xml如下:

<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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.lgc</groupId><artifactId>spring-cloud-alibaba</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><modules><module>cloud-alibaba-consumer80</module><module>cloud-alibaba-provider8081</module><module>cloud-alibaba-provider8082</module><module>cloud-alibaba-sentinel</module><module>cloud-alibaba-config-client</module><module>cloud-alibaba-getway</module></modules><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><spring.boot.version>2.2.2.RELEASE</spring.boot.version><spring.cloud.alibaba.version>2.2.0.RELEASE</spring.cloud.alibaba.version><spring.cloud.version>Hoxton.SR1</spring.cloud.version></properties><!--  依赖管理,父工程锁定版本--><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring.boot.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><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring.cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><!--<fork>true</fork>--><addResources>true</addResources></configuration></plugin></plugins></build>
</project>

Nacos

Nacos集成了Ribbon实现了负载均衡。

创建服务提供者子模块cloud-alibaba-provider8001

pom.xml如下

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.lgc</groupId><artifactId>spring-cloud-alibaba</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>cloud-alibaba-provider8081</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--springcloud alibaba nacos--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency></dependencies></project>

application.yml如下

server:port: 8001
spring:application:name: cloud-alibaba-nacos-providercloud:nacos:server-addr: 127.0.0.1:8848discovery:server-addr: ${spring.cloud.nacos.server-addr}
management:endpoints:web:exposure:include: "*"

 其中management这一段是属于端口暴露

创建启动类

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

Nacos注册服务需要在启动类中加上@EnableDiscoveryClient,意思就是服务注册发现

创建controller接口

@RestController
public class UserController {@Value("${server.port}")private int port;@GetMapping("/user/get")public String get(){return "provider port is :"+port;}
}

这样去取server.port是从application.yml去取。

启动服务提供者,在nacos界面上就能看到服务已经注册进来了。

同理,创建cloud-alibaba-provider8002,端口为8002.启动后发现nacos的集群的实例数为2.

OpenFeign

创建服务调用实例

创建服务消费者子模块cloud-alibaba-consumer80

pom.xml如下

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.lgc</groupId><artifactId>spring-cloud-alibaba</artifactId><version>1.0-SNAPSHOT</version></parent><version>1.0-SNAPSHOT</version><artifactId>cloud-alibaba-consumer80</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--springcloud alibaba nacos--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--feign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency></dependencies></project>

application.yml如下

server:port: 80
spring:application:name: cloud-alibaba-nacos-consumercloud:nacos:server-addr: 127.0.0.1:8848discovery:server-addr: ${spring.cloud.nacos.server-addr}
feign:client:#指定全局default:#连接超时时间connectTimeout: 5000#服务等待时间readTimeout: 5000loggerLevel: full
logging:level:com.lgc.cloudalibabaconsumer80.client: debug

需要把consumer这个服务也放到nacos中,就像把这些服务放到一个大容器中,大容器的服务之间可以相互调用、

创建启动类

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

@EnableFeignClients这个代表当前服务作为OpenFeign客户端。

创建Client接口,用于端口映射,可以调用其他服务中的接口(接口在其他服务中已存在)

@FeignClient(value = "cloud-alibaba-nacos-provider")
public interface UserClient {@GetMapping("/user/get")String get();
}

@FeignClient中 的Value值为目标服务的名字,也就是目标服务的spring.application.name

接口的路由也得对应上目标服务的请求url,也就是说cloud-alibaba-nacos-provider的controller中也有个/user/get的接口才可以。

创建controller

@RestController
@RequestMapping("/consumer")
public class UserController {@Autowiredprivate UserClient userClient;@GetMapping("/get")public String get() {return userClient.get();}
}

启动服务,在nacos中就可以看到

访问localhost:80/consumer/get,看到的是8001和8002在进行轮训负载,因为nacos默认支持负载均衡,原因是他默认引入了ribbon.

为了引入nacos的动态参数,我们新建一个cloud-alibaba-config-client模块,pom.xml如下

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><artifactId>spring-cloud-alibaba</artifactId><groupId>com.lgc</groupId><version>1.0-SNAPSHOT</version></parent><artifactId>cloud-alibaba-config-client</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--springcloud alibaba nacos--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency></dependencies>
</project>

新建bootstrap.yml:系统级别的配置,主要配置配置中心的相关信息,优先加载

spring:cloud:nacos:server-addr: 127.0.0.1:8848discovery:server-addr: ${spring.cloud.nacos.server-addr}config:server-addr: ${spring.cloud.nacos.server-addr}file-extension: yamlgroup: DEFAULT_GROUP#namespace: 5a2f851c-8639-4acb-98f1-d5e76cd46457
management:endpoints:web:exposure:include: '*'

 值得一提的是namespace填的是Id,而不是你新建的命名空间的汉字名称。

application.yml如下

spring:application:name: nacos-config-clientprofiles:
#    active: dev #开发环境
#    active: test 测试环境active: info #info??

注意一下这里的profiles选的是info级别,那么在加载nacos的配置文件的时候是以info为后缀的。

创建启动类

 

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

创建controller接口

@RestController
@RefreshScope //类上加了@RefreshScope注解,用于自动刷新。若不添加,则无法进行自动的配置刷新
public class UserController {@Value("${config.info}")private String info;@GetMapping("/config/get")public String get() {return "The config info is :" + info;}
}

@RefreshScope用于参数的自动刷新,如果你nacos中的配置更改,能够自动同步过来,不需要再重启服务。

nacos中的配置文件命名规则为:${prefix}-${spring.profile.active}.${file-extension}。

prefix :默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
spring.profile.active :即为当前环境对应的 profile。
file-exetension: 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。

假如spring.application.name=nacos-config-client,环境为dev,后缀名是yaml,那么dataID就是nacos-config-client-dev.yaml。这里不存在主/从配置文件的说法,只指定不同环境的配置,公共的配置都放在自己的环境中。另外,dataId后缀必须是yaml或properties。

测试

启动3344,访问http://localhost:3344/config/get,可以看到配置的信息。然后修改配置中的config.info内容,再刷新页面,发现配置信息也更新了。此时就做到了配置实时刷新。

Gatway

新建cloud-alibaba-gatway模块

pom.xml如下

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.lgc</groupId><artifactId>spring-cloud-alibaba</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>cloud-alibaba-getway</artifactId><dependencies><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-gateway</artifactId></dependency></dependencies></project>

application.yml如下

server:port: 7001
spring:application:name: cloud-gateway-servicecloud:nacos:server-addr: localhost:8848discovery:server-addr: ${spring.cloud.nacos.server-addr}#namespace: 5a2f851c-8639-4acb-98f1-d5e76cd46457gateway:routes:- id: provideuri: lb://cloud-alibaba-nacos-providerpredicates:- Path=/user/**- id: consumeruri: lb://cloud-alibaba-nacos-consumerpredicates:- Path=/consumer/**
management:endpoints:web:exposure:include: '*'

 lb:代表loadbalance负载均衡

lb://cloud-alibaba-nacos-provider    目标cloud-alibaba-nacos-provider服务

拦截请求/user/**    拦截/user下的所有请求,指向cloud-alibaba-nacos-provider服务。

创建启动类

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

Sentinel

下载地址Releases · alibaba/Sentinel · GitHub,选择对应的版本下载即可。这里以1.8.2版本为例

可以下载压缩包,也可以直接下载jar。本章节在Windows中说明,就直接下载jar进行说明。

下载到本地执行

java -jar sentinel-dashboard-1.7.2.jar

在浏览器访问http://localhost:8080   sentinel/sentinel

登录后看到仪表盘是空的,因为现在没有监控任何的服务。

创建cloud-alibaba-sentinel模块

pom.xml如下

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><artifactId>spring-cloud-alibaba</artifactId><groupId>com.lgc</groupId><version>1.0-SNAPSHOT</version></parent><artifactId>cloud-alibaba-sentinel</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--springcloud alibaba nacos--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--springcloud alibaba sentinel--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!--springcloud alibaba sentinel-datasource-nacos--><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId></dependency></dependencies></project>

application.yml如下

server:port: 8401
spring:application:name: cloud-alibaba-sentinel-servicecloud:nacos:server-addr: 127.0.0.1:8848discovery:server-addr: ${spring.cloud.nacos.server-addr}sentinel:transport:# sentinel dashboard的地址dashboard: 127.0.0.1:8080# sentinel dashboard内部通信端口,默认为8719,如果被占用会自动+1,直到找到为止port: 8719management:endpoints:web:exposure:include: "*"

创建启动类

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

创建controller

 

package com.zys.cloud.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class FlowLimitController {@GetMapping("/testA")public String testA(){return "--------testA";}@GetMapping("/testB")public String testB(){return "--------testB";}}

测试。先启动nacos服务,再启动sentinel服务,再启动8401。访问http://localhost:8401/testA后会在仪表盘看到生成了一个服务:

主要讲解:流控,熔断,热点,授权

其中QBS表示1秒的请求数,QPS表示1秒的拒绝请求数。

流控

流量控制(flow control),其原理是监控应用流量的QPS或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。

QPS表示每秒的请求数。可在簇点链路中选择链路的点击流控按钮添加,也可在流控规则中添加。其他的功能类似。这里以/testA的流控为例:

上图的配置,也就是说对于请求/testA,当每秒请求的次数超过阈值,那么会直接返回失败的信息。保存后显示列表如下:

访问localhost:8401/testA结果是正常的,若快速的刷新几次,会发现返回了流控的信息:

对于针对来源,默认使用default,那么也可以指定来源,那么当指定的这个来源调用/testA请求时会进行流控,其他服务调用/testA时不进行流控,也就是对来源进行针对性的流控。

也可设置并发线程的阈值,当某一时刻并发线程数量超过时会进行流控。

使用Jmeter对/testA发送超过阈值的并发请求,那么在发送的同时再访问/testA就会出现流控。

 流控模式-关联(言简意赅:两个服务共同参与限制条件原来是:A<C,现在是A+B<C)

1)说明:前面的两种的流程模式都设置为直接,这种模式是默认的,也就是说流量控制规则到达阈值时直接触发流量控制。本小节说明关联模式,均以QPS类型说明,后同。

2)关联:当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联。比如对数据库同一个字段的读操作和写操作存在争抢,读的速度过高会影响写得速度,写的速度过高会影响读的速度。如果放任读写操作争抢资源,则争抢本身带来的开销会降低整体的吞吐量。关联的关系是反向关联。

3)上述代码中的/testA和/testB就是关联关系,它们在同一个controller中,占用相同的资源,编辑配置如下:

使用Jmeter对/testB发送超过阈值的并发请求,那么在发送的同时再访问/testA就会出现流控。原因是两个请求相互争抢资源,进行了流控。

流控模式-链路:

链路模式也就是对某一条链路进行流控。如用户服务会调用订单服务,商品服务也会调用订单服务,就存在两条链路。在某个时刻,对商品服务->订单服务这条链路进行流控,从而保证订单服务的正常使用,最终让用户服务可以正常调用订单服务,虽然限流了商品服务这条链路,但不影响用户服务这条链路。

流控效果-快速失败:

默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException。前面已经使用过多次。

流控效果-Warm Up

预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。它有一个冷加载因子,值是3。曲线图如下

新加/testA的流控规则如下:

当1秒同时有20个请求,预热时间是10秒。那么服务会先处理7个请求(20/3),后面依次处理,当达到20秒时处理完所有的请求。

流控效果-排队等待

让请求以均匀的速度通过。修改/testA的规则

也就是说,当有大量的请求来时,每秒只处理20个请求,其他的请求进行排队等待,依次类推。当后面排队的时间超过5秒时就报错,显示流控信息。

熔断降级

一个服务常常会调用别的模块,如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。而Sentinel在服务出现不稳定情况时,会对其进行限制,请求快速失败,避免影响到其他资源而导致级联错误。当资源被降级后,在接下来的时间窗口内,对该资源的调用都自动熔断。

(1)慢调用比例:当单位统计时长内请求数目大于设置的最小请求数目,并且平均响应时间超过最大RT的请求的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。

经过熔断时长后熔断器会进入探测恢复状态,若接下来的一个请求成功完成则结束熔断,否则会再次被熔断。

说明:在1000ms内请求数超过5个,且平均响应时间超过300ms的请求的比例(超过300ms的请求占总请求的比例)大于0.4,则该资源自动熔断10s。10s后根据下一个请求判断是否再次被熔断。

(2)异常比例:当单位统计时长内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。

经过熔断时长后熔断器会进入探测恢复状态,若接下来的一个请求成功完成则结束熔断,否则会再次被熔断。

说明:在1000ms内请求数超过5个,且异常的请求超过6个,那么该资源将自动熔断20s。20s后根据下一个请求判断是否再次被熔断。

@SentinelResource的使用

前面的所讲的流控或降级,其返回的数据都是 Blocked by Sentinel (flow limiting) ,当然可以自定义。@SentinelResource和@HystrixCommand的作用是类似的,都是来指定流控或降级时返回的信息。

在方法上加@SentinelResource注解,且使用blockHandler(或者blockHandlerClass)指定流控或降级时的自定义提示,而blockHandler函数访问范围需要是public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数(类型是BlockException),且和原方法在同一个类中。使用fallback 指定未流控或降级发生异常时的自定义提示,其方法必须是public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配

下面通过对/testC进行流控和降级来说明:

1)流控配置:

2)降级配置:

修改controller

package com.lgc.cloudalibabasentinel.controller;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class FlowLimitController{@GetMapping("/testA")public String testA(){return "--------testA";}@GetMapping("/testB")public String testB(){return "--------testB";}@GetMapping("/testC")@SentinelResource(value = "aaa",blockHandler = "testCBlockHandler",fallback = "testCFallback")public String testC(Integer id){if (id < 0) {throw new RuntimeException("参数值格式错误");}return "--------testC";}//自定义降级或熔断时的提示信息public String testCBlockHandler(Integer id, BlockException exception){//判断异常的类型if (exception instanceof FlowException){return "你被限流了,请稍后再试";} else if (exception instanceof DegradeException) {return "你被降级了,请稍后再试";}return "当前服务不可用";}//自定义未限流时发生  异常  的提示信息public String testCFallback(Integer id){return "参数不合法";}
}

在@SentinelResource指定了value,其值就是要流控或降级的资源名,必须配置。

当访问/testC?id=8时,快速刷新,会出现流控提示信息。

当问/testC?id=-5时,刷新1此,会出现错误提示信息。

当问/testC?id=-5时,刷新5次以上,会出现降级提示信息。

规则持久化

每次无论重启sentinel服务还是要监控的服务,sentinel页面的配置规则都会消失,这是因为这些规则没有持久化,对应大量的配置规则,持久化也非常重要,可将其配置到nacos中。

这里直接在cloud-alibaba-sentinel模块进行说明:

1)导入依赖:

        <!--springcloud alibaba sentinel-datasource-nacos--><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId></dependency>

2)在yml配置,已存在配置省略:

spring:cloud:# 流控规则持久化到nacosdatasource:dsl:nacos:server-addr: ${spring.cloud.nacos.server-addr}data-id: ${spring.application.name}group-id: DEFAULT_GROUPdata-type: jsonrule-type: flow

3)在nacos中添加配置文件,如下图:

json内容:

[{"resource": "/testA","limitApp": "default","grade": 1,"count": 5,"strategy": 0,"controlBehavior": 0,"clusterMode": false}
]

可看到json中是一个数组,数组中只有一个元素,那么针对/test的请求的配置规则会存下来,不会因为重启而丢失,而其他的请求的配置规则还是丢失。针对这些请求,都按照这种规则配置在数组中即可。

相关文章:

SpringCloud Alibaba Demo(Nacos,OpenFeign,Gatway,Sentinel)

开源地址&#xff1a; ma/springcloud-alibaba-demo 简介 参考&#xff1a;https://www.cnblogs.com/zys2019/p/12682628.html SpringBoot、SpringCloud 、SpringCloud Alibaba 以及各种组件存在版本对应关系。可参考下面 版本对应 项目前期准备 启动nacos. ./startup.c…...

基于nodejs+vue畅听校园点歌系统的设计与实现

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…...

IDEA 设置代码注释模板

功能简介&#xff1a; 每次看别人代码时&#xff0c;面对毫无注释的类&#xff0c;除了头大还是头大&#xff0c; 以下提供了一种代码类注释模板 新建java类的时候&#xff0c;自动增加类注释&#xff0c;养成代码开发好习惯 效果展示&#xff1a; 代码模板&#xff1a; #if (…...

emoji对齐 特殊字符对齐 文本对齐

emoji如何对齐 特殊字符如何对齐 高级文本对齐 问题引出 我们在程序打印输出时&#xff0c;如何我们所输出的字符中包含emoji文本&#xff0c;或者其它特殊的字符文本&#xff0c;则我们的打印对齐效果将出现错位。以下代码复现了这一效果&#xff08;tips&#xff1a; 马老师…...

Selenium Python 中的动作链

Selenium 是一个用于自动化的独立的基于 Web 的工具。 它是任何人都可以使用的开源工具。 与Python语言结合使用该工具进行测试。 操作链是 Selenium 的基本组成部分&#xff0c;提供了一种管理低级交互的方法&#xff0c;例如按键、鼠标移动、鼠标按钮操作以及与上下文菜单的…...

OceanBase:03-集群部署

目录 一、集群规划 二、配置要求 三、部署前配置 1.配置 limits.conf 2.配置 sysctl.conf 3.关闭防火墙 4.关闭 SELinux 5.创建数据目录&#xff0c;修改文件所有者信息 6.设置无密码 SSH 登录 7.安装jdk 四、解压执行安装 五、集群部署 1.OBD命令行部署 2. OBD白…...

PTA: 矩阵的乘法运算

矩阵的乘法运算 题目输入格式输出格式输入样例输出样例 代码 题目 线性代数中的矩阵可以表示为一个row&#xff0a;column的二维数组&#xff0c;当row和column均为1时&#xff0c;退化为一个数&#xff0c;当row为1时&#xff0c;为一个行向量&#xff0c;当column为1时&…...

4K Video Downloader Pro v4.28.0(视频下载器)

4K Video Downloader Pro是一款专业的视频下载软件&#xff0c;支持从YouTube、Vimeo、Facebook、Instagram、TikTok等主流视频网站下载高质量的4K、HD和普通视频。它的操作流程简单&#xff0c;只需复制视频链接并粘贴到软件中即可开始下载。此外&#xff0c;该软件还提供了多…...

java pdf,word,ppt转图片

pom.xml <?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…...

map set

目录 一、关联式容器 二、键值对 三、树形结构的关联式容器 3.1 set 3.1.1 set的介绍 3.1.2 set的使用 3.2 multiset 3.2.1 multiset的介绍 3.2.2 multiset的使用 3.3 map 3.3.1 map的介绍 3.3.2 map的使用 …...

Fourier分析导论——第3章——Fourier级数的收敛性(E.M. Stein R. Shakarchi)

第 3 章 Fourier级数的收敛性(Convergence of Fourier Series) The sine and cosine series, by which one can represent an arbitrary function in a given interval, enjoy among other remarkable properties that of being convergent. This property did not escape…...

解决ruoyi-vue部署到域名子路径静态资源404

参考ruoyi前端手册...

游戏引擎中为什么要用四元数表示旋转而不用欧拉角旋转?

个人观点&#xff0c;仅供参考&#xff0c;如有错误可太刺激了 四元数的简单概念和使用 欧拉角通常用于表示一个物体的旋转状态&#xff0c;而不是表示旋转过程。 欧拉角描述的是物体相对于某个参考坐标系的朝向或旋转状态&#xff0c;通常以不同的轴&#xff08;例如&#x…...

E-Office(泛微OA)前台任意文件读取漏洞复现

简介 泛微E-Office是一款企业级的全流程办公自动化软件&#xff0c;它包括协同办公、文档管理、知识管理、工作流管理等多个模块&#xff0c;涵盖了企业日常工作中的各个环节。在该产品前台登录页存在文件读取漏洞。 officeserver.php文件存在任意文件读取漏洞&#xff0c;通…...

前端小案例 | 喵喵大王立大功 | 一个带便利贴功能的todolist面板

文章目录 &#x1f4da;html&#x1f4da;css&#x1f4da;js&#x1f407;stickynote.js&#x1f407;todolist.js&#x1f407;clock.js &#x1f4da;html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><m…...

算法训练营第十一天 | 20. 有效的括号、 1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

目录&#xff1a; 力扣 20. 有效的括号力扣 1047. 删除字符串中的所有相邻重复项力扣 150. 逆波兰表达式求值 问题一、 20. 有效的括号 题目链接&#xff1a;20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 思路分析&#xff1a; 很多朋友刚开始接触这一类题的时候…...

Python unittest单元测试框架 TestSuite测试套件

TestSuite 测试套件简介 对一个功能的验证往往是需要很多多测试用例&#xff0c;可以把测试用例集合在一起执行&#xff0c;这就产生了测试套件TestSuite 的概念&#xff0c;它是用来组装单个测试用例&#xff0c;规定用例的执行的顺序&#xff0c;而且TestSuite也可以嵌套Tes…...

FSB逮捕为乌克兰网络部队工作的俄罗斯黑客

导语 近日&#xff0c;俄罗斯联邦安全局&#xff08;FSB&#xff09;逮捕了两名涉嫌协助乌克兰网络部队对俄罗斯重要基础设施目标进行网络攻击的个人。这起事件引起了广泛关注&#xff0c;涉及到了网络安全和国际关系等多个领域。本文将为您详细介绍这一事件的背景和最新进展。…...

【PC电脑windows-学习样例tusb_serial_device-ESP32的USB模拟串口程序+VScode建立工程+usb组件添加+-基础样例学习】

【PC电脑windows-学习样例tusb_serial_device-ESP32的USB模拟串口程序-基础样例学习】 1、概述2、实验环境3-1、 物品说明3-2、所遇问题&#xff1a;ESP32 cannot open source file "tinyusb.h"或者“tinyusb.h:No such file or directory ....”3-3、解决问题&#…...

LeetCode75——Day26

文章目录 一、题目二、题解 一、题目 394. Decode String Given an encoded string, return its decoded string. The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated exactly k times. Note that k is guar…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...