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、使用
架构说明图:

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.

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

添加一个数据

查询全部

删除刚才新增的

下面测试负载均衡

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

在使用Feign进行微服务间的通信时,当发出一个请求到PayFeignApi接口时,该请求实际上是通过Feign客户端进行代理的。Feign会根据你提供的@FeignClient(value = "cloud-payment-service")注解中的value值(即服务名)来定位目标服务。
当请求到达PayFeignApi接口时大致流程:
- 路由到目标服务:Feign会根据我们在注解上填的微服务名称去注册中心(consul)找有没有这个微服务,然后找到这个微服务下的具体示例列表,因为Feign本身就有负载均衡能力,默认还是轮询的方式进行调度。
- 选择具体的端点:选择完目标示例之后,Feign会根据你定义的路径(/pay/add)来拼凑完整的URL,比如说选择了8001,那么URL就是:http://localhost:8001/pay/add;
- 发送请求:URL拿到后,Feign就使用HTTP客户端发送请求到服务提供者,然后就是具体的处理请求了,至此整个服务流程完成。
4、OpenFeign高级特性
4.1、OpenFeign超时控制
在Spring Cloud微服务架构中,大部分公司都是利用OpenFeign进行服务间的调用,而比较简单的业务使用默认配置是不会有多大问题的,但是如果是业务比较复杂,服务要进行比较繁杂的业务计算,那后台很有可能会出现Read Timeout这个异常,因此定制化配置超时时间就有必要了。

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关闭。

所以说,OpenFeign的默认超时时间是60秒,所以故意弄的睡眠时间就是60秒以上。
默认OpenFeign客户端等待60秒钟,但是服务端处理超过规定时间会导致Feign客户端返回报错。
为了避免这样的情况,有时候我们需要设置Feign客户端的超时控制,默认60秒太长或者业务时间太短都不好。
这就需要在yml中开始配置了:
connectTimeout 连接超时时间readTimeout 请求处理超时时间
官网默认配置参数

全局配置
在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服务测试一下:

有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
再次测试

结果是5秒,所以自己指点的时间就会覆盖掉默认设置的时间。
4.2、OpenFeign重试机制
OpenFeign的重试机制默认是关闭的

想开启重试就新增一个配置类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秒

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

我们先把超时重试的配置关闭。
@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
重启再看一下现在报错信息来至于哪里

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 中定义的信息之外,还有请求和响应的正文及元数据。
官网说明:


我们在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
现在可以开始测试了,重启服务测试。

我们可以看到开了压缩和没开压缩的还是有些差别的,没开请求响应压缩看不到任何的请求响应信息。
重试机制控制台看到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;}
}
重启服务开始测试。

相关文章:
OpenFeign服务接口调用
OpenFeign服务接口调用 1、OpenFeign简介 Feign是一个声明性web服务客户端。它使编写web服务客户端变得更容易。使用Feign创建一个接口并对其进行注释。它具有可插入的注释支持,包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。Spring Cloud添加…...
SQLiteC/C++接口详细介绍之sqlite3类(五)
快速跳转文章列表:SQLite—系列文章目录 上一篇:SQLiteC/C接口详细介绍之sqlite3类(四) 下一篇:SQLiteC/C接口详细介绍之sqlite3类(六)(未发表) 14.sqlite3_busy_handle…...
Linux 之二:CentOS7 的 IP 常用命令和配置及 xshell 基本使用方法
1. 进入虚拟机 点击右键---进入终端--输入 ip adrr 或 ifconfig 查看ip地址 下面输入命令 ifconfig(注意:不是 ipconfig ) 或 ip addr 来查看当前系统 IP 查看到IP 后,比如:上面是 192.168.184.137 1.1 IP 常用命令…...
24-Java策略模式 ( Strategy Pattern )
Java策略模式 摘要实现范例 策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更加灵活,具有更好的维护性和扩展性。 策略模式属于行为型模式 摘要 1. 意图 针对一组算法,将每一个算法封装到具有共…...
突破编程_C++_C++11新特性(模板的改进与细节)
1 模板右尖括号的改进 在 C11 之前,模板的解析和实例化过程中,右尖括号 > 的处理有时会导致一些意外的结果,特别是在嵌套模板或模板模板参数中。这是因为 C 编译器通常会试图“查看前方”来确定何时结束模板参数的列表,这有时…...
云原生消息流系统 Apache RocketMQ 在腾讯云的大规模生产实践
导语 随着云计算技术的日益成熟,云原生应用已逐渐成为企业数字化转型的核心驱动力。在这一大背景下,高效、稳定、可扩展的消息流系统显得尤为重要。腾讯云高级开发工程师李伟先生,凭借其深厚的技术功底和丰富的实战经验,为我们带…...
Node.js的事件驱动模型(非阻塞I/O)
Node.js的事件驱动模型是它能高效处理并发的关键。这个模型允许Node.js在单个线程上运行,同时通过非阻塞I/O操作来处理成千上万的并发连接。下面是对Node.js事件驱动模型的详细解释: 事件循环(Event Loop) 事件循环是Node.js事件…...
java过滤器Filter相关知识点汇总
1.Filter概述 Servlet Filter又称Servlet过滤器,它是在Servlet2.3规范中定义的,能够对Servlet容器传给Web资源的request对象和response对象执行检查和修改。 Filter不是Servlet,不能直接访问,其本身也不能生成request对象和resp…...
旅游景区公共广播 园区广播 公路服务区广播
旅游景区公共广播 园区广播 公路服务区广播 旅游景区公共广播 旅游景区公共广播(又称背景音乐)简称BGM,它的主要作用是掩盖噪声并创造一种轻松和谐的气氛,是一种创造轻松愉快环境气氛的音乐。掩盖环境噪声,创造与旅游景区相适应的气氛&#…...
Elastic Stack--09--ElasticsearchRestTemplate
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 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】聊天系统消息加密如何做
前言 先介绍一下对称加密算法,在介绍一下加密流程,然后是介绍一下查询加密消息的策略。然后结合现有技术架构然后去选型。 决定采用客户端解密。简而言之就是采用对称服务端加密。然后将加密内容存储到消息表的content字段。然后客户拉取content字段 然…...
网络建设与运维培训介绍和能力介绍
1.开过的发票 3.培训获奖的证书 4合同签署 5.实训设备...
3 种方法限制 K8s Pod 磁盘容量使用
容器在运行期间会产生临时文件、日志。如果没有任何配额机制,则某些容器可能很快将磁盘写满,影响宿主机内核和所有应用。 容器的临时存储,例如 emptyDir,位于目录/var/lib/kubelet/pods 下: /var/lib/kubelet/pods/ …...
05-ESP32-S3-IDF USART
ESP32-S3 IDF USART详解 USART简介 USART是一种串行通信协议,广泛应用于微控制器和计算机之间的通信。USART支持异步和同步模式,因此它可以在没有时钟信号的情况下(异步模式)或有时钟信号的情况下(同步模式ÿ…...
安塔利斯升级php8
1、includes/classes/class.Database.php 255行 multi_query方法加返回类型 :bool query方法加返回类型:: mysqli_result|bool 2、includes/classes/class.Session.php on line 91 Optional parameter $planetID declared before required parameter $dpath is…...
Clickhouse MergeTree 原理(一)
作者:俊达 MergeTree是Clickhouse里最核心的存储引擎。Clickhouse里有一系列以MergeTree为基础的引擎(见下图),理解了基础MergeTree,就能理解整个系列的MergeTree引擎的核心原理。 本文对MergeTree的基本原理进行介绍…...
【C语言】字符串函数上
👑个人主页:啊Q闻 🎇收录专栏:《C语言》 🎉道阻且长,行则将至 前言 这篇博客是字符串函数上篇,主要是关于长度不受限制的字符串函数(strlen,strcpy,strcat,strcm…...
Java集合基础知识总结(绝对经典)
List接口继承了Collection接口,定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理,还添加了面向位置的操作。 实际上有两种list:一种是基本的ArrayList,其优点在于随机访问元素,另一种是更强大的L…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
