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

springCloud/Alibaba常用中间件全集(上)

文章目录

  • SpringCloud:
    • 一、Consul:服务注册与发现
      • 1、下载Consul
      • 2、运行Consul
      • 3、服务注册
        • ①. 导入依赖
        • ②. 配置yml
        • ③. 启动类添加Consul的启动服务发现注解
        • ④. 解决 **硬编码** 问题
        • ⑤. 此时便可以将IP地址改为服务名
      • 4、服务配置与刷新
        • ①. 引入Consul-Config依赖
        • ②. 修改bootstrap.yml配置文件<br>
        • ③. 根据官方提供的规则(```config/服务名,~/data```)创建Consul的Key/Value <br>
        • ④. 将在Consul中配置与服务进行绑定(修改application.yml文件即可)
        • ⑤. 测试
        • ⑥. 动态的获取配置信息
    • 二、LoadBalancer负载均衡服务调用
      • 1、启用LoadBalancer
        • ①在微服务客户端的配置类上添加@LoadBalancer
        • ②切换负载均衡的算法(随机)
    • 三、Openfeign远程服务接口调用
      • 1、基本使用
        • ① 引入依赖
        • ③ 启动OpenFeign
        • ② 在common公共类创建一个OpenFeignApi接口,配置公共Api
        • ③ 测试:
      • 2、进阶配置
        • ①OpenFeign日志打印功能
          • 开启logger
        • ②OpenFeign超时控制
        • ③OpenFeign重试机制
        • ④OpenFeign更改默认HttpClient
        • ⑤OpenFeign请求/响应压缩
    • 四、CircuitBreaker断路器
      • Resilience4j
        • CircuitBreaker(熔断降级)
          • 代码演示
        • Bulkhead(隔离)
          • 代码演示
        • ratelimit(限流)
          • 代码演示


SpringCloud:

微服务的中间件介绍与使用

一、Consul:服务注册与发现

当我们要想做到俩个微服务之间的请求时,会将定义一个变量来存储想要请求的另外一个微服务的 IP地址和端口号
,但是此时的这个变量是定死在这里的,会存在非常多的问题

列如:

  1. 有一个微服务的端口号或IP地址发生改变,则调用它的所有微服务都会受到影响
  2. 如果系统中提供了多个微服务之间的请求时,则无法实现微服务的负载均衡功能。
  3. 系统需要支持更高的并发,需要部署更多的微服务之间的请求时,硬编码 微服务则后续的维护会变得异常复杂。

这时需要引入服务治理功能,实现微服务之间的动态注册与发现。

1、下载Consul

根据自己的系统下载即可

下载链接:https://developer.hashicorp.com/consul/install
在这里插入图片描述

2、运行Consul

  1. 将解压好的Consul文件放到一个没有中文的目录下,防止运行时出现报错
  2. 使用终端打开文件目录并输入 Consul -version(参看是否可以识别到Consul)
    在这里插入图片描述
  1. 输入启动命令:```Consul agent -dev````
    在这里插入图片描述
  1. 访问Consul页面:http://localhost:8500(默认端口8500,实际跟你们的运行时出现的端口号为准)

3、服务注册

①. 导入依赖
<!--consul服务发现与配置管理中间件-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
②. 配置yml
## 配置应用名称
spring:application:name: cloud-payment-service####Spring Cloud Consul for Service Discovery
cloud:consul:host: localhost #输入Consul的IP地址port: 8500 #Consul端口号discovery:service-name: ${spring.application.name} #动态设置服务注册到服务发现组件时的服务名称
③. 启动类添加Consul的启动服务发现注解

@EnableDiscoveryClient
在这里插入图片描述

启动代码之后,可以在Consul图形化界面进行查看是否有绑定
在这里插入图片描述

④. 解决 硬编码 问题

在配置微服务的RestTemplateConfig类中添加注解@LoadBalanced,解决报错 java.net.UnknownHostException:cloud-payment-service
在这里插入图片描述

⑤. 此时便可以将IP地址改为服务名

在这里插入图片描述

4、服务配置与刷新

当拆分过多个微服务时,每一个服务都要进行配置,会特别的麻烦,而Consul就解决了此痛点,

①. 引入Consul-Config依赖
<!--SpringCloud consul config-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
②. 修改bootstrap.yml配置文件

bootstrap与application配置对比:

applicaiton.ymlbootstrap.yml
是用户级的资源配置项是系统级的,优先级更加高
在bootstrap.yml配置文件中添加一个(这里将springCloud的配置都放到了bootstrap.yml中了)
spring:
application:name: cloud-payment-service
####Spring Cloud Consul for Service Discovery
cloud:consul:host: localhostport: 8500discovery:service-name: ${spring.application.name}
######ConsulConfigYml#####config:profile-separator: '-' # default value is ",",we update '-'format: YAML
③. 根据官方提供的规则(config/服务名,~/data)创建Consul的Key/Value

注意:这里因为我们在上面的profile-separator配置中已经将",“改为”-"所以在创建的时候可以直接 config/服务名- ~~ /data`
在这里插入图片描述
在这里插入图片描述

④. 将在Consul中配置与服务进行绑定(修改application.yml文件即可)

spring.profiles.active: dev多环境配置加载内容dev/prod,不写就是默认default配置

注意: 这里的可以不用写服务名直接写服务名后面的即可:
在这里插入图片描述

⑤. 测试

在这里插入图片描述在这里插入图片描述
(这里可以改一下active中的配置多测试几次)

⑥. 动态的获取配置信息

在启动类上加上注解@RefreshScope
在这里插入图片描述

配置bootstrap.yml文件规定刷新时间(不配置默认是55秒)
spring.cloud.consul.config.watch.wait-time:1 单位:秒
这里就不做演示了,大家可以自己试一下修改Consul的配置,输出的信息是否会跟着发生改变(修改完之后要重新请求一次)

参考文档:Spring-cloud-consul

二、LoadBalancer负载均衡服务调用

负载均衡是应对高并发的有效方案之一。
其核心原理是,当存在多个服务端时,如果大量客户端集中请求某一个服务端(如服务端 1),
会使其承受巨大压力,而其他服务端(如服务端 2)请求量相对较少,
此时通过负载均衡机制,将服务端 1 的部分客户端请求分配至服务端 2 ,以此均衡各服务端的负载。
在分布式系统中,负载均衡后多个服务端之间的数据一致性是一个重要考量。

根据 CAP 理论,

不同业务场景需在 一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)之间进行权衡。
若业务对数据一致性要求极为严格,常采用满足 CP 理论的架构。
例如,ZooKeeper 和 Consul 便是实现了 CP 理论的组件,它们在保证数据一致性(Consistency)的同时兼顾分区容错性(Partition
tolerance) ,
能为负载均衡后的分布式系统提供数据一致性保障。
这里不太懂CAP理论的可以看一下这张图:
在这里插入图片描述

1、启用LoadBalancer

①在微服务客户端的配置类上添加@LoadBalancer

就是在上面配置consul的RestTemplateConfig的注解,这个就是开启(轮询负载)负载均衡的作用

/*** RestTemplate的配置类,其作用就是在将此配置写入到IoC容器中,这样就只需要注入的方式便可创建RestTemplate* 它是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集* */
@Configuration
public class RestTemplateConfig {@Bean@LoadBalanced //使用@LoadBalanced注解赋予RestTemplate负载均衡的能力public RestTemplate restTemplate() {return new RestTemplate();}
}
②切换负载均衡的算法(随机)
/*** RestTemplate的配置类,其作用就是在将此配置写入到IoC容器中,这样就只需要注入的方式便可创建RestTemplate* 它是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集** */
@Configuration
@LoadBalancerClient(//下面的value值大小写一定要和consul里面的名字一样,必须一样value = "cloud-payment-service", configuration = RestTemplateConfig.class)
public class RestTemplateConfig {@Bean@LoadBalanced //使用@LoadBalanced注解赋予RestTemplate负载均衡的能力public RestTemplate restTemplate() {return new RestTemplate();}/*将负载均衡的算法改为随机算法*/@BeanReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);}
}

nginx负载均衡和LoadBalancer负载均衡的对比:

Nginx是 服务器负载均衡,客户端所有请求都会交给nginx,
然后由nginx实现转发请求,即负载均衡是由服务端实现的。

loadbalancer 本地负载均衡 ,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,
从而在本地实现RPC远程服务调用技术。

三、Openfeign远程服务接口调用

概念:openfeign就是将原本服务端要向客户端暴漏的API接口,给它封装为一个接口(OpenFeignApi),这时客户端只需要向这个接口进行访问即可。

优点说明
声明式调用通过注解定义 HTTP 请求,无需手动处理请求构建和响应解析
服务发现集成结合服务注册中心(如 consul、Nacos),通过服务名自动路由到具体实例
负载均衡内置客户端负载均衡(如 Ribbon 或 Spring Cloud LoadBalancer)
熔断与容错可集成 Hystrix、Resilience4J 等实现熔断降级
协议透明性支持 RESTful、HTTP/2 等协议,客户端无需关注底层通信细节

1、基本使用

① 引入依赖
<!--openfeign-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
③ 启动OpenFeign

在启动类上添加一个 @EnableFeignClients即可

@SpringBootApplication
@EnableFeignClients
public class WebApplication {public static void main(String[] args)  {SpringApplication.run(WebApplication.class, args); }
}
② 在common公共类创建一个OpenFeignApi接口,配置公共Api

这里可以分为两步去看:

1、使用OpenFeign:也就是在接口上添加一个注解 @FeignClient(value = "服务名"),标记我要使用OpenFeign,指定 **服务名
**

2、配置公共API

/*注意这里的服务名,一定要和你的服务名相同,也就是在consul中所配置的那个 */
@FeignClient(value = "cloud-payment-service")/*标记为OpenFeign接口,value为服务名*/
public interface openFeignApi {@PostMapping("/pay/add")/*这里的网址要与实际调用服务的API接口网址相同*/ResultData add(@RequestBody PayDTO payDTO);@GetMapping("/pay/getAll")ResultData getAll();@GetMapping("/pay/getInfo")String getInfo();
}
③ 测试:

此时这三个便是公共Api,可以让客户端进行访问的Api,我们可以在创建一个Model模拟客户端访问

这里只将公共模块的依赖导入,并创建Controller这里的controller大致也可以分为两步:

1、注入公共APi接口

2、对调用公共APi,并返回


@RestController
@RequestMapping("/consumer")
public class OrderController {/*注入公共APi接口*/@Resourceprivate openFeignApi openFeignApi;/*对调用公共APi,并返回*/@PostMapping("/add")public ResultData add(@RequestBody PayDTO payDTO) {return openFeignApi.add(payDTO);}@GetMapping("/getAll")public ResultData getAll() {return openFeignApi.getAll();}@GetMapping("/getInfo")public ResultData getInfo() {return ResultData.success(openFeignApi.getInfo());}
}

2、进阶配置

①OpenFeign日志打印功能

概念:

在OpenFeign中有个一日志功能(logger)

作用是:记录哪些 HTTP 请求/响应细节(如 Headers、Body 等)

同时它与springBoot中的logging一样也有日志等级(logger.Level)划分:

级别说明
NONE默认的,不显示任何日志;
BASIC仅记录请求方法、URL、响应状态码及执行时间;
HEADERS除了 BASIC 中定义的信息之外,还有请求和响应的头信息;
FULL除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据。

但是要注意别和springBoot的logging日志给搞混了,springBoot日志等级划分:

级别说明
TRACE这是最详细的日志级别,用于记录非常细致的信息,在调试极其复杂的问题时可能会用到。例如,记录方法内部每一步的变量值变化等详细信息。
DEBUG用于开发调试阶段,记录有助于排查问题的详细信息,但不像 TRACE 那样过于细致。比如记录方法的入参、中间计算结果等。
INFO用于记录应用运行过程中的重要信息,比如服务启动、关闭信息,关键业务流程的进展等。一般用于了解应用整体运行状况。
WARN表示出现了一些潜在问题,但应用还能继续运行。例如,应用使用了一个不推荐的 API,或者某个配置可能存在风险等情况。
ERROR用于记录应用运行过程中的错误信息,当发生异常导致应用部分功能无法正常运行时,会记录此级别的日志,方便定位和解决问题。

两者对比:

Feign Client



│ 生成 HTTP 请求/响应日志(内容由 Logger.Level 决定)



SLF4J Logger (Logger 名称为 Feign 接口的全限定名,如 project.user.UserClient)



│ 根据 logging.level 配置决定是否输出



控制台/日志文件

还有一个区别就是,springBoot的日志是可以输入到控制台中的,而Feign的日志并不可以需要借助springBoot的日志才可以

开启logger

1、创建Bean对象


@Configuration/*标记为配置类*/
public class openFeignConfig {/*注意这里的logger是feign.Logger这个包下的,别导错了*/@BeanLogger.Level openFeignLogLevel() {/*修改logger等级*/return Logger.Level.FULL;}
}

2、修改配置客户端的配置(application.yml)

#设置springBoot的日志等级,用于输出Feign的日志
#springboot日志等级设为DEBUG就可以输出Feign的所有日志等级了
logging:level:#这里是你要监听哪一个包(例如:com.chyb.cloud.apis)下的那一个接口(例如:openFeignApi)com.chyb.cloud.apis.openFeignApi: DEBUG

此时变已经设置好了,我们可以先往下看,输出下面的配置的日志

②OpenFeign超时控制

在OpenFeign中可以设置客户端请求的超时时间

为了演示效果配置一个sleep:在服务端的一个APi接口中设置sleep


@GetMapping("/getAll")
@Operation(summary = "查询全部")
public ResultData<List<Pay>> getAll() {try {/*阻塞62秒,这里设置62秒的原因是,在Feign中默认的超时时间是60秒,所以设置60秒以上即可*/TimeUnit.SECONDS.sleep(62);} catch (InterruptedException e) {ResultData.fail(ReturnCodeEnum.RC500.getCode(), e.getMessage());}return ResultData.success(payService.getAll());
}

在客户端调用APi前后输出时间,方便查看


@GetMapping("/getAll")
public ResultData getAll() {System.out.println("-------支付微服务远程调用,按照id查询订单支付流水信息");ResultData resultData = null;try {System.out.println("调用开始-----:" + DateUtil.now());resultData = openFeignApi.getAll();} catch (Exception e) {/*输出报错信息*/e.printStackTrace();System.out.println("调用结束-----:" + DateUtil.now());ResultData.fail(ReturnCodeEnum.RC500.getCode(), e.getMessage());}return resultData;
}

在客户端的application.yml中配置超时时间:

spring:cloud:openfeign:client:config:#配置默认超时时间#default:#连接超时时间#connectTimeout: 3000#读取超时时间#readTimeout: 3000#配置指定访问某一个服务时的超时时间cloud-payment-service:#连接超时时间connectTimeout: 2000#读取超时时间readTimeout: 2000

如图:
在这里插入图片描述

③OpenFeign重试机制

在正常的情况下:当一个请求超时时,要想再次请求就需要重新进行发送请求,这一段时间也是听浪费资源的

这是就可以用到OpenFeign中的一个 重试机制 原理就是当这个请求超时时并不会直接返回,而是在此基础上向服务端在此发起Api请求资源,直到请求成功或者规定的重试次数用完,才进行返回

配置重试机制:

在客户端中的配置类中添加一个Bean对象,即可


@Bean
public Retryer myRetryer() {
//        return Retryer.NEVER_RETRY; //Feign默认配置是不走重试策略的
//        最大请求次数为3(1+2),初始间隔时间为100ms,重试间最大间隔时间为1sreturn new Retryer.Default(100, 1, 3);
}

启动之后如图:
在这里插入图片描述

④OpenFeign更改默认HttpClient

HttpClient是什么:

  1. HttpClient 是 Java 领域功能最全面的 HTTP 客户端库,适合需要精细控制 HTTP 请求的场景。
  2. 在微服务架构中,通常不会直接使用 HttpClient,而是通过更高层的工具(如 OpenFeign、RestTemplate)封装调用,但其底层可能依赖
    HttpClient 实现通信。
  3. 合理配置连接池和超时参数,可显著提升性能,避免资源浪费。

在OpenFeign中默认HttpURLConnection没有连接池、性能和效率比较低,如果采用默认,性能上不是最牛B的,所以需要采用HttpClient5(又称hc5),这个可以变相的提升请求的速度
在 OpenFeign 中 启用 Apache HttpClient 5.x 可以提升性能,尤其是在高并发、高延迟或需要 HTTP/2 的场景下。

这里可以查看官网
所说的:

在这里插入图片描述

OpenFeign启用HttpClient5
1、导入依赖

     <!-- httpclient5-->
<dependency><groupId>org.apache.httpcomponents.client5</groupId><artifactId>httpclient5</artifactId><version>5.3</version>
</dependency>
<!-- feign-hc5-->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-hc5</artifactId><version>13.1</version>
</dependency>

2、修改客户端的yml配置文件

#  Apache HttpClient5 配置开启
spring:cloud:openfeign:httpclient:hc5:enabled: true

启动客户端查看日志
在这里插入图片描述

⑤OpenFeign请求/响应压缩

在OpenFeign中可将请求或者响应的内容压缩为gzip,进行请求/响应,这个样子可以提高请求响应的速度

配置客户端yml配置文件

spring:cloud:openfeign:#开启对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。compression:request:enabled: true #开启请求压缩min-request-size: 2048 #最小触发压缩的大小mime-types: text/xml,application/xml,application/json #触发压缩数据类型response:enabled: true #开启响应压缩

效果如图可以在日志信息中查看:
在这里插入图片描述

四、CircuitBreaker断路器

介绍:CircuitBreaker(断路器)是一套关于断路器的一种规范,其实现者是:Resilience4j、Spring
Retry。(这里我们使用Resilience4j)

CircuitBreaker(断路器)的实现与原理:

在CircuitBreaker中规定了六个状态,

最常用的三个:

状态解释
OPEN打开状态,这个时候会进入一个短路的状态,请求将会有一个降级的机制去执行 兜底 的方案
HALF_OPEN半开启状态,会鉴于开启和关闭之间,其作用就是在当因为某一个原因开启了短路时,要想回到关闭状态,并不会直接关闭,而是先去尝试几次请求是否可以成功,若是可以则在关闭,否则相反
CLOSED关闭状态,这个时候就是正常的状态
不常用的三个:
状态解释
METRICS_ONLY:持续收集请求的各种统计指标
DISABLED:强制关闭
FORCED_OPEN:强制开启

在这里插入图片描述

有了这些状态,就可以更好的控制并发情况下会引发的 雪崩 ,同时提高系统了 可用性健壮性

Resilience4j

在上述中我们知道了CircuitBreaker(断路器)的这些状态,但是具体要如何进行实现,还是需要使用Resilience4j进行实现
而在Resilience4j中一般会使用三大核心策略:熔断降级、隔离、限流,去控制CircuitBreaker(断路器)
的状态,从而实现了CircuitBreaker(断路器)规范

CircuitBreaker(熔断降级)

概念:当请求次数的 失败率 或者 慢调用率达到你所设置的值时,便会 熔断 (也就是将状态改为OPEN),此时便会 降级
,并执行 兜底 操作,过了5s(可以自定义)会从熔断(OPEN)
变为 半开启(HALF_OPEN) 重新尝试请求是否可以 关闭(
CLOSED)

具体流程如下图:
在这里插入图片描述

代码演示

这里从演示两个不同的熔断类型(count-based\time-based)
1、count-based演示

①:创建一个服务Api供客户端调用,并使用公共APi接口对外进行暴漏此API


@RestController
public class PayCircuitController {//=========CircuitBreaker(熔断降级)的演示@GetMapping(value = "/pay/circuit/{id}")public String myCircuit(@PathVariable("id") Integer id) {if (id == -4) throw new RuntimeException("----circuit id 不能负数");if (id == 9999) {try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}}return "Hello, circuit! inputId:  " + id + " \t " + IdUtil.simpleUUID();}
}

@FeignClient(value = "cloud-payment-service")/*标记为OpenFeign接口,value为服务名*/
public interface openFeignApi {@GetMapping(value = "/pay/circuit/{id}")public String myCircuit(@PathVariable("id") Integer id);
}

②导入依赖、修改YML配置文件

<!--resilience4j-circuitbreaker:熔断-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
<!-- 由于断路保护等需要AOP实现,所以必须导入AOP包 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
spring:cloud:consul:circuitbreaker:# 开启circuitbreaker和分组激活enabled: truegroup:enabled: true #没有分组永远不用分组的配置。精确优先、分组次之(开了分组)、默认(default)最后#   #################熔断
# Resilience4j CircuitBreaker 按照次数:COUNT_BASED 的例子
#  6次访问中当执行方法的失败率达到50%时CircuitBreaker将进入开启OPEN状态(保险丝跳闸断电)拒绝所有请求。
#  等待5秒后,CircuitBreaker 将自动从开启OPEN状态过渡到半开HALF_OPEN状态,允许一些请求通过以测试服务是否恢复正常。
#  如还是异常CircuitBreaker 将重新进入开启OPEN状态;如正常将进入关闭CLOSE闭合状态恢复正常处理请求。
resilience4j:circuitbreaker:configs:#修改默认配置default:#配置失败率的阀值failureRateThreshold: 50 #设置50%的调用失败时打开断路器,超过失败请求百分⽐CircuitBreaker变为OPEN状态。#设置滑动窗口(熔断)类型slidingWindowType: COUNT_BASED # 滑动窗口的类型为:计数类型# 设置实时关注的请求数/时间slidingWindowSize: 6 #滑动窗⼝的⼤⼩配置COUNT_BASED表示6个请求,配置TIME_BASED表示6秒# 设置最小样本数minimumNumberOfCalls: 6 #断路器计算失败率或慢调用率之前所需的最小样本(每个滑动窗口周期)。如果minimumNumberOfCalls为10,则必须最少记录10个样本,然后才能计算失败率。如果只记录了9次调用,即使所有9次调用都失败,断路器也不会开启。#启用半开启状态automaticTransitionFromOpenToHalfOpenEnabled: true # 是否启用自动从开启状态过渡到半开状态,默认值为true。如果启用,CircuitBreaker将自动从开启状态过渡到半开状态,并允许一些请求通过以测试服务是否恢复正常# OPEN与HALF_OPEN的切换间隔waitDurationInOpenState: 5s #从OPEN到HALF_OPEN状态需要等待的时间#半开起状态的最大请求数permittedNumberOfCallsInHalfOpenState: 2 #半开状态允许的最大请求数,默认值为10。在半开状态下,CircuitBreaker将允许最多permittedNumberOfCallsInHalfOpenState个请求通过,如果其中有任何一个请求失败,CircuitBreaker将重新进入开启状态。#异常记录recordExceptions:- java.lang.Exception #指定异常并记录#这里我又重新写了一个配置,加上default可以更好的理解,注意,若是count_based中没有配置的,则使用默认(default)的配置testCount:#滑动窗口的大小配置,在count_based表示6个请求,在time_based中表示6s,#  (若是没有 sliding - window - size 的话,会使判定数据随着时间以及请求次数而增加,且判定的数据也可能会因为以前数据和现在的数据进行结合,使得数据并不会因为最近的数据而发生很大的改变#  【也就是两点:数据累积与无时效性(数据没有限制的进行累计)、新旧数据混合影响】)sliding-window-size: 500#       配置 CircuitBreaker 可以计算错误率或慢速调用率之前所需的最小调用次数 (每个滑动窗口周期)【简单来说就是配置样本的最小采集个数】。例如,如果 minimumNumberOfCalls 为 10,则必须至少记录 10 个调用,然后才能计算失败率,如果只记录了 9 个调用,则即使所有 9 个调用都失败,CircuitBreaker 也不会转换为打开。#       这里有一个细节就是,在配置样本次数多时,测试会发现就算是没有到达指定的次数(minimum-number-of-calls)也会只要请求失败的率达到(failure-rate-threshold),也会熔断这是因为Resilience4j有一个类似于"试探性熔断",其作用就是未到达样本次数时,会进行判定是否达到了配置的阀值,若是达到了便会开启熔断minimum-number-of-calls: 500#       要是还是不理解的话,可以直接将sliding-window-size和minimum-number-of-calls这两个值配置相同即可#         ---------------配置半开启状态---------------automatic-transition-from-open-to-half-open-enabled: true #是否启用自动从开启状态过度到半开启状态,默认为true。如果启用,CircuitBreaker将自动从开启状态过渡到半开状态,并允许一些请求通过以测试服务是否恢复正常wait-duration-in-open-state: 5s #从OPEN到HALF_OPEN状态需要等待的时间permitted-number-of-calls-in-half-open-state: 2 #在半开启状态允许的最大请求次数,默认值为:10,在半开启状态CircuitBreaker是允许请求的,如果在此期间有有一次请求失败则都会重新进行开启CircuitBreaker#       --------对指定异常进行记录,且报这个异常的时候也会进行熔断--recordExceptions:#        当报这个异常的时候熔断- java.lang.RuntimeException#         忽略某一个异常#         忽略某一个异常#       ignore-exceptions:#         - java.lang.RuntimeException #当出现此异常时忽略,并不会参与熔断的计算#  resilience4j.circuitbreaker.instances:精细化配置,对某一个服务(cloud-payment-service)进行指定配置(customer)。instances:cloud-payment-service:base-config: testCount

③在微服务客户端中新建一个类用于测试CircuitBreaker断路器


@RestController
public class OrderCircuitController {/*注入公共Api接口*/@Resourceprivate openFeignApi openFeignApi;@GetMapping(value = "/feign/pay/circuit/{id}")@Operation(summary = "熔断降级的测试请求")/*fallbackMethod:是一个设置降级后的兜底方法,当请求熔断之后便会降级,而fallbackMethod会指定一个方法进行兜底操作*/@CircuitBreaker(name = "cloud-payment-service", fallbackMethod = "myCircuitFallback")public String myCircuitBreaker(@PathVariable("id") Integer id) {return openFeignApi.myCircuit(id);}//myCircuitFallback就是服务降级后的兜底处理方法public String myCircuitFallback(Integer id, Throwable t) {// 这里是容错处理逻辑,返回备用结果return "myCircuitFallback,系统繁忙,请稍后再试-----/(ㄒoㄒ)/~~";}
}

测试:这里试着运行几个请求:
比如:3次id为11的请求,三次id为-4的请求,在运行id为11的请求看一下结果,会发现也会报错了。

这就是因为我们配置的失败率为50%,达到这个值便会直接熔断(OPEN),只有等待到半开启状态才可以正常请求
在这里插入图片描述

2、time-based演示
这里依旧是使用公共APi所以直接配置yml即可

resilience4j:circuitbreaker:configs:testTime:# 这两个阀值:分别管理失败请求的阀值、慢调用请求的阀值,所以在这里并不冲突failureRateThreshold: 50 #设置50%的调用失败时打开断路器,超过失败请求百分⽐CircuitBreaker变为OPEN状态。slowCallRateThreshold: 30 #慢调用百分比峰值,断路器把调用时间⼤于slowCallDurationThreshold,视为慢调用,当慢调用比例高于阈值,断路器打开,并开启服务降级slowCallDurationThreshold: 2s #慢调用时间阈值,高于这个阈值的视为慢调用并增加慢调用比例。slidingWindowType: TIME_BASED # 滑动窗口的类型slidingWindowSize: 2 #滑动窗口的大小配置,配置TIME_BASED表示2秒minimumNumberOfCalls: 2 #断路器计算失败率或慢调用率之前所需的最小样本(每个滑动窗口周期)。permittedNumberOfCallsInHalfOpenState: 2 #半开状态允许的最大请求数,默认值为10。waitDurationInOpenState: 5s #从OPEN到HALF_OPEN状态需要等待的时间recordExceptions:- java.lang.Exception#   精细化配置,对某一个服务(cloud-payment-service)进行指定配置(customer)instances:cloud-payment-service:base-config: testTime

注意:设置这个的时候记得要把设置OpenFeign中设置的超时时间,改的比公共APi中设置的sleep时间少,或者直接注释掉,否则会影响测试
在这里插入图片描述

测试,这里当id为9999的时候因为要sleep5秒,且设置2s便为慢调用,所以id=9999是会被视为慢调用,
这时我们可以测试三次9999,三次!=999&&!=-4,的请求,在此请求正常的请求就会发现会报错,这就是time_based的发力ー( ̄~ ̄) ξ,开启了熔断(OPEN)
在这里插入图片描述

熔断降级是对请求失败率/慢调用率,进行判断是否 熔断降级(OPEN),也就是防止故障扩散到上游服务

Bulkhead(隔离)

作用:在服务内部对资源(线程、连接)进行隔离,防止单一故障点耗尽所有资源。
在resilience4中有两种隔离机制:SemaphoreBulkhead(信号量舱壁)、FixedThreadPoolBulkhead(固定线程池舱壁)
如官网:
在这里插入图片描述

代码演示

1、SemaphoreBulkhead(信号量舱壁)

基本上就是我们JUC信号灯内容的同样思想

信号量舱壁(SemaphoreBulkhead)原理:

  1. 当信号量有空闲时,进入系统的请求会直接获取信号量并开始业务处理。
  2. 当信号量全被占用时,接下来的请求将会进入阻塞状态,SemaphoreBulkhead提供了一个阻塞计时器,
  3. 如果阻塞状态的请求在阻塞计时内无法获取到信号量则系统会拒绝这些请求。
  4. 若请求在阻塞计时内获取到了信号量,那将直接获取信号量并执行相应的业务处理。

    代码演示:

①:创建一个服务Api供客户端调用,并使用公共APi接口对外进行暴漏此API

//=========Resilience4j bulkhead(隔离) 的例子
@GetMapping(value = "/pay/bulkhead/{id}")
public String myBulkhead(@PathVariable("id") Integer id) {if (id == -4) throw new RuntimeException("----bulkhead id 不能-4");if (id == 9999 || id == 8888) {try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}}return "Hello, bulkhead! inputId:  " + id + " \t " + IdUtil.simpleUUID();
}
    /*** 测试隔离* @param id* @return*/
@GetMapping(value = "/pay/bulkhead/{id}")
String myBulkhead(@PathVariable("id") Integer id);

②:导入依赖

<!--resilience4j-bulkhead:隔离-->
<dependency><groupId>io.github.resilience4j</groupId><artifactId>resilience4j-bulkhead</artifactId>
</dependency>

③:配置yml文件

resilience4j:#resilience4j bulkhead(隔离)的型号量的例子bulkhead:configs:bulkheadConfig:maxConcurrentCalls: 2 # 隔离允许并发线程执行的最大数量maxWaitDuration: 1s # 当达到并发调用数量时,新的线程的阻塞时间,我只愿意等待1秒,过时不候进舱壁兜底fallbackinstances:cloud-payment-service:base-config: bulkheadConfigtimelimiter:configs:bulkheadConfig:timeout-duration: 20s #神坑的位置,timelimiter 默认限制远程1s,超于1s就超时异常,配置了降级,就走降级逻辑

测试:一次id=9999,一次id=8888(模拟并情况),最后再请求id=11
则:在这里插入图片描述

2、FixedThreadPoolBulkhead(固定线程池舱壁)代码演示
FixedThreadPoolBulkhead的功能与SemaphoreBulkhead一样也是用于限制并发执行的次数的,
但是二者的实现原理存在差别而且表现效果也存在细微的差别。
FixedThreadPoolBulkhead使用一个固定线程池和一个等待队列来实现舱壁。
代码演示

①:修改yml


####resilience4j bulkhead(隔离)的固定型号量的例子
resilience4j:thread-pool-bulkhead:configs:default:core-thread-pool-size: 1max-thread-pool-size: 1queue-capacity: 1instances:cloud-payment-service:baseConfig: default

配置解释如下图
在这里插入图片描述

②:修改调用的Api方法

    /***(船的)舱壁,隔离[固定型号量]* @param id* @return*/
@GetMapping(value = "/feign/pay/bulkhead/{id}")
@Bulkhead(name = "cloud-payment-service", fallbackMethod = "myBulkheadFallback", type = Bulkhead.Type.THREADPOOL)/*注意要修改一下类型*/
/*注意这里的返回值要是:CompletableFuture<T>类型,否则会报错*/
public CompletableFuture<String> myBulkheadTHREADPOOL(@PathVariable("id") Integer id) {System.out.println(Thread.currentThread().getName() + "\t" + "enter the method!!!");try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "\t" + "exist the method!!!");return CompletableFuture.supplyAsync(() -> openFeignApi.myBulkhead(id) + "\t" + " Bulkhead.Type.THREADPOOL");
}public CompletableFuture<String> myBulkheadPoolFallback(Integer id, Throwable t) {return CompletableFuture.supplyAsync(() -> "Bulkhead.Type.THREADPOOL,系统繁忙,请稍后再试-----/(ㄒoㄒ)/~~");
}

测试:随便测试id不同的三个请求
在这里插入图片描述

ratelimit(限流)

概念:ratelimit(限流)就是对指定时间段请求次数过多,从而对他进行限流,防止恶意请求【频率控制】
实现的算法有:

算法解释图形化解释
漏桶算法(Leaky Bucket)一个固定容量的漏桶,按照设定常量固定速率流出水滴,类似医院打吊针,不管你源头流量多大,我设定匀速流出。如果流入水滴超出了桶的容量,则流入的水滴将会溢出了(被丢弃),而漏桶容量是不变的。在这里插入图片描述
令牌桶算法(Token Bucket)系统以固定速率生成令牌存入桶中,请求需获取令牌才能被处理。 (SpringCloud的默认算法)在这里插入图片描述
滚动时间窗(tumbling time window)允许固定数量的请求进入(比如1秒取4个数据相加,超过25值就over)超过数量就拒绝或者排队,等下一个时间段进入。在这里插入图片描述
滑动时间窗口(sliding time window)滑动窗口算法是把固定时间片进行划分并且随着时间移动,移动方式为开始时间点变为时间列表中的第2个时间点,结束时间点增加一个时间点,不断重复,通过这种方式可以巧妙的避开计数器的临界点的问题。在这里插入图片描述

对比

维度漏桶算法令牌桶算法滚动时间窗滑动时间窗
核心目标流量整形(恒定速率)允许突发 + 限流固定周期统计动态时间段统计
突发处理❌不允许✅ 允许(依赖桶容量)❌ 窗口内固定✅ 窗口内动态
实现复杂度
数据连续性❌不适用❌不适用❌窗口间不连续✅ 窗口间连续
典型场景严格限制请求速率容忍短暂突发的限流周期性报表统计实时精准限流
代码演示

①:创建一个服务Api供客户端调用,并使用公共APi接口对外进行暴漏此API

//=========Resilience4j ratelimit 的例子
@GetMapping(value = "/pay/ratelimit/{id}")
public String myRatelimit(@PathVariable("id") Integer id)
{return "Hello, myRatelimit欢迎到来 inputId:  "+id+" \t " + IdUtil.simpleUUID();
}
/*** Resilience4j Ratelimit 的例子* @param id* @return*/
@GetMapping(value = "/pay/ratelimit/{id}")
public String myRatelimit(@PathVariable("id") Integer id);

② 导入依赖

<!--resilience4j-ratelimiter-->
<dependency><groupId>io.github.resilience4j</groupId><artifactId>resilience4j-ratelimiter</artifactId>
</dependency>

③配置yml依赖

####resilience4j ratelimiter 限流的例子
resilience4j:ratelimiter:configs:default:limitForPeriod: 2 #在一次刷新周期内,允许执行的最大请求数![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/944cb5267b6b434ca1ebb88ffa845711.png#pic_center)limitRefreshPeriod: 1s # 限流器每隔limitRefreshPeriod刷新一次,将允许处理的最大请求数量重置为limitForPeriodtimeout-duration: 1 # 线程等待权限的默认等待时间instances:cloud-payment-service:baseConfig: default

④测试
一个请求多刷新几次便会:
在这里插入图片描述


参考资源:spring官网、尚硅谷

相关文章:

springCloud/Alibaba常用中间件全集(上)

文章目录 SpringCloud:一、Consul:服务注册与发现1、下载Consul2、运行Consul3、服务注册①. 导入依赖②. 配置yml③. 启动类添加Consul的启动服务发现注解④. 解决 **硬编码** 问题⑤. 此时便可以将IP地址改为服务名 4、服务配置与刷新①. 引入Consul-Config依赖②. 修改boots…...

嵌入式单片机通过ESP8266连接物联网实验

第一:通过手机APP远程监控和控制 ESP8266驱动RST低电平触发复位,平时需要跟EN一样分别接10k拉高到3.3V 如果是12E/F的话管脚比较多,GPIO15也要接个1K到地 烧录时GPIO要接地,正常工作时将其拉高或者悬空 主要使用串口通信,烧录固件也是通过串口,烧录时,启动烧录程序后…...

Visio导出清晰图片步骤

在Visio里画完图之后如何导出清晰的图片&#xff1f;&#x1f447; ①左上角单击【文件】 ②导出—更改文件类型—PNG/JPG ③分辨率选择【打印机】&#xff0c;大小选择【源】&#xff0c;即可。 ④选择保存位置并命名 也可以根据自己需要选择是否需要【透明底】哈。 选PNG 然…...

速查手册:TA-Lib 超过150种量化技术指标计算全解 - 1. Overlap Studies(重叠指标)

速查手册&#xff1a;TA-Lib 超过150种量化技术指标计算全解 - 1. Overlap Studies&#xff08;重叠指标&#xff09; TA-Lib&#xff08;Technical Analysis Library&#xff09;是广泛使用的金融技术分析库&#xff0c;实现了超过150种技术指标计算函数&#xff0c;适用于股票…...

大模型Rag - 如何评估Rag

一.RAG流程与评估标准补充 RAG&#xff08;Retrieval-Augmented Generation&#xff09;是一种结合检索与生成的问答架构。为了确保系统效果&#xff0c;需要从以下三个角度对其评估&#xff1a; 回顾RAG流程 用户提出问题 → 系统检索相关上下文 → 基于上下文由大语言模型…...

复习JUC的总结笔记

JUC基础 调用Thread的start方法会调用start0&#xff0c;start0会调用该Thread类的run方法。Thread类如果传入了Runnable&#xff0c;run方法里会调用Runnable的run方法&#xff0c;如果没有传入&#xff0c;则什么也不会做。也可以通过重写Thread的run方法&#xff0c;让start…...

基于MTF的1D-2D-CNN-GRU-Attention时序图像多模态融合的故障识别,适合研究学习(Matlab完整源码和数据),附模型研究报告

基于MTF的1D-2D-CNN-GRU-Attention时序图像多模态融合的故障识别&#xff0c;适合研究学习&#xff08;Matlab完整源码和数据&#xff09;&#xff0c;附模型研究报告 目录 基于MTF的1D-2D-CNN-GRU-Attention时序图像多模态融合的故障识别&#xff0c;适合研究学习&#xff08;…...

5G 毫米波滤波器的最优选择是什么?

新的选择有很多&#xff0c;但到目前为止还没有明确的赢家。 蜂窝电话技术利用大量的带带&#xff0c;为移动用途提供不断增加的带宽。 其中的每一个频带都需要透过滤波器将信号与其他频带分开&#xff0c;但目前用于手机的滤波器技术可能无法扩展到5G所规划的全部毫米波&#…...

构造函数和析构函数

概念&#xff1a;对象的初始化和清理是非常重要的&#xff0c;一个对象在使用之前&#xff0c;需要进行初始化&#xff0c;使用完成后也需要及时清理数据&#xff0c;简单来说构造函数时用来初始化成员属性的&#xff0c;析构函数时用来清理数据的。 C中利用构造函数和析构函数…...

卷积神经网络(CNN)详解

文章目录 引言1.卷积神经网络&#xff08;CNN&#xff09;的诞生背景2.卷积神经网络&#xff08;CNN&#xff09;介绍2.1 什么是卷积神经网络&#xff1f;2.2 卷积神经网络&#xff08;CNN&#xff09;的基本特征2.2.1 局部感知&#xff08;Local Connectivity&#xff09;2.2.…...

NoSQl注入学习

文章目录 什么是NOSQL相关概念数据库文档集合 MongoDB 基础语法创建数据库创建集合插入文档更新文档查询文档 Nosql注入PHP 中的 MongoDB 注入重言式注入联合查询注入JavaScript 注入布尔盲注 Nodejs 中的 MongoDB 注入 从一道题中学习nosql注入 参考&#xff1a; Nosql 注入从…...

借助LlamaIndex实现简单Agent

借助LlamaIndex实现简单Agent 1 简介 智能体的构建发展是一个趋势&#xff0c;借助LlamaIndex简单实现Agent。本文主要借助LlamaIndex中的FunctionTool和Workflow。Workflow是使用事件流的方法实现。 2 构建公共类 由于LlamaIndex中的OpenAI无法直接连接国内大模型&#xf…...

MCGS昆仑通太屏笔记

4.3寸&#xff1a;4013ef/e1 7寸&#xff1a;7032kw 特点&#xff1a; 如果是使用组态屏进行调试使用&#xff0c;选择com1如果是实际项目使用&#xff0c;选择com2 操作步骤&#xff1a; 先创建设备窗口&#xff0c;再创建用户界面 在设备窗口界面&#xff0c;依次设置如下…...

纯FPGA控制AD9361的思路和实现之一 概述

我们知道PS通过内存映射方式方式用户的IP&#xff0c;具体是将用户的逻辑做成AXI_LITE_SALVE外设&#xff0c;PS做为AXI_LITE_MASTER去控制。 在ZYNQ系统中存在PS所以这个架构和思路很流行&#xff0c;ADI出的配置软件无线电子板的DEMO基本都是基于这样的架构。比如下图【上截…...

北斗短报文终端与5G融合:构建空天地海一体化通信新生态

随着北斗三号全球组网完成&#xff0c;短报文通信服务从区域覆盖迈向全球通达&#xff0c;其与5G技术的深度融合&#xff0c;正开创“空天地海一体化”通信新时代。深圳作为全国北斗产业高地&#xff0c;汇聚了遨游通讯等领军企业&#xff0c;其推出的北斗短报文终端通过技术创…...

Meteonorm8-免费使用教程(详细教程-免费)

Meteonorm介绍 Meteonorm 8 是一款专业的气象数据生成软件&#xff0c;广泛应用于太阳能、建筑能效、农业气候研究等领域。它提供全球范围内高精度的气象数据&#xff0c;支持多种数据源和插值方法&#xff0c;帮助用户获取特定地点的长期气象统计信息。 Meteonorm核心功能 …...

nohup的使用

最近远程连接服务器跑程序的时候&#xff0c;总是碰到本地电脑息屏或者ssh断开导致程序中断&#xff0c;往往一觉醒来不是程序跑完了而是因为各种原因本地中断了。为此想到了nohup这个命令&#xff0c;可以让程序在我本地电脑关机后也可以在远端服务器上面运行。 命令如下&…...

如何查看HTTP状态码?

目录 一、HTTP状态码查看方法 1. ​​浏览器开发者工具​​ 2. ​​命令行工具​​ 3. ​​服务器日志分析​​ 二、HTTP状态码分类与核心含义 1. ​​信息类&#xff08;1xx&#xff09;​​ 2. ​​成功类&#xff08;2xx&#xff09;​​ 3. ​​重定向类&#xff08…...

2025.04.19【Chord diagram】| 弦图绘制技巧大全

Customization Apply customization to the circular chart: color, background, track height and more. Chart types Learn how to use other chart types like line chart, barcharts, vertical ablines and more. 文章目录 CustomizationChart types 什么是弦图&#xff…...

解码 Web Service:从技术原理到应用场景的深度剖析

Web Service 是一种基于网络的、分布式的计算技术&#xff0c;它允许不同的应用程序之间通过网络进行通信和交互。以下是关于 Web Service 的详细介绍&#xff1a; 一、定义与概念 Web Service 是一种可以通过 Web 协议&#xff08;如 HTTP&#xff09;进行访问的软件组件&am…...

hackmyvm-airbind

收集信息 arp-scan -l nmap -sS -v 192.168.195.162 访问扫描到的ip&#xff0c;直接跳转到登录页面&#xff0c;利用admin/admin弱口令登录 在settings.php中找到一处文件上传&#xff0c;上传一句话木马&#xff0c;上传成功 反弹shell 上传php-reverse-shell.php 抓包&am…...

[HCIP] OSPF 综合实验

题目 实验需求 1.R5为TSP&#xff0c;其上只能配置IP地址&#xff1b; R5与其他所有直连设备间均使用公有IP&#xff1b;环回地址为100.1.1.1/32 2.R4设备为企业出口路由器 3.整个OSPF环境IP基于172.16.0.0/16划分&#xff1b; 4.所有设备均可访问R5的环回&#xff1b; 5…...

arkTs:使用setTimeout / setInterval 实现透明度切换的轮播图

使用setTimeout / setInterval 实现透明度切换的轮播图 1 主要内容说明1.1 setTimeout1.2 setInterval1.3 表格 2 举例说明2.1 图片变化的内容说明2.2 源码相关内容说明2.3 源码A2.4源码A的运行效果展示2.4.1 效果截图2.4.2 效果视频 3.结语4.定位日期 1 主要内容说明 1.1 set…...

苍穹外卖项目中所涉及到的测试内容

1.使用JWT令牌封装用户令牌&#xff0c;并且设置相应的拦截器校验JWT的有效性&#xff0c;从而确保了项目的安全可靠 1.基本功能测试&#xff1a; 验证合法JWT是否能够正常通过拦截器的校验 验证非法的JWT能否正常通过拦截器的校验 2.可靠性测试&#xff1a; 3.易用性测试 …...

案例驱动的 IT 团队管理:创新与突破之路:第五章 创新管理:从机制设计到文化养成-5.2 技术决策民主化-5.2.3草根创新的孵化土壤构建

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 草根创新的孵化土壤构建&#xff1a;IT团队技术决策民主化的底层实践1. 背景与挑战&#xff1a;传统技术决策体系的失效1.1 行业现状与痛点1.2 草根创新的价值潜力 2. 机制设…...

探秘Python 工匠:案例、技巧与工程实践:解锁Python进阶的通关秘籍

重要的放前面 Python 工匠&#xff1a;案例、技巧与工程实践 探秘Python 工匠&#xff1a;案例、技巧与工程实践&#xff1a;解锁Python进阶的通关秘籍 在Python的编程世界中&#xff0c;从入门小白到技术大牛的进阶之路往往充满挑战。Python工匠&#xff1a;案例、技巧与工…...

【langchain4j】Springboot如何接入大模型以及实战开发-AI问答助手(一)

langchain4j介绍 官网地址&#xff1a;https://docs.langchain4j.dev/get-started langchain4j可以说是java和spring的关系&#xff0c;spring让我们开发java应用非常简单&#xff0c;那么langchain4j对应的就是java开发ai的 “Spring” 他集成了AI应用的多种场景&#xff0c…...

解决Windows update服务启动拒绝访问的问题 | wuauserv 注册表拒绝访问的方法

在某些情况下,为了配置系统更新相关服务(例如禁用 Windows 自动更新),我们需要更改注册表中 wuauserv 项的权限。本教程将带你一步步操作,成功获取并修改权限。 修改注册表路径: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wuauserv 步骤一:打开注册表编辑…...

精益数据分析(5/126):解锁创业成功的关键密码

精益数据分析&#xff08;5/126&#xff09;&#xff1a;解锁创业成功的关键密码 大家好&#xff01;我一直坚信在技术与商业不断融合的当下&#xff0c;持续学习是保持进步的唯一途径。之前我们一起探讨了《精益数据分析》的部分内容&#xff0c;今天咱们接着深入学习&#x…...

Cribl 优化EC2 ip-host-region 数据

We’ve seen examples of using the magical powers of regex to customize Functions, extract fields, and filter events in real time. In this section, we’ll show you how to sprinkle your Lookups with regex magic. Lets walk through a Pipeline that demonstrates…...

【java实现+4种变体完整例子】排序算法中【桶排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格

以下是桶排序的详细解析&#xff0c;包含基础实现、常见变体的完整代码示例&#xff0c;以及各变体的对比表格&#xff1a; 一、桶排序基础实现 原理 将数据分到有限数量的桶中&#xff0c;每个桶内部使用其他排序算法&#xff08;如插入排序或快速排序&#xff09;&#xf…...

栈(c++)

今天介绍两种在c中写“栈”方法 1. #include <bits/stdc.h> using namespace std;class mystack { private:int a[1000];int curr -1; public:void push(int);void pop();int top();bool empyt();int size(); };int main() {mystack n;while(true){int a;cout<<&…...

GraphRAG与RAG的区别和原理简介

第一章 图谱与向量的共生逻辑 1.1 知识载体的局限性 向量空间模型虽能高效捕捉文本语义相似性&#xff0c;却无法解析知识的深层关联。例如&#xff0c;当用户询问“特斯拉4680电池与续航里程的关系”&#xff0c;向量检索可能仅返回技术参数片段&#xff0c;而无法解释化学成…...

vue2技术练习-开发了一个宠物相关的前端静态商城网站-宠物商城网站

为了尽快学习掌握相关的前端技术&#xff0c;最近又实用 vue2做了一个宠物行业的前端静态网站商城。还是先给大家看一下相关的网站效果&#xff1a; 所以大家如果想快速的学习或者掌握一门编程语言&#xff0c;最好的方案就是通过学习了基础编程知识后&#xff0c;就开始利用…...

[每周一更]-(第140期):sync.Pool 使用详解:性能优化的利器

文章目录 一、什么是 sync.Pool&#xff1f;二、sync.Pool 的基本作用三、sync.Pool 的主要方法四、sync.Pool 的内部工作原理五、sync.Pool 适用场景六、使用示例示例 1&#xff1a;基本使用输出示例&#xff1a;示例 2&#xff1a;并发使用 七、一个基于 sync.Pool 的 **Benc…...

Prompt-Tuning 提示词微调

1. Hard Prompt 定义&#xff1a; Hard prompt 是一种更为具体和明确的提示&#xff0c;要求模型按照给定的信息生成精确的结果&#xff0c;通常用于需要模型提供准确答案的任务. 原理&#xff1a; Prompt Tuning原理如下图所示&#xff1a;冻结主模型全部参数&#xff0c;在…...

sqli-labs之Less-7 GET注入写shell

验证注入点&#xff1a;单引号报错&#xff0c;)) 根据提示&#xff0c;是想让我们试试写shell 第一个条件 secure_file_priv 写shell即MySQL需要对外写文件&#xff0c;但默认MySQL是不允许outfile来导出数据的&#xff0c;先动手在MySQL确认一下。 MySQL特性&#xff0c;se…...

数据库基础-B+树

查询类型 全表扫描&#xff0c;不提供索引&#xff0c;扫描所有集合中的数据。根据指定key值查询指定点范围查询&#xff0c;在指定区间内查询 有很多方法能够进行快速扫面数据&#xff0c;但是再快复杂度也是O(N)&#xff0c;我们的目标是想办法将查询复杂度降低到O(logN)。…...

智能语音备忘录:SpeechRecognition与gTTS的奇妙融合

引言&#xff1a;智能语音备忘录的时代已经到来 在这个信息爆炸的时代&#xff0c;我们每天需要处理大量的事务和信息。传统的文字记录方式虽然可靠&#xff0c;但在效率上往往难以满足快节奏生活的需求。想象一下&#xff0c;如果你能在驾车、散步或是灵感突现的任何时刻&…...

C++项目 —— 基于多设计模式下的同步异步日志系统(3)(日志器类)

C项目 —— 基于多设计模式下的同步&异步日志系统&#xff08;3&#xff09;&#xff08;日志器类&#xff09; 整体思想设计日志消息的构造C语言式的不定参函数的作用函数的具体实现逻辑1. 日志等级检查2. 初始化可变参数列表3. 格式化日志消息4. 释放参数列表5. 序列化和…...

2025/4/19 数据库的流程控制函数

单行函数_流程函数 要点: 流程处理函数可以根据不同的条件 执行不同的处理流程 可以在SQL语句中实现不同的条件选择,MySQL中的流程处理函数主要包括if() ifnull() 和 case() 函数 多行函数_聚合函数 和单行函数的区别: 单行函数是作用在每一行 最终结果可能是多行结果 多行…...

代码随想录打家劫舍+树形DP入门

动态规划part07 198.打家劫舍 视频讲解&#xff1a;https://www.bilibili.com/video/BV1Te411N7SX https://programmercarl.com/0198.%E6%89%93%E5%AE%B6%E5%8A%AB%E8%88%8D.html dp数组&#xff1a;进入房屋i能够偷得得最大金额dp[i]递推公式&#xff1a;根据不相邻原则…...

Http基础

目录 定义 一、请求部分&#xff08;Request&#xff09; 1. 请求行&#xff08;Request Line&#xff09; 常见请求方法&#xff1a; 2. 请求头&#xff08;Request Headers&#xff09; 3. 请求体&#xff08;Request Body&#xff09; 二、响应部分&#xff08;Respo…...

【Unity】bug记录——部分物体突然不受animator控制

博主烘焙完灯光后突然发现有的物体的动画失效了&#xff0c;不会动&#xff0c;测试发现是因为勾了static&#xff08;但是有些勾了static的物体就没事&#xff09;&#xff0c;修改static为Contribute GI Static&#xff08;只针对光照静态&#xff09;就行...

Zephyr、FreeRTOS、RT-Thread 邮箱(Mailbox)对比分析

一、核心特性对比 特性ZephyrFreeRTOSRT-Thread消息类型支持指针或4字节数据&#xff08;依赖架构&#xff09;仅支持指针传递支持任意数据类型&#xff08;需指定消息长度&#xff09;容量固定容量&#xff08;静态初始化配置&#xff09;动态容量&#xff08;基于队列长度&a…...

xilinx fpga中pll与mmcm的区别

Xilinx中的PLL&#xff08;锁相环&#xff09;和MMCM&#xff08;混合模式时钟管理器&#xff09;都是用于时钟管理的关键组件&#xff0c;但它们之间存在一些显著的区别。以下是对两者的详细比较&#xff1a; 1. 功能特性 PLL&#xff08;锁相环&#xff09;&#xff1a; 主…...

Python语法系列博客 · 第8期[特殊字符] Lambda函数与高阶函数:函数式编程初体验

上一期小练习解答&#xff08;第7期回顾&#xff09; ✅ 练习1&#xff1a;找出1~100中能被3或5整除的数 result [x for x in range(1, 101) if x % 3 0 or x % 5 0]✅ 练习2&#xff1a;生成字符串长度字典 words ["apple", "banana", "grape…...

黑马商城(五)微服务保护和分布式事务

一、雪崩问题 二、雪崩-解决方案&#xff08;服务保护方案&#xff09; 请求限流&#xff1a; 线程隔离&#xff1a; 服务熔断&#xff1a; 服务保护组件&#xff1a; 三、Sentinel 引入依赖&#xff1a; <!--sentinel--> <dependency><groupId>com.aliba…...

Java 编译与反编译深度解析

Java 编译与反编译深度解析 1. 编译过程详解 (1) 完整编译流程 .java 文件 → 词法分析 → 语法分析 → 语义分析 → 字节码生成 → .class 文件│ │ │ │↓ ↓ ↓ ↓识别关键字 生成抽象语法树 类型…...

Java集合框架中的List、Map、Set详解

在Java开发中&#xff0c;集合框架是处理数据时不可或缺的工具之一。今天&#xff0c;我们来深入了解一下Java集合框架中的List、Map和Set&#xff0c;并探讨它们的常见方法操作。 目录 一、List集合 1.1 List集合介绍 1.2 List集合的常见方法 添加元素 获取元素 修改元素…...