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

通用多级缓件组件

背景

业界第三方缓存框架一般为redis,本地缓地ehcache或guava,一般通过spring提供的restTemplate操作缓存

然而这样会存在以下问题:

  • 与缓存中间件强耦合
  • 需手动整合多级缓存
  • 不支持注解
  • 数据更新时无法自动刷新缓存
  • 存在缓存穿透、缓存击穿、缓存雪崩风险
  • 日志不足

改造方案

基于上述问题,针对每点问题提出修复/优化方案:

1、与缓存中间件强耦合

对外仅暴露一个接口cacheService操作缓存,调用方无需关心内部实现,但需要通过配置开启第三方缓存

2、需手动整合多级缓存

自动整合两级缓存,redis + guava

3、不支持注解

增加自定义注解

4、数据更新时无法自动刷新缓存(未实现)

使用阿里开源框架canal监听mysql的binlog日志,将变更通过MQ广播到消费端,由消费端实时更新缓存:

1)MQ划分两个组:集群组与机器组,分别用于处理第三方缓存刷新(只需一台机器处理)和本地缓存刷新(每台机器都要处理)

2)canal收到binlog变更后,发送一条消息到集群组

3)收到消息的机器先判断缓存是否开启了本地缓存,若是则向机器组发送一条消息,然后判断是否开启了第三方缓存,若有则刷新最新数据

4)收到本地缓存消息的机器刷新本地缓存最新数据

5、存在缓存穿透、缓存击穿、缓存雪崩风险

缓存穿透:增加NULL值,缓存较短的时间

缓存击穿:增加锁同步数据获取过程

缓存雪崩:增加预警参数提前异步刷新,热点缓存监控

6、日志不足

增加统一日志,方便排查问题

详细设计

模块组成:

类图:

配置类

支持两级缓存:一级为本地缓存,使用guava实现;二级为分布式缓存,使用redis + redisson实现

二级缓存需要添加分布式服务配置,而一级缓存在缓存单位中配置即可,实时更新依赖MQ服务

1、服务配置

redisson配置类:RedissonConfiguration,用于redis相关配置

详细配置项参考附录

2、缓存单位配置

同一前缀为一个缓存单位,新增配置文件cache-config.yml(参考cache-config-demo.yml)对缓存参数进行定义,服务启动后会解析该文件,将配置保存到CacheConfiguration中

注意:支持依赖jar内配置cache-config.yml,若key冲突则在启动时报错

caches:# 业务空间,非必填application: mc# L1并发级别,即同时支持多少个线程,非必填l1ConcurrencyLevel: 10# 单个缓存配置cache:# 前缀,必填,唯一prefix: user_# 版本,非必填,用于缓存结构改变后升级reload最新内容version: v1# 缓存时间,必填,支持d/h/m/s,默认sexpired: 5m# 预警时间,非必填,支持d/h/m/s,默认s,用于提前更新alarm: 2m# 序列化方式,非必填,支持hessian/jdk,默认hessianserializer: hessian# 开启一级缓存,非必填,一二级至少开启其一L1:# 初始容量,非必填,Guava扩容代价大,尽量指定所需容量initialCapacity: 100# 最大容量,必填maximumSize: 1000# 并发级别,非必填,优先级高于l1ConcurrencyLevelconcurrencyLevel: 10# 开启二级缓存,非必填,一二级至少开启其一L2:# 指定配置名称,必填(否则无法解析为对象),用于多分布式缓存源,为空使用默认配置ref: xxxConfig# 实时更新配置,非必填(未实现)reload:# 订阅的表,必填,多个用逗号分隔table: user, lesson# reload操作,非必填,UPDATE(更新)/DELETE(删除,默认)/RELOAD(重新刷新)operation: UPDATE# key拼接方式,非必填,数据库记录用小括号作动态替换key: _(id)

模块服务类

1、存储实体

实体字段如下:

public class CacheEntity implements Serializable {private static final long serialVersionUID = 1L;// 真实内容,通过hession/jdk进行序列化/反序列化private String value;// 缓存时间private long cacheTime;// 预警时间private long alarmTime;
}

2、缓存操作

包括常规的get()、set()、add()、del()外,增加带LoadingCache功能的get方法,提供分布式锁方法DLock()、unDLock(),由redisson实现

public  <T> T get(String prefix, String key, LoadingCache loader, Object ... params) {CacheEntity entity = null;T value = null;// 获取缓存单位配置Config config = CacheConfiguration.getConfig(prefix);if (config.hasL1() != null) {// 获取L1结果entity = getL1();}if (entity == null) {if (config.hasL2() != null) {// 获取L2结果entity = getL2();}}if (entity == null && loader != null) {// 获取数据value = loader.load(params);if (value != null) {// 设置缓存set(prefix, key, value);} else {// 设置NULL值setNull(prefix, key);}return value;}return serializer.deserialize(value);
}

3、提前更新

缓存未到expired但已到alarm时,在返回内容之前开启异步线程提前更新缓存内容

private void alarmUpdate(Config config, CacheEntity entity, LoadingCache loader) {long time = System.currentTimeMillis() + entity.getCacheTime();if (time > entity.getAlarmTime()) {T value = loader.load();if (value != null) {// 设置缓存set(prefix, key, value);}}
}

4、注解配置

支持在方法上增加自定义注解,在调用时自动走缓存

// 获取单个缓存
@MethodCache("user_")
public List getList(int id, String name) {// ...
}
// 获取批量缓存
// 注意第一个参数必须为key的list集合,返回以key分组
@MultipleMethodCache(CacheServiceTest.l1Prefix)
public Map<String, CacheTestB> getMultiAutoIncrement(List<String> keys, String value, int num) {// ...
}

注意:只能增强由spring管理的类方法

5、实时更新(未实现)

使用阿里开源框架canal监听mysql的binlog日志,将变更通过MQ广播到消费端,具体参考:Canal Kafka RocketMQ QuickStart

服务收到消息后,对消息进行解析处理

public boolean consumer(byte[] bytes) {Message message = JsonUtil.fromStr(bytes, Message.class);String table = message.getTable();// 获取reload配置ReloadConfig reloadConfig = CacheConfiguration.getReloadConfig(table);if (reloadConfig != null) {String key = reloadConfig.getKey();if (reloadConfig.getOperation() == DELETE) {// 删除缓存del(key);} else {// 更新缓存update(key, message);}}
}

6、其它

  • 增加debug级别日志打印
  • 增加是否使用缓存配置,用于测试用例

待实现功能

  • 目前仅支持byte数组存储,后期将开放redis其它类型的实现(部分redis独有的类型geo等如真有需求,是否考虑直接提供client?这样子就增加了耦合性)
  • 基于canal自动刷新缓存
  • 热点数据统计

附录

源码

基于spring boot通用多级缓件组件: 业界第三方缓存框架一般为redis,本地缓地ehcache或guava,一般通过spring提供的restTemplate操作缓存,然而这样会存在一些问题,期望通过此组件解决问题

redis配置

以redisson作为前缀,开启redis配置:redisson.open.flag=true

单机版redis

#单Redis节点模式

redisson.singleServerConfig.address=127.0.0.1:6379

集群模式

集群模式除了适用于Redis集群环境,也适用于任何云计算服务商提供的集群模式,例如AWS ElastiCache集群版、Azure Redis Cache和阿里云(Aliyun)的云数据库Redis版。

#集群模式

redisson.model=CLUSTER

#redis机器.一直累加下去

redisson.multiple-server-config.node-addresses[0]=127.0.0.1:6379

redisson.multiple-server-config.node-addresses[1]=127.0.0.1:6380

redisson.multiple-server-config.node-addresses[2]=127.0.0.1:6381

云托管模式

云托管模式适用于任何由云计算运营商提供的Redis云服务,包括亚马逊云的AWS ElastiCache、微软云的Azure Redis 缓存和阿里云(Aliyun)的云数据库Redis版

#云托管模式

redisson.model=REPLICATED

#redis机器.一直累加下去

redisson.multiple-server-config.node-addresses[0]=127.0.0.1:6379

redisson.multiple-server-config.node-addresses[1]=127.0.0.1:6380

redisson.multiple-server-config.node-addresses[2]=127.0.0.1:6381

哨兵模式

redisson.model=SENTINEL

#主服务器的名称是哨兵进程中用来监测主从服务切换情况的。

redisson.multiple-server-config.master-name="mymaster"

#redis机器.一直累加下去

redisson.multiple-server-config.node-addresses[0]=127.0.0.1:6379

redisson.multiple-server-config.node-addresses[1]=127.0.0.1:6380

redisson.multiple-server-config.node-addresses[2]=127.0.0.1:6381

主从模式

redisson.model=MASTERSLAVE

#第一台机器就是主库.其他的为从库

redisson.multiple-server-config.node-addresses[0]=127.0.0.1:6379

redisson.multiple-server-config.node-addresses[1]=127.0.0.1:6380

redisson.multiple-server-config.node-addresses[2]=127.0.0.1:6381

属性列表

基本都是官方参数.我将参数整合了下.分为 公共参数,单例模式参数,集群模式参数

1.公共参数

属性名

默认值

备注

redisson.name

default

配置名称,必须保证唯一,否则配置将被覆盖

redisson.password

用于节点身份验证的密码。

redisson.attemptTimeout

10000L

等待获取锁超时时间,-1则是一直等待

redisson.lockModel

单个key默认可重入锁

多个key默认联锁

锁的模式.如果不设置, REENTRANT(可重入锁),FAIR(公平锁),MULTIPLE(联锁),REDLOCK(红锁),READ(读锁), WRITE(写锁)

redisson.model

SINGLE

集群模式:SINGLE(单例),SENTINEL(哨兵),MASTERSLAVE(主从),CLUSTER(集群),REPLICATED(云托管)

redisson.codec

org.redisson.codec.JsonJacksonCodec

Redisson的对象编码类是用于将对象进行序列化和反序列化,以实现对该对象在Redis里的读取和存储

redisson.threads

当前处理核数量 * 2

这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。

redisson.nettyThreads

当前处理核数量 * 2

这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。

redisson.transportMode

NIO

TransportMode.NIO,TransportMode.EPOLL - 需要依赖里有netty-transport-native-epoll包(Linux) TransportMode.KQUEUE - 需要依赖里有 netty-transport-native-kqueue包(macOS)

redisson.idleConnectionTimeout

10000

如果当前连接池里的连接数量超过了最小空闲连接数,而同时有连接空闲时间超过了该数值,那么这些连接将会自动被关闭,并从连接池里去掉。时间单位是毫秒

redisson.connectTimeout

10000

同任何节点建立连接时的等待超时。时间单位是毫秒。

redisson.timeout

3000

等待节点回复命令的时间。该时间从命令发送成功时开始计时。

redisson.retryAttempts

3

如果尝试达到 retryAttempts(命令失败重试次数) 仍然不能将命令发送至某个指定的节点时,将抛出错误。如果尝试在此限制之内发送成功,则开始启用 timeout(命令等待超时) 计时。

redisson.retryInterval

1500

在一条命令发送失败以后,等待重试发送的时间间隔。时间单位是毫秒。

redisson.subscriptionsPerConnection

5

每个连接的最大订阅数量。

redisson.clientName

在Redis节点里显示的客户端名称。

redisson.sslEnableEndpointIdentification

true

开启SSL终端识别能力。

redisson.sslProvider

JDK

确定采用哪种方式(JDK或OPENSSL)来实现SSL连接。

redisson.sslTruststore

指定SSL信任证书库的路径。

redisson.sslTruststorePassword

指定SSL信任证书库的密码。

redisson.sslKeystore

指定SSL钥匙库的路径。

redisson.sslKeystorePassword

指定SSL钥匙库的密码。

redisson.lockWatchdogTimeout

30000

监控锁的看门狗超时时间单位为毫秒。该参数只适用于分布式锁的加锁请求中未明确使用leaseTimeout参数的情况。如果该看门口未使用lockWatchdogTimeout去重新调整一个分布式锁的lockWatchdogTimeout超时,那么这个锁将变为失效状态。这个参数可以用来避免由Redisson客户端节点宕机或其他原因造成死锁的情况。

redisson.keepPubSubOrder

true

通过该参数来修改是否按订阅发布消息的接收顺序出来消息,如果选否将对消息实行并行处理,该参数只适用于订阅发布消息的情况。

单例模式参数

属性名

默认值

备注

redisson.singleServerConfig.address

服务器地址,必填ip:port

redisson.singleServerConfig.database

0

尝试连接的数据库编号。

redisson.singleServerConfig.subscriptionConnectionMinimumIdleSize

1

用于发布和订阅连接的最小保持连接数(长连接)。Redisson内部经常通过发布和订阅来实现许多功能。长期保持一定数量的发布订阅连接是必须的。

redisson.singleServerConfig.subscriptionConnectionPoolSize

50

用于发布和订阅连接的连接池最大容量。连接池的连接数量自动弹性伸缩。

redisson.singleServerConfig.connectionMinimumIdleSize

32

最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时写入反应速度。

redisson.singleServerConfig.connectionPoolSize

64

连接池最大容量。连接池的连接数量自动弹性伸缩。

redisson.singleServerConfig.dnsMonitoringInterval

5000

用来指定检查节点DNS变化的时间间隔。使用的时候应该确保JVM里的DNS数据的缓存时间保持在足够低的范围才有意义。用-1来禁用该功能。

集群模式

属性名

默认值

备注

redisson.multiple-server-config.node-addresses

服务器节点地址.必填
redisson.multiple-server-config.node-addresses[0]=127.0.0.1:6379
redisson.multiple-server-config.node-addresses[1]=127.0.0.1:6380
redisson.multiple-server-config.node-addresses[2]=127.0.0.1:6381

redisson.multiple-server-config.loadBalancer

org.redisson.connection.balancer.RoundRobinLoadBalancer

在多Redis服务节点的环境里,可以选用以下几种负载均衡方式选择一个节点:
org.redisson.connection.balancer.WeightedRoundRobinBalancer - 权重轮询调度算法
org.redisson.connection.balancer.RoundRobinLoadBalancer - 轮询调度算法
org.redisson.connection.balancer.RandomLoadBalancer - 随机调度算法

redisson.multiple-server-config.slaveConnectionMinimumIdleSize

32

多从节点的环境里,每个 从服务节点里用于普通操作(非 发布和订阅)的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时读取反映速度。

redisson.multiple-server-config.slaveConnectionPoolSize

64

多从节点的环境里,每个 从服务节点里用于普通操作(非 发布和订阅)连接的连接池最大容量。连接池的连接数量自动弹性伸缩。

redisson.multiple-server-config.masterConnectionMinimumIdleSize

32

多节点的环境里,每个 主节点的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时写入反应速度。

redisson.multiple-server-config.masterConnectionPoolSize

64

多主节点的环境里,每个 主节点的连接池最大容量。连接池的连接数量自动弹性伸缩。

redisson.multiple-server-config.readMode

SLAVE

设置读取操作选择节点的模式。 可用值为: SLAVE - 只在从服务节点里读取。 MASTER - 只在主服务节点里读取。 MASTER_SLAVE - 在主从服务节点里都可以读取。

redisson.multiple-server-config.subscriptionMode

SLAVE

设置订阅操作选择节点的模式。 可用值为: SLAVE - 只在从服务节点里订阅。 MASTER - 只在主服务节点里订阅。

redisson.multiple-server-config.subscriptionConnectionMinimumIdleSize

1

用于发布和订阅连接的最小保持连接数(长连接)。Redisson内部经常通过发布和订阅来实现许多功能。长期保持一定数量的发布订阅连接是必须的。 redisson.multiple-server-config.subscriptionConnectionPoolSize

redisson.multiple-server-config.dnsMonitoringInterval

5000

监测DNS的变化情况的时间间隔。

redisson.multiple-server-config.scanInterval

1000

(集群,哨兵,云托管模特特有) 对Redis集群节点状态扫描的时间间隔。单位是毫秒。

redisson.multiple-server-config.database

0

(哨兵模式,云托管,主从模式特有)尝试连接的数据库编号。

redisson.multiple-server-config.masterName

(哨兵模式特有)主服务器的名称是哨兵进程中用来监测主从服务切换情况的。

多redis源配置

以multiple.redisson为前缀,sources为多源,以key/value配置,value与上面的配置一致(去掉redission)

例:

multiple.redisson.sources.test2.singleServerConfig.address=10.8.104.71:6379

multiple.redisson.sources.test2.threads=1

即ref=test2时使用上述配置

相关文章:

通用多级缓件组件

背景 业界第三方缓存框架一般为redis&#xff0c;本地缓地ehcache或guava&#xff0c;一般通过spring提供的restTemplate操作缓存 然而这样会存在以下问题&#xff1a; 与缓存中间件强耦合需手动整合多级缓存不支持注解数据更新时无法自动刷新缓存存在缓存穿透、缓存击穿、缓…...

MindIE Service服务化集成部署通义千问Qwen模型

一、昇腾开发者平台申请镜像 登录Ascend官网昇腾社区-官网丨昇腾万里 让智能无所不及 二、登录并下载mindie镜像 #登录docker login -u XXX#密码XXX#下载镜像docker pull XXX 三、下载Qwen的镜像 使用wget命令下载Qwen1.5-0.5B-Chat镜像&#xff0c;放在/mnt/Qwen/Qwen1.5-…...

chrome 接口请求等待时间(installed 已停止)过长问题定位

参考: 解决实际项目中stalled时间过久的问题 背景: 测试反馈系统开 6 个标签页后, 反应变的很慢 定位: 看接口请求瀑布流, 已停止时间很长, 后端返回速度很快, 确定是前端的问题 推测是并发请求窗口数量的问题, 屏蔽部分一直 pending 的接口, 发现速度正常了, 搜到上面的参…...

HDialog特殊动画效果

基于HDialog的特殊动画效果实现 业务场景 在开发过程中直接使用HDialog所展现的效果很快&#xff0c;同时不能够与用户所点击位置进行交互&#xff0c;会造成用户的体验观感不够好。因此需要实现一种能够从用户点击按钮位置以可变动画效果所展现的Dialog效果。 工作原理及实…...

基因组挖掘指导天然药物分子的发现-文献精读34

基因组挖掘指导天然药物分子的发现 摘要 天然产物是临床药物的主要来源&#xff0c;也是新药研发过程中先导化合物结构设计和优化的灵感源泉。但传统策略天然药源分子的发现却遭遇了瓶颈&#xff0c;新颖天然产物的数量逐渐无法满足现代药物开发的需求和应对全球多药耐药的威胁…...

hcip学习 DHCP中继

DHCP 中继 在可能收到 DHCP Discover 报文的接口配置 DHCP 中继&#xff0c; 指明 DHCP 服务器的地址&#xff0c;然后将 DHCP 发现报文以单播的形式送到 DHCP 服务器上 DHCP 中继报文的源地址和目标地址怎么确定 1、源地址&#xff1a;收到 Discover 报文的接口地址 2、目…...

[Mysql-函数、索引]

目录 函数&#xff1a; 日期函数 字符串函数 数学函数 聚合函数 索引&#xff1a; 索引分类 慢查询 创建索引 函数&#xff1a; MySQL函数&#xff0c;是一种控制流程函数&#xff0c;属于数据库用语言。 MySQL常见的函数有&#xff1a; 数学函数 用作常规的数学运…...

org.eclipse.jgit 简单总结

org.eclipse.jgit 是一个用于处理 Git 版本控制系统的纯 Java 库。它允许你读取和写入 Git 仓库&#xff0c;执行如克隆、拉取、推送、提交等操作。下面我将通过几个例子来展示如何使用 org.eclipse.jgit 进行一些常见的 Git 操作。 1. 克隆仓库 克隆一个远程 Git 仓库到本地目…...

Fork软件笔记:一键拉取仓库所有模块

Fork是一个好用的git工具&#xff0c;只是没有中文而已&#xff08;不过不用翻译也能看使用&#xff09;。 工具下载地址&#xff1a;https://fork.dev/ 界面展示&#xff1a; 当项目中仓库模块比较多时&#xff0c;可以看到每个模块都是一个分页&#xff0c;每一个都要手动切换…...

常见的锂电保护芯片 单节锂电保护/双节锂电保护芯片

目前外出贸易的要求不断增多&#xff0c;出口的产品基本上都需要带上锂电保护芯片 以下是常见的单节锂电保护芯片的选型 包括了市面上大部分的可用型号。 锂电保护芯片的脚位上面基本都是通用&#xff0c;可以直接替代 双节的锂电保护使用情况较少&#xff0c;需要外置MOS管调节…...

初识Java(六)

一、String类 1、类中有操作字符串的方法 查找&#xff1a;找到某个字符是字符串内的第几个&#xff1a;charAt&#xff1b;找到某个字符在字符串内第一次出现的下标&#xff1a;index 替换&#xff1a;替换所有&#xff1a;replaceAll&#xff1b;替换首个&#xff1a;repla…...

Spring-原理篇-DispatcherServlet 初始化 怎么和IOC进行了打通?

委托模式的体现&#xff0c;在初始化醒目的时候Spring MVC为我们提供了一个DispatcherServlet&#xff0c;映射了所有的路径&#xff0c;所有的请求都会先到达这里然后被转发到具体的Controller 进行处理&#xff0c;此文来探索一下&#xff0c;DispatcherServlet 初始化的时候…...

关于swift- OC混编使用Pod遇到的2个错误

错误1 Cannot find interface declaration for UITableViewCell, superclass of "DEFUITalbleViewCell" Cannot find interface declaration for UIView, superclass of "DefUIView" Cannot find interface declaration for 系统类, superclass of "自…...

Golang | Leetcode Golang题解之第290题单词规律

题目&#xff1a; 题解&#xff1a; func wordPattern(pattern string, s string) bool {word2ch : map[string]byte{}ch2word : map[byte]string{}words : strings.Split(s, " ")if len(pattern) ! len(words) {return false}for i, word : range words {ch : patt…...

【Django5】模型定义与使用

系列文章目录 第一章 Django使用的基础知识 第二章 setting.py文件的配置 第三章 路由的定义与使用 第四章 视图的定义与使用 第五章 二进制文件下载响应 第六章 Http请求&HttpRequest请求类 第七章 会话管理&#xff08;Cookies&Session&#xff09; 第八章 文件上传…...

HTML--JavaScript操作DOM对象

目录 本章目标 一.DOM对象概念 ​编辑 二.节点访问方法 常用方法&#xff1a; 层次关系访问节点 三.节点信息 四.节点的操作方法 操作节点的属性 创建节点 删除替换节点 五.节点操作样式 style属性 class-name属性 六.获取元素位置 总结 本章目标 了解DOM的分类和节…...

Redis 缓存

安装 安装 Redis 下载&#xff1a; Releases tporadowski/redis (github.com) winr ----services.msc-----将redis 设置为手动(只是学习&#xff0c;如果经常用可以设置为自动) 安装 redis-py 库 pip install redis-py Redis 和 StrictRedis redis-py 提供 Redis 和 Str…...

Prozyme糖样本检测平台--GlykoPrep® Rapid N-Glycan Preparation with APTS

单克隆抗体已成为生物制药行业具有潜力的新兴蛋白候选药物。其药物研发流程包括一系列精细的控制和评估步骤&#xff0c;需要仔细、严格地监测目标化合物的治疗稳定性及有效性。因此&#xff0c;在商业化前的每个阶段对单克隆抗体进行全面表征是极其有益的。在大量研究成熟的蛋…...

力扣面试题(一)

1、给你两个字符串 word1 和 word2 。请你从 word1 开始&#xff0c;通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长&#xff0c;就将多出来的字母追加到合并后字符串的末尾。 char * mergeAlternately(char * word1, char * word2){int len1 strlen(word1);i…...

Python 输入输出

重点内容&#xff1a; 1、梳理掌握输入和输出函数的应用。 2、熟练使用int() float() str()等函数进行数据转换 3、常用转义字符在数据输入、输出中的应用 4、熟练使用ljust()、center()、rjust()等方法对字符位置进行控制。 5、灵活应用ASCII码、字母、数字及特殊字符解决…...

国服最强文字转音频?Fish Speech

官网文档与示例 Fish Speech V1.2 是一款领先的文本到语音 (TTS) 模型&#xff0c;使用 30 万小时的英语、中文和日语音频数据进行训练。我尝试用1066运行&#xff0c;但是质量不尽如人意&#xff0c;建议使用RTX系列的显卡进行推理。 使用结果展示 text """20…...

数据结构(6):图

1 图的基本概念 1.1 基本概念 1.1.1 定义【多对多的关系】 一个图不可能是空图&#xff01;&#xff01;&#xff01;一个图的顶点集一定是非空集&#xff0c;但是边集可以为空集&#xff01; 1.1.2 应用 1.2 无向图和有向图 弧头是有箭头的那一边&#xff0c;弧尾是没有箭头…...

kaggle使用api下载数据集

背景 kaggle通过api并配置代理下载数据集datasets 步骤 获取api key 登录kaggle&#xff0c;点个人资料&#xff0c;获取到自己的api key 创建好的key会自动下载 将key放至家目录下的kaggle.json文件中 我这里是windows的administrator用户。 装包 我用了虚拟环境 pip …...

前缀表达式(波兰式)和后缀表达式(逆波兰式)的计算方式

缀是指操作符。 1. 前缀表达式&#xff08;波兰式&#xff09; &#xff08;1&#xff09;不需用括号&#xff1b; &#xff08;2&#xff09;不用考虑运算符的优先级&#xff1b; &#xff08;3&#xff09;操作符置于操作数的前面。&#xff08;如 3 2 &#xff09; 1.1 中…...

智能井盖管理系统:城市窨井的井下“保镖”

随着城市化进程的加速&#xff0c;城市的生命线基础设施面临着越来越多的挑战。其中&#xff0c;旭华智能智能井盖传感器技术的发展为提升城市基础设施的安全性和管理效率提供了新的解决方案。它专门用于监控市政窨井、燃气井、供水井内的积水状况以及井盖状态&#xff0c;以增…...

vue3-环境变量-JavaScript-axio-基础使用-lzstring-字符串压缩-python

文章目录 1.Vue3环境变量1.1.简介1.2.全局变量的引用1.3.package.json文件 2.axio2.1.promise2.2.安装2.3.配置2.3.1.全局 axios 默认值2.3.2.响应信息格式 2.4.Axios的拦截器2.4.1.请求拦截器2.4.2.响应拦截器2.4.3.移除拦截器2.4.4.自定义实例添加拦截器 3.lz-string3.1.java…...

ubuntu下载docker依赖包

Ubuntu下载docker依赖包 ​ 公司对外客户一直偏向对安全性要求较高&#xff0c;因此在外部署服务得时候&#xff0c;安装docker是一件极为重要得事情&#xff0c;之前得服务器得系统是centos7。在上一家公司的时候&#xff0c;已经把docker所需得rpm包已经集成打包好了。并且d…...

java面向对象进阶进阶篇--《JDK8,JDK9接口中新增的方法、接口的应用、适配器设计模式》

个人主页→VON 收录专栏→java从入门到起飞 接口→接口和接口与抽象类综合案例 一、JDK8接口中新增的方法 在JDK 8中&#xff0c;接口新增了几个重要的特性和方法&#xff0c;其中最显著的是默认方法&#xff08;Default Methods&#xff09;和静态方法&#xff08;Static Met…...

15.2 zookeeper java client

15.2 zookeeper java client 1. Zookeeper官方1.1 依赖1.2 Zookeeper客户端连接测试1.3***************************************************************************************1. Zookeeper官方 1.1 依赖 <!-- 集成方式一:官方集成zookeeper依赖 --><dependenc…...

素材管理太繁琐?有这一个就够了!

引言&#xff1a; 在创意行业中&#xff0c;素材管理一直是设计师们的痛点。从灵感的捕捉到作品的完成&#xff0c;每一步都离不开素材的积累与整理。然而&#xff0c;传统的素材管理方式往往繁琐且效率低下&#xff0c;让人头疼不已。今天&#xff0c;我要介绍的这款智能素材管…...

KubeSphere 部署向量数据库 Milvus 实战指南

作者&#xff1a;运维有术星主 Milvus 是一个为通用人工智能&#xff08;GenAI&#xff09;应用而构建的开源向量数据库。它以卓越的性能和灵活性&#xff0c;提供了一个强大的平台&#xff0c;用于存储、搜索和管理大规模的向量数据。Milvus 能够执行高速搜索&#xff0c;并以…...

前端canvas——贝塞尔曲线

曲线之美&#xff0c;不在于曲线本身&#xff0c;而在于用的人。 所以就有了这期贝塞尔曲线。 新规矩&#xff0c;先上个GIT。 效果图 开局一张图&#xff0c;代码全靠编。 代码 画骨 先想着怎么画一个心形吧&#xff0c;等你想好了&#xff0c;就知道怎么画了。 首先就还…...

Elasticsearch模糊查询之Wildcard

{“wildcard” : { “LPR.keyword” : { “wildcard” : “${Keyword}”} }},你的示例中使用了 wildcard 查询&#xff0c;它适用于模糊搜索&#xff0c;允许使用通配符&#xff08;* 和 ?&#xff09;来匹配字段值。你使用了 keyword 子字段来确保精确匹配&#xff0c;这是一…...

【人工智能】穿越科技迷雾:解锁人工智能、机器学习与深度学习的奥秘之旅

文章目录 前言一、人工智能1. 人工智能概述a.人工智能、机器学习和深度学习b.人工智能发展必备三要素c.小案例 2.人工智能发展历程a.人工智能的起源b.发展历程 3.人工智能的主要分支 二、机器学习1.机器学习工作流程a.什么是机器学习b.机器学习工作流程c.特征工程 2.机器学习算…...

Nginx服务 rewrite、proxy_pass 用rewrite去除URL中的特定参数

Nginx 是一个高性能的开源反向代理服务器&#xff0c;可以用于处理跨域请求、负载均衡和缓存等功能。在本文中&#xff0c;我们将介绍如何使用 Nginx 配置文件来实现反向代理。 我们可以实现跨域请求的处理&#xff0c;同时保护用户的隐私和安全。此外&#xff0c;Nginx 还…...

RocketMQ事务消息机制原理

RocketMQ工作流程 在RocketMQ当中&#xff0c;当消息的生产者将消息生产完成之后&#xff0c;并不会直接将生产好的消息直接投递给消费者&#xff0c;而是先将消息投递个中间的服务&#xff0c;通过这个服务来协调RocketMQ中生产者与消费者之间的消费速度。 那么生产者是如何…...

【C++】选择结构- 嵌套if语句

嵌套if语句的语法格式&#xff1a; if(条件1) { if(条件1满足后判断是否满足此条件) {条件2满足后执行的操作} else {条件2不满足执行的操作} } 下面是一个实例 #include<iostream> using namespace std;int main4() {/*提示用户输入一个高考分数&#xff0c;根据分…...

scrapy解决管道阻塞问题采用threadpool库线程池+twisted同步语法异步编程

实现方法&#xff1a;process_item和download任务函数像下面编写即可&#xff0c;其他管道像往常一样写法 import time import threadpool import random from twisted.internet import deferclass VideoPipeline:def __init__(self):self.pool threadpool.ThreadPool(10) # …...

Axure RP:打造动态交互的大屏可视化设计利器

Axure大屏可视化是指使用Axure RP这款原型设计工具来创建具有视觉冲击力和数据展示功能的大屏幕界面。Axure以其强大的交互设计和丰富的组件库&#xff0c;成为了实现大屏可视化的重要工具之一。以下是对Axure大屏可视化的详细阐述&#xff1a; 一、Axure在大屏可视化中的优势 …...

“八股文”在实际工作中是助力、阻力还是空谈

目录 1.概述 1.1.对实际工作的助力 1.2.存在的问题 2.“八股文”对招聘过程的影响 2.1.“八股文”在筛选候选人时的作用 2.2.面试中的比重及其合理性 2.3.如何平衡“八股文”与实际编程能力的考察 3.“八股文”在日常工作中的实用价值 3.1.在团队协作环境中进行有效沟…...

项目开发:@ControllerAdvice注解的基本应用

目录 简介基本用法全局异常处理全局拦截器全局数据绑定 注解参数1.value(): String[]2.basePackages(): String[]3.basePackageClasses(): Class<?>[]4.assignableTypes(): Class<?>[]5.annotations(): Class<? extends Annotation>[] 三.注解组成总结 简…...

Jmeter三种方式获取数组中多个数据并将其当做下个接口参数入参【附带JSON提取器和CSV格式化】

目录 一、传统方式-JOSN提取器获取接口返回值 1、接口调用获取返回值 2、添加JSON提取器 3、调试程序查看结果 4、添加循环控制器 5、设置count计数器 6、添加请求 7、执行请求 二、CSV参数化 1、将结果写入后置处理程序 2、设置循环处理器 3、添加CSV文件 4、设置…...

C++入门基础:C++中的循环语句

循环语句是编程语言中用来重复执行一段代码直到满足特定条件的一种控制结构。它们对于处理需要重复任务的场景非常有用&#xff0c;比如遍历数组、累加数值、重复执行某项操作直到满足条件等。 但是在使用循环语句的时候需要注意下哈&#xff0c;有时候一不小心会构成死循环或者…...

VUE 基础(二)

1 v-show:根据表达值的真假&#xff0c;切换元素的显示和隐藏 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">&l…...

VMware Cloud Foundation ESXi 主机

一、准备嵌套 ESXi 主机环境# 1)物理 ESXi 主机信息 本次准备用于部署 VCF 嵌套实验环境的物理宿主机的配置信息如下图所示。其实,部署 VCF 环境主要对内存的大小要求比较高,部署完整的管理域相关组件下来差不多就要占用 200 GB左右内存,而对 CPU 和存储的需求可以根据实…...

PyTorch深度学习快速入门(下)

PyTorch深度学习快速入门&#xff08;下&#xff09; 一、现有网络模型的使用及修改&#xff08;一&#xff09;背景知识&#xff08;二&#xff09;修改网络模型的三种方法 二、网络模型的保存与加载&#xff08;一&#xff09;保存网络模型的两种方法&#xff08;二&#xff…...

轻松入门Linux—CentOS,直接拿捏 —/— <1>

一、什么是Linux Linux是一个开源的操作系统&#xff0c;目前是市面上占有率极高的服务器操作系统&#xff0c;目前其分支有很多。是一个基于 POSIX 和 UNIX 的多用户、多任务、支持多线程和多 CPU 的操作系统 Linux能运行主要的UNIX工具软件、应用程序和网络协议 Linux支持 32…...

pandas安装以及导入CSV

安装pandas pip install pandas速度慢可以切换国内镜像源 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pandas执行导入csv操作 import pandas as pd# 读取csv文件 data pd.read_csv(yourPath)输入data查看数据 导入成功&#xff01;...

新能源车浪潮来袭,同时存在高压低压系统,如何准确进行高低压布线间距EMC分析?

摘要 随着车辆电气化水平的逐步提升&#xff0c;电气零部件布局和布线面临着前所未有的挑战&#xff0c;在不断的压缩电气零部件间间距后&#xff0c;EMC性能成为非常关键的性能指标。特别是对于新能源车型&#xff0c;同时存在高压和低压系统&#xff0c;高低压耦合若处理的不…...

QUIC 协议

详解 QUIC 协议&#xff1a;它为何比 TCP 更优越&#xff1f;...