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

【Spring Cloud Alibaba】(三)OpenFeign扩展点实战 + 源码详解

CSDN成就一亿技术人

系列目录

【Spring Cloud Alibaba】(一)微服务介绍 及 Nacos注册中心实战
【Spring Cloud Alibaba】(二)微服务调用组件Feign原理+实战


本文目录

  • 系列目录
  • 前言
  • 一、Feign扩展点配置
  • 二、OpenFeign扩展点配置
    • 1. 通过配置文件配置
      • 有效范围说明
      • 验证是否生效
    • 2. 通过Java Bean配置
      • 有效范围说明
      • 验证是否生效
    • 补充说明1. 日志级别
    • 补充说明2. 契约contract
    • 补充说明3. 编解码器
    • 补充说明4. 拦截器
    • 补充说明5. 配置Client
      • 1). 配置Client为Apache HttpClient
      • 2). 配置Client为OkHttp
    • 补充说明6. 配置GZIP压缩
    • 小结
  • 三、源码解读
    • 1. 注册流程
    • 2. 扩展点配置主逻辑
    • 3. 配置文件源头
    • 4. Java Bean配置源头
  • 最后


前言

书接上文,我们掌握了Feign的基本使用、核心原理,以及Spring Cloud Alibaba如何快速整合Feign,真的太简单了!你是不是觉得这样就够了?但在实际项目使用OpenFeign时,我们常常会遇到各种需求,需要用到它提供的扩展,例如日志分析、自定义统一拦截器、客户端组件配置、GZIP压缩等等,这也正是我接下来在本文中分享的内容:首先我会从原生Feign扩展点配置入手,然后进行OpenFeign扩展点配置实战,最后对OpenFeign是如何实现的进行了源码解读,内容很详细,Let’s go!


一、Feign扩展点配置

在上文,我们主要讲解了架构图的上部和下部,本文主要针对架构图中间扩展部分
在这里插入图片描述

Feign本身提供了很多扩展点,例如:

  • 日志级别logLevel
  • 契约contract
  • 客户端client
  • 超时设置options
  • 编码器encoder
  • 解码器decoder
  • 拦截器requestInterceptor

这些扩展点,我们在使用原生Feign时,可以通过Feign.Builder指定,最后再通过target生成动态代理类,完成Bean注册。
Feign.Builder

举个例子:

@Bean
public UserService userService() {return Feign.builder().logLevel(Logger.Level.BASIC).contract(new Contract.Default()).client(new Client.Default(null, null)).encoder(new Encoder.Default()).decoder(new Decoder.Default()).target(UserService.class, "http://demo-b");
}

二、OpenFeign扩展点配置

通过上文的OpenFeign实战,我们很容易搭建出Spring Cloud Alibaba微服务框架,并实现服务之间通过OpenFeign调用。如果还未看过上文的同学,建议先看上文:【Spring Cloud Alibaba】(二)微服务调用组件Feign原理+实战

我这里准备了3个Spring Cloud Alibaba微服务:demo-ademo-bdemo-c,之所以准备3个服务是为了验证配置是全局有效还是局有效!
OpenFeign扩展点Demo的3个服务

在OpenFeign中扩展配置项,可以通过配置文件Java Bean两种方式,接下来我们就配置试试看!

1. 通过配置文件配置

application.properties格式:

feign.client.config.{服务名}.{配置名} = {配置值} 

我们配置一些你可能用的上的扩展项,比如:日志级别配置契约配置超时配置编解码配置拦截器配置,如下:

# 日志级别配置
feign.client.config.default.loggerLevel = BASIC
# 契约配置
feign.client.config.default.contract = feign.Contract.Default
# 连接超时配置
feign.client.config.default.connectTimeout = 5000
# 读取超时配置
feign.client.config.default.readTimeout = 30000
# 编码器配置
feign.client.config.default.encoder = feign.jackson.JacksonEncoder
# 解码器配置
feign.client.config.default.decoder = feign.jackson.JacksonDecoder
# 拦截器配置, 是数组, 需要自定义RequestInterceptor
feign.client.config.default.requestInterceptors[0]=com.tiangang.demo.c.interceptor.MyFeignRequestInterceptor

有效范围说明

  • 全局生效:配置 {服务名}default ,如上面例子中所示
  • 局部生效:配置 {服务名}具体服务名
    例如,下面的配置仅对调用demo-b服务有效。
  feign.client.config.demo-b.loggerLevel = BASIC

验证是否生效

你知道如何快速验证吗?

挨个试?😏😏😏 教你一个简单有效的方法:

我使用demo-c发起调用,可以在启动demo-c 启动服务 时,构建 动态代理前 打断点查看Feign.Builder

即在FeignClientFactoryBean.loadBalance方法的调target之前打断点:
FeignClientFactoryBean.loadBalance打断点查看Feign.Builder

  • 配置后的Feign.Builder,确认已经按application.properties配置:

Feign.Builder查看调试属性-已配置

  • 如果未配置,默认Feign.Builder如下:

Feign.Builder查看调试属性-未配置

对于是全局还是局部有效,我是确认过的,因为不好演示,所以大家有兴趣可以自行验证确认!

2. 通过Java Bean配置

通过Java代码配置的话需要定义一个配置类,例如我命名为:FeignConfig,里面定义需要配置的@Bean,与上面配置文件的配置项保持一致!为了做区分,这里将编解码器改为Gson。

public class FeignConfig {// 日志级别配置@Beanpublic Logger.Level feignLoggerLevel() {return Logger.Level.BASIC;}// 契约配置@Beanpublic Contract feignContract() {return new Contract.Default();}// 超时配置@Beanpublic Request.Options options() {return new Request.Options(5000, 30000);}// 编解码器配置Jackson/*@Beanpublic Encoder encoder() {return new JacksonEncoder();}@Beanpublic Decoder decoder() {return new JacksonDecoder();}*/// 编解码器配置Gson@Beanpublic Encoder encoder() {return new GsonEncoder();}@Beanpublic Decoder decoder() {return new GsonDecoder();}// 拦截器配置@Beanpublic MyFeignRequestInterceptor myFeignRequestInterceptor() {return new MyFeignRequestInterceptor();}
}

有效范围说明

  • 全局生效(扫描到的所有服务),两种方式:
    • 1.在FeignConfig上加@Configuration注解(需要保证能扫描到)
    • 2.在启动类的@EnableFeignClients注解中配置defaultConfiguration
@EnableFeignClients(defaultConfiguration = FeignConfig.class) 
  • 局部生效(指定服务):在接口API的@FeignClient注解中配置
@FeignClient(value = "demo-b", configuration = FeignConfig.class)

验证是否生效

这里直接到FeignClientFactoryBean.loadBalance方法的target生成动态代理之前打断点查看:

  • Java Bean配置后的Feign.Builder
    Java Bean配置后的Feign.Builder

对于是全局还是局部有效,我是确认过的,因为不好演示,所以大家有兴趣可以自行验证确认!

补充说明1. 日志级别

Feign提供了4种日志级别

日志级别简单说明
NONE默认值,不记录日志
BASIC记录请求方法、请求URL、响应状态代码、执行时间
HEADERS在BASIC级别的基础上,记录请求和响应的header
FULL记录全部日志:请求和响应的header、body和metadata

注意: 若要正常输出日志,需要配置接口包路径的日志级别,我这里是com.tiangang.demo.api,所以 application.properties 配置:

# 格式:logging.level.{feign接口包路径}=debug/info...
logging.level.com.tiangang.demo.api=debug

在这里插入图片描述

补充说明2. 契约contract

在OpenFeign下,大部分情况下不需要配置contract,但如果老项目已经定义了大量的feign注解,那么就没必要再改成SpringMvc注解了,直接改contract是个好办法!

OpenFeign的默认contract是SpringMvcContract,即支持SpringMvc注解。

如果修改为feign.Contract.Default,测试时别忘了加feign注解,否则会编译报错。

补充说明3. 编解码器

使用Jackson,需要引入依赖:

<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-jackson</artifactId>
</dependency>

使用Gson,需要引入依赖:

<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-gson</artifactId>
</dependency>

Gsonapplication.properties配置:

feign.client.config.default.encoder = feign.gson.GsonEncoder
feign.client.config.default.decoder = feign.gson.GsonDecoder

Feign本身还提供了很多编解码器,需要的话可以直接用,如下图:
Feign源码:Decoder实现类

当然了,你也可以自定义编解码器!

补充说明4. 拦截器

拦截器是 非常有用的扩展点,是我们实现定制化需求的利器!

当我们需要统一处理Header、处理请求参数、处理响应结果时,就可以通过自定义拦截器处理。

Feign默认提供了Basic 认证拦截器,我们可以直接配置使用:

public class FeignConfig {@Beanpublic BasicAuthRequestInterceptor basicAuthRequestInterceptor() {return new BasicAuthRequestInterceptor("userName", "password");}
}

另外,我们也可以自定义 ,只需要实现接口RequestInterceptor

public interface RequestInterceptor {/*** Called for every request. Add data using methods on the supplied {@link RequestTemplate}.*/void apply(RequestTemplate template);
}

例如,上面的例子我自定义实现的拦截器如下:

public class MyFeignRequestInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate template) {template.header("ACCESS_KEY", "9ZIpCT02u2ctppiXOzbpwBWMtRKPgxKe");}
}

例子的拦截器就是统一加了一个ACCESS_KEY的header,当你的调用需要统一加header时,就可以使用拦截器实现。当然,不仅用于加header!下面的GZIP压缩就是通过拦截器实现的!

补充说明5. 配置Client

除了上面提到的通用配置方式外,OpenFeign提供了专门的FeignAutoConfiguration,里面包含对Client等的配置,帮助我们快速配置Client。

在OpenFeign中,默认的Client是JDK原生的URLConnection,接下来,我们就实战 快速配置Apache HttpClientOkHttp

1). 配置Client为Apache HttpClient

  • 引入依赖
<!-- Apache HttpClient-->
<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId>
</dependency>
<!-- Feign集成Apache HttpClient -->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId>
</dependency>
  • 配置文件中启用

application.properties

feign.httpclient.enabled=true

参考源码: FeignAutoConfiguration.HttpClientFeignConfiguration
OpenFeign源码:FeignAutoConfiguration.HttpClientFeignConfiguration源码头部

验证已经生效:
Feign验证已配置Client为HttpClient

2). 配置Client为OkHttp

  • 引入依赖
<!-- okhttp -->
<dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId>
</dependency>
<!-- Feign集成okhttp -->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-okhttp</artifactId>
</dependency>
  • 配置文件中启用

application.properties

feign.httpclient.enabled=false
feign.okhttp.enabled=true

参考源码: FeignAutoConfiguration.OkHttpFeignConfiguration
OpenFeign源码:FeignAutoConfiguration.OkHttpFeignConfiguration源码头部

验证已经生效:
Feign验证已配置Client为OkHttp

补充说明6. 配置GZIP压缩

在大数据量HTTP传输时,开启压缩可以有效节约网络资源,提升接口性能,我们可以配置 GZIP 来压缩数据,这也是OpenFeign通过自定义拦截器为我们实现的扩展功能。

application.properties

# 请求数据压缩
feign.compression.request.enabled=true
# 压缩类型
feign.compression.request.mimeTypes=text/xml,application/xml,application/json
# 启用压缩的最小大小(默认是2048),这里为了测试配置成1
feign.compression.request.minRequestSize=1
# 响应数据压缩
feign.compression.response.enabled=true

配置项参考源码: FeignClientEncodingProperties
OpenFeign源码:FeignClientEncodingProperties头部
压缩条件判断逻辑:

  • 请求 必须 有header:Content-Type ,并且在配置的mimeTypes
  • 请求 必须 有header:Content-Length,并且大于配置的minRequestSize

OpenFeign源码:GZIP压缩条件判断逻辑

我这里准备了一个POST请求,请求json,返回json,日志级别我改为了FULL验证已经生效:
OpenFeign:验证GZIP已生效

注意: 只有当Feign的Client 不是 okhttp3.OkHttpClient 的时候,压缩配置才会生效,因为请求和响应的源码中有要求!如下:

  • 参考源码: FeignContentGzipEncodingAutoConfiguration
    OpenFeign源码: FeignContentGzipEncodingAutoConfiguration

  • 参考源码:FeignAcceptGzipEncodingAutoConfiguration
    OpenFeign源码:FeignAcceptGzipEncodingAutoConfiguration

老方法,我们也可以打断点看下GZIP压缩的拦截器:
验证Feign的GZIP拦截器

小结

配置项application.propertiesJava配置对象
日志级别logLevelfeign.client.config.default.loggerLevel = BASIC@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.BASIC;
}
契约contractfeign.client.config.default.contract = feign.Contract.Default@Bean
public Contract feignContract() {
return new Contract.Default();
}
超时设置optionsfeign.client.config.default.connectTimeout = 5000
feign.client.config.default.readTimeout =30000
@Bean
public Request.Options options() {
return new Request.Options(5000, 30000);
}
编解码器encoder&decoderfeign.client.config.default.encoder = feign.jackson.JacksonEncoder
feign.client.config.default.decoder = feign.jackson.JacksonDecoder
@Bean
public Encoder encoder() {
return new JacksonEncoder();
}
@Bean
public Decoder decoder() {
return new JacksonDecoder();
}
拦截器requestInterceptors#是数组,可以按下标配置多个
feign.client.config.default.requestInterceptors[0]=
com.tiangang.demo.api.interceptor.MyFeignRequestInterceptor
@Bean
public MyFeignRequestInterceptor myFeignRequestInterceptor() {
return new MyFeignRequestInterceptor();
}
Client#配置为ApacheHttpClient, 别忘了引入依赖
feign.httpclient.enabled=true

#配置为OkHttp, 别忘了引入依赖
feign.httpclient.enabled=false
feign.okhttp.enabled=true
GZIP压缩#当Feign的Client 不是 okhttp3.OkHttpClient 的时生效。
# 请求数据压缩
feign.compression.request.enabled=true
# 压缩类型
feign.compression.request.mimeTypes=text/xml,application/xml,application/json
# 启用压缩的最小大小(默认是2048)
feign.compression.request.minRequestSize=2048
# 响应数据压缩
feign.compression.response.enabled=true

三、源码解读

请思考:如果让你来开发设计,你会在哪里做扩展点配置?
思索中

我们先跟进下 注册流程,看看能不能找出扩展点配置是在哪里配置的!

1. 注册流程

回顾上文OpenFeign的实战三步走:

  • 引入依赖:spring-cloud-starter-openfeign
  • 定义远程API接口加@FeignClient注解
  • 启动类加@EnableFeignClients注解

通过这三步走,我们可以断定OpenFeign的核心实现:肯定和@EnableFeignClients注解有关,因为没有其它入口了,这也是SpringBoot整合的惯用套路,所以我们快速跟踪一下主线流程,看它是如何将接口API生成的动态代理类:

  • FeignClientsRegistrar
    @EnableFeignClients上有@Import(FeignClientsRegistrar.class)注解,
    OpenFeign源码:EnableFeignClients
    FeignClientsRegistrar重写的registerBeanDefinitions方法里会扫描所有@FeignClient的接口,并将所有接口注册为FeignClientFactoryBean
    OpenFeign源码:FeignClientsRegistrar扫描@FeignClient注解的接口并注册
  • FeignClientFactoryBean
    FeignClientFactoryBean重写getObject方法,先通过feign方法获取到Feign.Builder,再根据FeignClient.url决定是否走负载均衡loadBalance,不管怎么走,最终都会调用Feign.Builder.target方法生成动态代理对象。
    OpenFeign源码:FeignClientFactoryBean.getObject和getTarget

2. 扩展点配置主逻辑

OK,根据注册流程,主线已经很清晰了,获取到Feign.Builder的地方,正是我们扩展点配置的好地方,实际也确实在这里,如下图:
OpenFeign源码:FeignClientFactoryBean.feign

configureFeign方法:
在这里插入图片描述

红框处就是扩展点配置的主逻辑,如果以application.properties为默认defaultToProperties=true,默认也是true,一般也不会改):

  • 1.配置Java Bean

  • 2.配置properties的default配置(全局)

  • 3.配置properties的当前服务配置(局部)

否则else就反过来!(后配置的优先级自然更高!

3. 配置文件源头

主逻辑中的FeignClientPropertiesproperties 就是application.properties配置文件项的源头,带有@ConfigurationProperties注解,如下图:
OpenFeign源码:FeignClientProperties

从这里就可以看出:具体每项配置是Map类型的config,它的key=服务名value=FeignClientConfiguration

所以在application.properties里配置,均为feign.client.config.{服务名}.{配置名}={配置值}

如果 {服务名} =default,即默认对所有服务有效!否则,仅对配置服务有效!

FeignClientConfiguration中全部可配置的属性如下图:
OpenFeign源码: FeignClientConfiguration中全部可配置的属性

4. Java Bean配置源头

Java Bean配置,主要在主逻辑configureUsingConfiguration方法,另外在构建builder时也算一处,一共有两处,优先级由低到高:

  • FeignClientFactoryBean.feign方法 - 构建
    这里配置必备Bean,下图这5个都有在FeignClientsConfiguration里配置缺省Bean,当然,如果你在指定的FeignConfig中加了自定义@Bean,就会以你配置的为准!
    OpenFeign源码: FeignClientFactoryBean.feign方法 - 构建
  • FeignClientFactoryBean.configureUsingConfiguration方法 - 配置
    主要在这里配置可选Bean,就是下图这些 builder. 设置的,当然,如果你在指定的FeignConfig中加了自定义@Bean,就会以你配置的为准!
    OpenFeign源码: FeignClientFactoryBean.configureUsingConfiguration方法 - 配置

最后

通过本文,我们对OpenFeign的扩展点配置进行了实战,并对源码进行了详细解读,如果你在项目中使用到了OpenFeign,相信这些扩展功能会让你在项目中使用得心应手。 另外需要说明:OpenFeign不仅可以用于微服务之间的调用,还可以用于调用第三方服务,所以应用非常广泛!
至此,OpenFeign的神秘面纱就被我们完全揭开了!
那么接下来,在Spring Cloud Alibaba家族中,还有一位主打高性能RPC调用的组件,就是由阿里巴巴公司开源的,后捐献给Apache 基金会的Dubbo,那么它到底有什么过人之处,会让很多公司从Feign转到Dubbo调用?这也是我计划将在下文分享的内容,如果感觉不错,欢迎订阅本专栏,后面还有更多的【Spring Cloud Alibaba】实战知识陆续放出。

关注我 天罡gg 分享更多干货: https://blog.csdn.net/scm_2008
大家的「关注❤️ + 点赞👍 + 收藏⭐」就是我创作的最大动力!谢谢大家的支持,我们下文见!


相关文章:

【Spring Cloud Alibaba】(三)OpenFeign扩展点实战 + 源码详解

系列目录 【Spring Cloud Alibaba】&#xff08;一&#xff09;微服务介绍 及 Nacos注册中心实战 【Spring Cloud Alibaba】&#xff08;二&#xff09;微服务调用组件Feign原理实战 本文目录系列目录前言一、Feign扩展点配置二、OpenFeign扩展点配置1. 通过配置文件配置有效范…...

面向对象设计原则

在面向对象的设计过程中, 我们要对代码进行一个设计, 从而提高一个软件系统的可维护性和可复用性, 那么遵从面向对象的设计原则&#xff0c;可以在进行设计方案时减少错误设计的产生&#xff0c;从不同的角度提升一个软件结构的设计水平。 面向对象有以下七大原则:1.单一职责原…...

2022年“网络安全”赛项湖南省赛选拔赛 任务书

2022年“网络安全”赛项湖南省赛选拔赛 任务书2022年“网络安全”赛项湖南省赛选拔赛 任务书A模块基础设施设置/安全加固&#xff08;200分&#xff09;B模块安全事件响应/网络安全数据取证/应用安全&#xff08;400分&#xff09;C模块 CTF夺旗-攻击 &#xff08;200分&#x…...

学习笔记:Java 并发编程⑥_并发工具_JUC

若文章内容或图片失效&#xff0c;请留言反馈。 部分素材来自网络&#xff0c;若不小心影响到您的利益&#xff0c;请联系博主删除。 视频链接&#xff1a;https://www.bilibili.com/video/av81461839配套资料&#xff1a;https://pan.baidu.com/s/1lSDty6-hzCWTXFYuqThRPw&am…...

Linux文件隐藏属性(修改与显示):chattr和lsattr

文件除了基本的九个权限以外还有隐藏属性存在&#xff0c;这些隐藏属性对于系统有很大的帮助&#xff0c;尤其是系统安全&#xff08;Security&#xff09;上 chattr&#xff08;配置文件隐藏属性&#xff09; chattr 【-】【ASacdistu】文件或目录名称 选项与参数&#xff1a…...

广东省基层就业补贴

基层就业补贴链接&#xff1a;https://www.gdzwfw.gov.cn/portal/v2/guide/11440309MB2D27065K4440511108001 一.申请条件&#xff1a; 1、劳动者到中小微企业、个体工商户、社会组织等就业&#xff0c;或到乡镇&#xff08;街道&#xff09;、村居社会管理和公共服务岗位就业…...

高压放大器在超声导波钢轨传播中的应用

实验名称&#xff1a;高压放大器在超声导波钢轨传播中的应用研究方向&#xff1a;无损检测测试目的&#xff1a;超声导波具有传播距离远、检测距离长的特点&#xff0c;在钢轨无损检测领域受到越来越多的关注。本文使用有限元仿真方法和现场实验方法&#xff0c;对钢轨各模态超…...

Java字符串常见拼接方式

目录 最常见的方式 StringBuilder.append()和StringBuffer.append() String类下的cocat()方法 String类下的join()方法 StringUtils.join 项目中使用 不建议在 for 循环中使用 “” 进行字符串拼接 通过字符串连接&#xff0c;可以将两个或多个字符串、字符、整数和浮点…...

商城业务:购物车

人生在世如身处荆棘之中&#xff0c;心不动&#xff0c;人不妄动&#xff0c;不动则不伤&#xff1b;如心动则人妄动&#xff0c;伤其身痛其骨&#xff0c;于是体会到世间诸般痛苦。 1、购物车需求 1&#xff09;、需求描述&#xff1a; - 用户可以在登录状态下将商品添加到购…...

计算机网络学习笔记(一)

网络是由若干接点和连接这些结点的链路组成。 多个网络通过路由器互联起来构成覆盖范围更大的互联网。 普通用户通过ISP接入因特网。 基于ISP的三层结构因特网 相隔较远的两台主机间通信可能需要经过多个ISP。 有电路交换&#xff0c;报文交换&#xff0c;分组交换三种交换方…...

【单目标优化算法】烟花优化算法(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

微服务项目【秒杀商品展示及商品秒杀】

登录方式调整 第1步&#xff1a;从zmall-common的pom.xml中移除spring-session-data-redis依赖 注意&#xff1a; 1&#xff09;本次不采用spring-session方式&#xff0c;改用redis直接存储用户登录信息&#xff0c;主要是为了方便之后的jmeter压测&#xff1b; 2&#xff09…...

DIDL3_模型选择、复杂度、过欠拟合的相关概念

模型选择、复杂度、过欠拟合的概念模型选择训练误差和泛化误差验证数据集和测试数据集K-则交叉验证&#xff08;没有足够多数据时使用&#xff09;过拟合和欠拟合模型容量模型容量的影响估计模型容量控制模型容量数据复杂度处理过拟合的方法&#xff08;1&#xff09;&#xff…...

Android 9.0 去除锁屏界面及SystemUI无sim卡拨打紧急电话控件显示功能实现

1.1概述 在9.0的系统rom定制化开发中,关于SystemUI的定制化功能也是比较多的,在SystemUI的锁屏页面和状态栏提示无sim卡拨打紧急电话控件显示等相关提示 的功能中,在有些systemui的定制中是不需要这些功能的,所以需要从systemui中去掉这些功能提示的,这就需要从systemui中…...

AntDB-M设计之内存结构

亚信科技专注通信行业多年&#xff0c;AntDB数据库从诞生开始&#xff0c;就面对通信级的大数据量应用场景挑战&#xff0c;在性能、稳定性、规模化等方面获得了超过10年的通信核心业务系统验证&#xff0c;性能峰值达到每秒百万的通信核心交易量。AntDB-M&#xff08;AntDB内存…...

互联网舆情监测公司监测哪些内容,TOOM北京舆情监测公司

互联网舆情监测公司是一种提供舆情监测、分析和管理服务的公司&#xff0c;其业务主要涉及互联网舆情监测、数据分析、报告撰写、危机处理等方面。这些公司通过使用各种技术和工具&#xff0c;帮助客户监测他们在互联网上的声誉和品牌形象&#xff0c;并提供相应的建议和解决方…...

一篇文章带你熟练使用Ansible中的playbook

目录 一、Playbook的功能 二、YAML 1、简介 2、特点 3、语法简介 4、YAML 列表 5、YAML的字典 三、playbook执行命令 四、 Playbook的核心组件 五、vim 设定技巧 练习 一、Playbook的功能 playbook 是由一个或多个play组成的列表 Playboot 文件使用YAML来写的 二、…...

HashedWheelTimer

序言这种算法是一种轮询算法的优化升级,能够以只有一个Timer的情况下处理大量的定时任务.Begin结合HashedWheelTimer的思想根据自然时间1分钟为例,来做大批量的定时任务触发首先定一个长度为60的数组,数组中存放的是Set集合,集合里面是任务详情.当有定时任务刚来的时候判断是否…...

OPenCV库移植到ARM开发板子上面配置过程

步骤一 1&#xff0c;环境准备去下载opencv官方的源码。 我这里用的是opencv-4.5.5版本的 2&#xff0c;还需要交叉编译工具一般&#xff0c;你交叉编译的工具板子厂家会提供工具&#xff0c;最好还是用板子厂家提供的交叉编译工具&#xff0c;因为我之前编译试过其他的交叉…...

Jenkins实现CI/CD

Jenkins是一个开源的持续集成和持续交付&#xff08;CI/CD&#xff09;解决方案&#xff0c;它可以自动执行构建、测试和部署等任务&#xff0c;从而简化了开发工作流程。本文将详细介绍如何使用Jenkins实现CI/CD。 首先&#xff0c;您需要安装Jenkins并启动它。您可以通过以下…...

如何给img标签里的请求添加自定义header

是这样的需求&#xff0c;有一个web页面&#xff0c;里面图片的上传和预览来自于一个独立的文件服务器&#xff0c;对http的请求需要进行访问权限的设置&#xff0c;就是在请求的header里加一个Authorization的字段。上传好说我用的Axios直接添加一个header就行了&#xff0c;但…...

Linux系统基本概念操作,用户和文件权限管理

常用快捷键和通配符常用快捷键按键作用Ctrld键盘输入结束或退出终端Ctrls暂停当前程序&#xff0c;暂停后按下任意键恢复运行Ctrlz将当前程序放到后台运行&#xff0c;恢复到前台为命令fgCtrla将光标移至输入行头&#xff0c;相当于Home键Ctrle将光标移至输入行末&#xff0c;相…...

数据库中的单表查询和多表查询

一、单表查询素材&#xff1a; 表名&#xff1a;worker-- 表中字段均为中文&#xff0c;比如 部门号 工资 职工号 参加工作 等 CREATE TABLE worker (部门号 int(11) NOT NULL,职工号 int(11) NOT NULL,工作时间 date NOT NULL,工资 float(8,2) NOT NULL,政治面貌 varchar(10) …...

全网详解MyBatis-Plus LambdaQueryWrapper的使用说明以及LambdaQueryWrapper和QueryWapper的区别

文章目录1. 文章引言2. 代码演示3. 分析LambdaQueryWrapper3.1 引入LambdaQueryWrapper的原因3.2 LambdaQueryWrapper和QueryWapper的区别4. 重要总结1. 文章引言 今天在公司写代码时&#xff0c;发现同事使用LambdaQueryWrapper来查询数据&#xff0c;而我一直习惯使用QueryW…...

暴力破解(new)

数据来源 本文仅用于信息安全的学习&#xff0c;请遵守相关法律法规&#xff0c;严禁用于非法途径。若观众因此作出任何危害网络安全的行为&#xff0c;后果自负&#xff0c;与本人无关。 01 暴力破解介绍及应用场景 》暴力破解介绍 》暴力破解字典 GitHub - k8gege/Passwor…...

Android12之apex调试

1.问题在调试libtinyalsa.so中添加log后&#xff0c;但是发现push so后&#xff0c;却没有log打印&#xff0c;why&#xff1f;2.分析以下为libtinyalsa.so的位置/system/lib64/libtinyalsa.so /system/lib/libtinyalsa.so /apex/com.android.vndk.v31/lib64/libtinyalsa.so /a…...

Python - 数字(Number)数据类型常用操作

目录数字运算类型转换数学函数数学库math、cmathmath 模块常量math 模块方法随机函数库 randomrandom 模块方法保留小数到指定位数三角函数数字运算 &#xff1a;用于给变量赋值type(x)&#xff1a;查看数据所属类型isinstance(x, A_tuple)&#xff1a;判断数据是否为预期类型…...

QT(51)-动态链接库-windows

1.qt- 调用win32 DLL 2.qt- 调用MFC DLL 0概述&#xff1a; 01.扩展DLL&#xff1a; 必须有一个DllMain()函数&#xff0c;且调用AfxInitExtensionModule()函数。 CRuntimeClass类-初始化函数CDynLinkLibrary。02.windows定位DLL文件&#xff1a; 1&#xff09…...

[Vivado那些事儿]将自定义 IP (HDL)添加到 Vivado 模块设计(Block Design)

绪论使用Vivado Block Design设计解决了项目继承性问题&#xff0c;但是还有个问题&#xff0c;不知道大家有没有遇到&#xff0c;就是新设计的自定义 RTL 文件无法快速的添加到Block Design中&#xff0c;一种方式是通过自定义IP&#xff0c;但是一旦设计的文件有问题就需要重…...

开学必备数码清单,大学生开学必备数码好物分享

还有很多小伙伴不知道开学应该准备什么&#xff0c;在学校当中需要用到的数码产品&#xff0c;在宿舍娱乐使用的音箱、学习当中使用到的笔记本&#xff0c;这些都是我们可以准备的&#xff0c;还有一个小众的好物&#xff0c;能够让我们在学校当中提升生活的幸福感&#xff0c;…...

福永网站的建设/百度网盘官网登录首页

运行命令 第 1 步&#xff1a;创建网络 docker network create localhost-network --driver bridge第 2 步&#xff1a;启动 Zookeeper 服务器实例 使用命令的–network localhost-network参数docker run将 Zookeeper 容器连接到localhost-network网络。 docker run -d --nam…...

优秀网站h5案例分享/百度营销登录入口

接着etcd的集群&#xff0c;现在用原有环境基础&#xff0c;增加master集群haproxy负载&#xff0c;机器受限 还是用1.5,1.6做master&#xff0c;把haproxy安装在1.5上 一般生产的时候&#xff0c;haproxy master etcd node 还是要分开集群 首先安装haproxy yum install haprox…...

wordpress发表的文章百度抓取失败/厦门百度seo

任务目的&#xff1a; 每点击一下按钮删除一个标签。 掌握到了&#xff1a; 这里是主要学习到了parentNote以及removeChild两个DOM属性。 parentNote:parent英译为父亲&#xff0c;Note英译为节点。顾名思义就是&#xff1a;父节点 removeChild&#xff1a;remove删除&#xff…...

桂林商品房做民宿在哪个网站登记好/软文推广广告

...

有没有专门教做扯面的网站/如何设计一个网页

作者&#xff1a;一一哥 一. Spring之起源 1.你知道J2EE吗&#xff1f; 要说到Spring的历史起源&#xff0c;首先咱们要说说J2EE这个玩意儿。 J2EE在1999年和2000年的时候开始得到广泛实现&#xff0c;在J2EE中提出了”事务管理“等核心中间层标准化的概念&#xff0c;但是在…...

怎么在网站上做404页面/外链工厂

扩展教程 网站备案流程 转载于:https://www.cnblogs.com/Frank99/p/11028060.html...