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

OpenFeign服务接口调用

OpenFeign服务接口调用

1、OpenFeign简介

​ Feign是一个声明性web服务客户端。它使编写web服务客户端变得更容易。使用Feign创建一个接口并对其进行注释。它具有可插入的注释支持,包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。Spring Cloud添加了对Spring MVC注释的支持,以及对使用Spring Web中默认使用的HttpMessageConverter的支持。Spring Cloud集成了Eureka、Spring Cloud CircuitBreaker以及Spring Cloud LoadBalancer,以便在使用Feign时提供负载平衡的http客户端。

官网:Spring Cloud OpenFeign

​ 一句话:openfeign是一个声明式的Web服务客户端,我们只需要创建一个Rest接口并在该接口上添加注解@FeignClint即可使用,OpenFeign基本上就是当前微服务之间调用的事实标准。

​ 官网演示了一个案例

  • 先在springboot应用中开启FeignClients

    @SpringBootApplication
    @EnableFeignClients
    public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}
    
  • 然后写个接口StoreClient打上@FeignClint注解

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

2、OpenFeign能干什么?

​ 前面在使用SpringCloud LoadBalancer+RestTemplate时,利用RestTemplate对http请求的封装处理形成了一套模版化的调用方法。

​ 但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。

​ 所以,OpenFeign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。 在OpenFeign的实现下,我们只需创建一个接口并使用注解的方式来配置它(在一个微服务接口上面标注一个**@FeignClient**注解即可),即可完成对服务提供方的接口绑定,统一对外暴露可以被调用的接口方法,大大简化和降低了调用客户端的开发量,也即由服务提供者给出调用接口清单,消费者直接通过OpenFeign调用即可。

OpenFeign同时还集成SpringCloud LoadBalancer

​ 可以在使用OpenFeign时提供Http客户端的负载均衡,也可以集成阿里巴巴Sentinel来提供熔断、降级等功能。而与SpringCloud LoadBalancer不同的是,通过OpenFeign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。

OpenFeign主要能干的事

  • 可插拔的注解支持,包括Feign注解和JAX-RS注解;
  • 支持可插拔的HTTP编码器和解码器;
  • 支持Sentinel和它的Fallback;
  • 支持SpringCloudLoadBalancer的负载均衡;
  • 支持HTTP请求和响应的压缩;

​ 我们目前是80消费者端的服务去调8001支付服务模块和8002订单服务模块,在80消费者端我们使用的是RestTemplate实现调用,但是,微服务之间也需要相互调用呢?8002调用8001呢?难不成每一个微服务想调用其他服务时再写一次RestTemplate?8001作为一个支付服务含有很多支付流水信息,会有很多其他微服务会调用它,根据解耦和面向接口的原则,我们最好在8001上写出对外暴露的接口,其他服务想调用它,就要找8001定义的接口。

3、使用

​ 架构说明图:

image-20240313105409039

3.1、新建module

​ 新建module,cloud-consumer-feign-order80,导入依赖。

pom.xml

 <dependencies><!--openfeign新加的坐标--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--SpringCloud consul discovery--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-discovery</artifactId></dependency><!-- 引入自己定义的api通用包 --><dependency><groupId>com.zm.cloud</groupId><artifactId>cloud-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency><!--web + actuator--><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><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--hutool-all--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency><!--fastjson2--><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId></dependency><!-- swagger3 调用方式 http://你的主机IP地址:5555/swagger-ui/index.html --><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>

写YML

server:port: 80
spring:application:name: cloud-consumer-openfeign-order####Spring Cloud Consul for Service Discoverycloud:consul:host: localhostport: 8500discovery:prefer-ip-address: true #优先使用服务ip进行注册service-name: ${spring.application.name} 

主启动类

@SpringBootApplication
@EnableDiscoveryClient //使用consul为注册中心时注册服务
@EnableFeignClients  //开启OpenFeign功能并激活
public class MainOpenFeign80 {public static void main(String[] args) {SpringApplication.run(MainOpenFeign80.class,args);}
}

要把接口PayFeignApi创建在通用的api模块cloud-api-commons中

​ 修改cloud-api-commons模块,pom文件中添加openfeign的依赖

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

​ 参考微服务8001的Controller层,新建PayFeignApi接口

@FeignClient(value = "cloud-payment-service")
public interface PayFeignApi {/*** 新增一条支付相关流水记录* @param payDTO* @return*/@PostMapping("/pay/add")public ResultData addPay(@RequestBody PayDTO payDTO);//通过id查询@GetMapping(value = "/pay/get/{id}")public ResultData getPayById(@PathVariable("id") Integer id);//删除@DeleteMapping("/pay/del/{id}")public ResultData delById(@PathVariable("id") Integer integer);//修改@PutMapping("/pay/update")public ResultData update(@RequestBody PayDTO payDTO);//查全部@GetMapping("/pay/getall")public ResultData getAll();//openfeign天然支持负载均衡演示@GetMapping("/pay/getInfo")public String myLB();}

​ 我们把原来微服务80的controller复制一份到cloud-consumer-feign-order80中,原来的内容全部删除,重新使用PayFeignApi实现。当应用启动时,Feign 使用 Java 的动态代理机制生成接口的实现。这个过程由 Spring Cloud 集成提供支持Feign 客户端在内部构建了请求的详细信息,并将接口方法调用转换为 HTTP 调用。

@RestController
public class OrderController {@Resourceprivate PayFeignApi payFeignApi;@PostMapping("/feign/pay/add")public ResultData addPay(@RequestBody PayDTO payDTO){System.out.println("1、使用本地addOrder新增订单功能(省略sql操作),2、开启addPay支付微服务远程调用");ResultData resultData = payFeignApi.addPay(payDTO);return resultData;}@GetMapping("/feign/pay/get/{id}")public ResultData getByID(@PathVariable("id") Integer id){System.out.println("-------支付微服务远程调用,按照id查询订单支付流水信息");ResultData payById = payFeignApi.getPayById(id);return payById;}@DeleteMapping("/feign/pay/del/{id}")public ResultData delById(@PathVariable("id") Integer id){System.out.println("-------支付微服务远程调用,按照id查删除订单支付流水信息");return payFeignApi.delById(id);}@PutMapping("/feign/pay/update")public ResultData update(@RequestBody PayDTO payDTO){System.out.println("-------支付微服务远程调用,修改订单支付流水信息");return payFeignApi.update(payDTO);}@GetMapping("/feign/pay/getall")public ResultData getAll(){return payFeignApi.getAll();}@GetMapping("/feign/pay/getInfo")public String mylb(){return payFeignApi.myLB();}}

​ 测试启动新的80服务,启动微服务8001和8002.

image-20240313140818314

​ 使用浏览器或者其他测试工具先查询一个看看

image-20240313141906611

​ 添加一个数据

image-20240313142141138

​ 查询全部

image-20240313142211054

​ 删除刚才新增的

image-20240313142303242

​ 下面测试负载均衡

image-20240313142738116

​ 因为OpenFeign默认的集成了LoadBalancer,所以就会负载均衡。

​ 梳理一遍

image-20240313144743890

​ 在使用Feign进行微服务间的通信时,当发出一个请求到PayFeignApi接口时,该请求实际上是通过Feign客户端进行代理的。Feign会根据你提供的@FeignClient(value = "cloud-payment-service")注解中的value值(即服务名)来定位目标服务。

​ 当请求到达PayFeignApi接口时大致流程:

  1. 路由到目标服务:Feign会根据我们在注解上填的微服务名称去注册中心(consul)找有没有这个微服务,然后找到这个微服务下的具体示例列表,因为Feign本身就有负载均衡能力,默认还是轮询的方式进行调度。
  2. 选择具体的端点:选择完目标示例之后,Feign会根据你定义的路径(/pay/add)来拼凑完整的URL,比如说选择了8001,那么URL就是:http://localhost:8001/pay/add;
  3. 发送请求:URL拿到后,Feign就使用HTTP客户端发送请求到服务提供者,然后就是具体的处理请求了,至此整个服务流程完成。

4、OpenFeign高级特性

4.1、OpenFeign超时控制

​ 在Spring Cloud微服务架构中,大部分公司都是利用OpenFeign进行服务间的调用,而比较简单的业务使用默认配置是不会有多大问题的,但是如果是业务比较复杂,服务要进行比较繁杂的业务计算,那后台很有可能会出现Read Timeout这个异常,因此定制化配置超时时间就有必要了。

image-20240313151559540

4.1.1、设置超时演示

​ 我们故意设置超时出错情况,让8001的服务睡一会儿。

服务提供方cloud-provider-payment8001故意写暂停62秒钟程序,把getById的controller修改一下,睡一会儿

//通过id查询
@GetMapping("/pay/get/{id}")
@Operation(summary = "查询",description = "通过ID查询")
public ResultData<Pay> payById(@PathVariable("id") Integer id){System.out.println("---------正在查询--------");try {TimeUnit.SECONDS.sleep(62);} catch (InterruptedException e) {throw new RuntimeException(e);}return ResultData.success(payServiceImp.getById(id));
}

​ 为啥是62秒???试出超时时间。

服务调用方cloud-consumer-feign-order80写好捕捉超时异常

@GetMapping("/feign/pay/get/{id}")
public ResultData getByID(@PathVariable("id") Integer id){System.out.println("-------支付微服务远程调用,按照id查询订单支付流水信息");ResultData payById = null;try {System.out.println("调用开始时间------>"+ DateUtil.now());payById = payFeignApi.getPayById(id);}catch (Exception e){e.printStackTrace();System.out.println("调用结束时间------>"+ DateUtil.now());ResultData.fail(ReturnCodeEnum.RC500.getCode(), e.getMessage());}return payById;
}

​ 开始测试,重新启动8001和80,浏览器输入localhost/feign/pay/get/1:

​ **注意:**如果测试的时候你的8002服务没有关闭的话,轮询还是存在的,可能第一次请求就是成功的,刷新一下就轮到8001了,你要不想轮询就把8002关闭。

image-20240313154153904

​ 所以说,OpenFeign的默认超时时间是60秒,所以故意弄的睡眠时间就是60秒以上。

​ 默认OpenFeign客户端等待60秒钟,但是服务端处理超过规定时间会导致Feign客户端返回报错。

​ 为了避免这样的情况,有时候我们需要设置Feign客户端的超时控制,默认60秒太长或者业务时间太短都不好。

​ 这就需要在yml中开始配置了:

connectTimeout       连接超时时间readTimeout          请求处理超时时间

​ 官网默认配置参数

image-20240313155357974

全局配置

​ 在application.yml文件中配置

server:port: 80
spring:application:name: cloud-consumer-openfeign-order####Spring Cloud Consul for Service Discoverycloud:consul:host: localhostport: 8500discovery:prefer-ip-address: true #优先使用服务ip进行注册service-name: ${spring.application.name}openfeign:client:config:default:#连接超时时间connectTimeout: 3000#读取超时时间readTimeout: 3000

​ 重启80服务测试一下:

image-20240313185725554

​ 有1秒的误差,打印信息了。

指定配置

​ 还可以指定某个服务的超时时间,但是不能和default一起写,这样会覆盖掉default的时间,用你指定服务的超时时间。演示一下两者都写的情况。

server:port: 80
spring:application:name: cloud-consumer-openfeign-order####Spring Cloud Consul for Service Discoverycloud:consul:host: localhostport: 8500discovery:prefer-ip-address: true #优先使用服务ip进行注册service-name: ${spring.application.name}openfeign:client:config:default:connectTimeout: 3000            #连接超时时间readTimeout: 3000             #读取超时时间cloud-payment-service:connectTimeout: 5000readTimeout: 5000

​ 再次测试

image-20240313190714409

​ 结果是5秒,所以自己指点的时间就会覆盖掉默认设置的时间。

4.2、OpenFeign重试机制

​ OpenFeign的重试机制默认是关闭的

image-20240313192605874

​ 想开启重试就新增一个配置类FeignConfig并修改Retryer配置,把指定的8001超时时间设置为4秒

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

​ 现在测试一下,如果走了重试应该就是5*3=15秒

image-20240313200641627

4.3、OpenFeign默认HttpClient修改

​ OpenFeign中http client,如果不做特殊配置,OpenFeign默认使用JDK自带HttpURLConnection发送HTTP请求,由于默认HttpURLConnection没有连接池、性能和效率比较低,如果采用默认,性能上不是最强大的,所以需要换掉推荐使用阿帕奇的HC5

​ 我们看到官网

image-20240313202234136

​ 我们先把超时重试的配置关闭。

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

​ 修改POM文件,添加依赖

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

​ 在application.yml配置文件中打开Apache HttpClient5

server:port: 80
spring:application:name: cloud-consumer-openfeign-order####Spring Cloud Consul for Service Discoverycloud:consul:host: localhostport: 8500discovery:prefer-ip-address: true #优先使用服务ip进行注册service-name: ${spring.application.name}openfeign:client:config:
#            default:
#             connectTimeout: 3000            #连接超时时间
#             readTimeout: 3000             #读取超时时间cloud-payment-service:connectTimeout: 5000readTimeout: 5000httpclient:hc5:enabled: true

​ 重启再看一下现在报错信息来至于哪里

image-20240313203114165

4.4、OpenFeign请求/响应压缩

对请求和响应进行GZIP压缩

Spring Cloud OpenFeign支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。

通过下面的两个参数设置,就能开启请求与相应的压缩功能:

spring.cloud.openfeign.compression.request.enabled=truespring.cloud.openfeign.compression.response.enabled=true

细粒度化设置

​ 对请求压缩做一些更细致的设置,比如下面的配置内容指定压缩的请求数据类型并设置了请求压缩的大小下限,只有超过这个大小的请求才会进行压缩:

spring.cloud.openfeign.compression.request.enabled=truespring.cloud.openfeign.compression.request.mime-types=text/xml,application/xml,application/json #触发压缩数据类型spring.cloud.openfeign.compression.request.min-request-size=2048 #最小触发压缩的大小

​ 我们可以在配置文件中设置一下

server:port: 80
spring:application:name: cloud-consumer-openfeign-order####Spring Cloud Consul for Service Discoverycloud:consul:host: localhostport: 8500discovery:prefer-ip-address: true #优先使用服务ip进行注册service-name: ${spring.application.name}openfeign:client:config:
#            default:
#             connectTimeout: 3000            #连接超时时间
#             readTimeout: 3000             #读取超时时间cloud-payment-service:connectTimeout: 5000readTimeout: 5000httpclient:hc5:enabled: truecompression:request:enabled: truemin-request-size: 2048 #最小触发压缩的大小mime-types: text/xml,application/xml,application/json #触发压缩数据类型response:enabled: true

​ 压缩效果在日志打印功能中展现…

4.5、OpenFeign日志打印功能

​ Feign 提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解 Feign 中 Http 请求的细节,说白了就是对Feign接口的调用情况进行监控和输出。

日志级别

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

官网说明:

image-20240313204326264

image-20240313204046193

​ 我们在FeignConfig中可以配置日志,注意导包要导feign的。

@Configuration
public class FeignConfig {@Beanpublic Retryer myRetryer(){return Retryer.NEVER_RETRY; //Feign默认配置是不走重试策略的//最大请求次数为(1+2)次,初始时间间隔为100ms,重试最大间隔时间为1秒//return new Retryer.Default(100,1,3);}@BeanLogger.Level feignLoggerLevel() {return Logger.Level.FULL;}
}

​ 然后在配置文件中开启日志的Feign客户端。

​ 这里有一个套路可以这样写:

公式(三段):logging.level + 含有@FeignClient注解的完整带包名的接口名+debug

完整的application.yml

server:port: 80
spring:application:name: cloud-consumer-openfeign-order####Spring Cloud Consul for Service Discoverycloud:consul:host: localhostport: 8500discovery:prefer-ip-address: true #优先使用服务ip进行注册service-name: ${spring.application.name}openfeign:client:config:
#            default:
#             connectTimeout: 3000            #连接超时时间
#             readTimeout: 3000             #读取超时时间cloud-payment-service:connectTimeout: 5000readTimeout: 5000httpclient:hc5:enabled: truecompression:request:enabled: truemin-request-size: 2048 #最小触发压缩的大小mime-types: text/xml,application/xml,application/json #触发压缩数据类型response:enabled: true# feign日志以什么级别监控哪个接口
logging:level:com:zm:cloud:apis:PayFeignApi: debug 

​ 现在可以开始测试了,重启服务测试。

image-20240313205737543

​ 我们可以看到开了压缩和没开压缩的还是有些差别的,没开请求响应压缩看不到任何的请求响应信息。

重试机制控制台看到3次过程

​ 现在有了日志打印功能就可以看到具体的3次重试过程了。

​ 先把重试功能打开,为了快速展示我们把超时时间改成1秒,那么一会儿总时间应该是3秒。

@Configuration
public class FeignConfig {@Beanpublic Retryer myRetryer(){//return Retryer.NEVER_RETRY; //Feign默认配置是不走重试策略的//最大请求次数为(1+2)次,初始时间间隔为100ms,重试最大间隔时间为1秒return new Retryer.Default(100,1,3);}@BeanLogger.Level feignLoggerLevel() {return Logger.Level.FULL;}
}

​ 重启服务开始测试。
image-20240313210815882

相关文章:

OpenFeign服务接口调用

OpenFeign服务接口调用 1、OpenFeign简介 ​ Feign是一个声明性web服务客户端。它使编写web服务客户端变得更容易。使用Feign创建一个接口并对其进行注释。它具有可插入的注释支持&#xff0c;包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。Spring Cloud添加…...

SQLiteC/C++接口详细介绍之sqlite3类(五)

快速跳转文章列表&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;四&#xff09; 下一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;六&#xff09;&#xff08;未发表&#xff09; 14.sqlite3_busy_handle…...

Linux 之二:CentOS7 的 IP 常用命令和配置及 xshell 基本使用方法

1. 进入虚拟机 点击右键---进入终端--输入 ip adrr 或 ifconfig 查看ip地址 下面输入命令 ifconfig&#xff08;注意&#xff1a;不是 ipconfig &#xff09; 或 ip addr 来查看当前系统 IP 查看到IP 后&#xff0c;比如&#xff1a;上面是 192.168.184.137 1.1 IP 常用命令…...

24-Java策略模式 ( Strategy Pattern )

Java策略模式 摘要实现范例 策略模式的重心不是如何实现算法&#xff0c;而是如何组织、调用这些算法&#xff0c;从而让程序结构更加灵活&#xff0c;具有更好的维护性和扩展性。 策略模式属于行为型模式 摘要 1. 意图 针对一组算法&#xff0c;将每一个算法封装到具有共…...

突破编程_C++_C++11新特性(模板的改进与细节)

1 模板右尖括号的改进 在 C11 之前&#xff0c;模板的解析和实例化过程中&#xff0c;右尖括号 > 的处理有时会导致一些意外的结果&#xff0c;特别是在嵌套模板或模板模板参数中。这是因为 C 编译器通常会试图“查看前方”来确定何时结束模板参数的列表&#xff0c;这有时…...

云原生消息流系统 Apache RocketMQ 在腾讯云的大规模生产实践

导语 随着云计算技术的日益成熟&#xff0c;云原生应用已逐渐成为企业数字化转型的核心驱动力。在这一大背景下&#xff0c;高效、稳定、可扩展的消息流系统显得尤为重要。腾讯云高级开发工程师李伟先生&#xff0c;凭借其深厚的技术功底和丰富的实战经验&#xff0c;为我们带…...

Node.js的事件驱动模型(非阻塞I/O)

Node.js的事件驱动模型是它能高效处理并发的关键。这个模型允许Node.js在单个线程上运行&#xff0c;同时通过非阻塞I/O操作来处理成千上万的并发连接。下面是对Node.js事件驱动模型的详细解释&#xff1a; 事件循环&#xff08;Event Loop&#xff09; 事件循环是Node.js事件…...

java过滤器Filter相关知识点汇总

1.Filter概述 Servlet Filter又称Servlet过滤器&#xff0c;它是在Servlet2.3规范中定义的&#xff0c;能够对Servlet容器传给Web资源的request对象和response对象执行检查和修改。 Filter不是Servlet&#xff0c;不能直接访问&#xff0c;其本身也不能生成request对象和resp…...

旅游景区公共广播 园区广播 公路服务区广播

旅游景区公共广播 园区广播 公路服务区广播 旅游景区公共广播 旅游景区公共广播(又称背景音乐)简称BGM&#xff0c;它的主要作用是掩盖噪声并创造一种轻松和谐的气氛&#xff0c;是一种创造轻松愉快环境气氛的音乐。掩盖环境噪声&#xff0c;创造与旅游景区相适应的气氛&#…...

Elastic Stack--09--ElasticsearchRestTemplate

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 spring-data-elasticsearch提供的APIQueryBuildersElasticsearchRestTemplate 方法ElasticsearchRestTemplate ---操作索引 ElasticsearchRestTemplate ---文档操作…...

论坛管理系统|基于Spring Boot+ Mysql+Java+B/S架构的论坛管理系统设计与实现(可运行源码+数据库+设计文档+部署说明+视频演示)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 目录 前台功能效果图 管理员功能登录前台功能效果图 用户功能模块 系统功能设计 数据库E-R图设计 l…...

2022 Task 2 Max Sum of 2 integers sharing first and last digits

Task 2 There is an array A consisting of N integers. What’s the maximum sum of two integers from A that share their first and last digits? For example, 1007 and 167 share their first(1) and last(7) digits, whereas 2002 and 55 do not. Write a function: …...

【分布式websocket】聊天系统消息加密如何做

前言 先介绍一下对称加密算法&#xff0c;在介绍一下加密流程&#xff0c;然后是介绍一下查询加密消息的策略。然后结合现有技术架构然后去选型。 决定采用客户端解密。简而言之就是采用对称服务端加密。然后将加密内容存储到消息表的content字段。然后客户拉取content字段 然…...

网络建设与运维培训介绍和能力介绍

1.开过的发票 3.培训获奖的证书 4合同签署 5.实训设备...

3 种方法限制 K8s Pod 磁盘容量使用

容器在运行期间会产生临时文件、日志。如果没有任何配额机制&#xff0c;则某些容器可能很快将磁盘写满&#xff0c;影响宿主机内核和所有应用。 容器的临时存储&#xff0c;例如 emptyDir&#xff0c;位于目录/var/lib/kubelet/pods 下&#xff1a; /var/lib/kubelet/pods/ …...

05-ESP32-S3-IDF USART

ESP32-S3 IDF USART详解 USART简介 USART是一种串行通信协议&#xff0c;广泛应用于微控制器和计算机之间的通信。USART支持异步和同步模式&#xff0c;因此它可以在没有时钟信号的情况下&#xff08;异步模式&#xff09;或有时钟信号的情况下&#xff08;同步模式&#xff…...

安塔利斯升级php8

1、includes/classes/class.Database.php 255行 multi_query方法加返回类型 :bool query方法加返回类型&#xff1a;: mysqli_result|bool 2、includes/classes/class.Session.php on line 91 Optional parameter $planetID declared before required parameter $dpath is…...

Clickhouse MergeTree 原理(一)

作者&#xff1a;俊达 MergeTree是Clickhouse里最核心的存储引擎。Clickhouse里有一系列以MergeTree为基础的引擎&#xff08;见下图&#xff09;&#xff0c;理解了基础MergeTree&#xff0c;就能理解整个系列的MergeTree引擎的核心原理。 本文对MergeTree的基本原理进行介绍…...

【C语言】字符串函数上

&#x1f451;个人主页&#xff1a;啊Q闻 &#x1f387;收录专栏&#xff1a;《C语言》 &#x1f389;道阻且长&#xff0c;行则将至 前言 这篇博客是字符串函数上篇&#xff0c;主要是关于长度不受限制的字符串函数&#xff08;strlen,strcpy,strcat,strcm…...

Java集合基础知识总结(绝对经典)

List接口继承了Collection接口&#xff0c;定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理&#xff0c;还添加了面向位置的操作。 实际上有两种list&#xff1a;一种是基本的ArrayList&#xff0c;其优点在于随机访问元素&#xff0c;另一种是更强大的L…...

原生js操作元素类名(classList,classList.add...)

1、classList classList属性是一个只读属性&#xff0c;返回元素的类名&#xff0c;作为一个DOMTokenList集合(用于在元素中添加&#xff0c;移除及切换css类) length:返回类列表中类的数量&#xff0c;该属性是只读的 <style> .lis { width: 200px; …...

web3-以太坊智能合约基础(理解智能合约Solidity)

以太坊智能合约基础&#xff08;理解智能合约/Solidity&#xff09; 无需编程经验&#xff0c;也可以帮助你了解Solidity独特的部分&#xff1b;如果本身就有相应的编程经验如java&#xff0c;python等那么学起来也会非常的轻松 一、Solidity和EVM字节码 实际上以太坊链上储存…...

Simplicity studio SDK下载和安装,创建工程

下载SDK工具地址 Simplicity Studio - Silicon Labs 选择适合自己电脑的版本。 这个就使用你自己的邮箱注册一个就可以了&#xff0c;我是用的公司邮箱注册的。 下载完成&#xff1a; 安装 下载完成后右键点击安装&#xff0c;一路下一步 安装完成后&#xff0c;程序自动打…...

PyQt实现3维数组与界面TableWidget双向绑定

以下是一个使用PyQt实现3维数组与界面TableWidget双向绑定的示例代码。该程序包含一个下拉菜单选择第0维索引&#xff0c;表格展示第1维和第2维的数据&#xff0c;并支持双向数据同步&#xff1a; import sys import numpy as np from PyQt5.QtWidgets import (QApplication, …...

深度学习姿态估计实战:基于ONNX Runtime的YOLOv8 Pose部署全解析

本文将详细介绍如何脱离YOLO官方环境&#xff0c;使用ONNX Runtime部署YOLOv8姿态估计模型。内容包括模型加载、图像预处理&#xff08;Letterbox缩放和填充&#xff09;、推理执行、输出解码&#xff08;边界框和关键点处理&#xff09;、非极大值抑制&#xff08;NMS&#xf…...

Java高效批量读取Redis数据:原理、方案与实战案例

Java高效批量读取Redis数据&#xff1a;原理、方案与实战案例 在电商大促场景中&#xff0c;某平台需要实时展示用户购物车数据&#xff0c;面对每秒10万的请求&#xff0c;传统单次读取Redis的方式导致响应延迟高达500ms。通过批量读取优化&#xff0c;最终将延迟降至20ms以内…...

在 CentOS 上安装 Docker 和 Docker Compose 并配置使用国内镜像源

在 CentOS 上安装 Docker 和 Docker Compose 并配置使用国内镜像源&#xff0c;可以加速镜像下载速度。以下是详细的步骤&#xff1a; 一、安装 Docker 移除旧版本的 Docker&#xff08;如果有&#xff09;&#xff1a; sudo yum remove docker \docker-client \docker-client…...

从0开始学vue:pnpm怎么安装

一、什么是 pnpm&#xff1f; pnpm&#xff08;Performant npm&#xff09;是新一代 JavaScript 包管理器&#xff0c;优势包括&#xff1a; 节省磁盘空间&#xff1a;通过硬链接和符号链接实现高效存储安装速度更快&#xff1a;比 npm/yarn 快 2-3 倍内置工作区支持&#xf…...

[yolov11改进系列]基于yolov11引入注意力机制SENetV1或者SENetV2的python源码+训练源码

本文给大家带来的改进机制是SENet&#xff08;Squeeze-and-Excitation Networks&#xff09;其是一种通过调整卷积网络中的通道关系来提升性能的网络结构。SENet并不是一个独立的网络模型Q&#xff0c;而是一个可以和现有的任何一个模型相结合的模块&#xff08;可以看作是一种…...

CppCon 2015 学习:CLANG/C2 for Windows

Visual Studio 2015 引入了基于 CLANG/LLVM 的新代码生成器&#xff0c;及其背景和意义。简单理解如下&#xff1a; 理解要点&#xff1a; VS2015 中引入了全新的代码生成技术&#xff0c;性能和质量都很棒。这套新技术基于 Clang&#xff0c;微软展示了相关新工具。Clang 和…...