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

Spring Boot ShardingJDBC分库分表(草稿)

ShardingJDBC分库分表

1.Maven 引用

		<dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.1.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency>

2.数据库和表格

数据库
*****_ch
*****_hk
*****_us
*****_olap表格
kline
kline_D_0
kline_D_1
.......
kline_D_15kline
kline_M_0
kline_M_1
.......
kline_M_15kline_m1
kline_m1_250121
.......
kline_m1_2501221kline_M5_0
.......
kline_M5_15kline_M30_0
.......
kline_M30_15kline_M60_0
.......
kline_M60_15kline_W_0
.......
kline_W_15kline_Y_0
.......
kline_Y_15trade_record_240101trade_record_250213_0
........
trade_record_250221_249
CREATE DEFINER=`admin`@`%` PROCEDURE `CreateKlineTables`()
BEGINDECLARE i INT DEFAULT 0;DECLARE j INT DEFAULT 0;DECLARE table_name VARCHAR(64);DECLARE date_parts TEXT;DECLARE date_part VARCHAR(10);-- 定义时间周期数组SET date_parts = 'M5,M30,M60,D,W,M,Y';-- 循环遍历时间周期WHILE j < LENGTH(date_parts) - LENGTH(REPLACE(date_parts, ',', '')) + 1 DOSET date_part = SUBSTRING_INDEX(SUBSTRING_INDEX(date_parts, ',', j + 1), ',', -1);-- 循环创建表SET i = 0;WHILE i < 16 DOSET table_name = CONCAT('kline_', date_part, '_', i);SET @sql = CONCAT('CREATE TABLE IF NOT EXISTS ', table_name, ' LIKE kline');PREPARE stmt FROM @sql;EXECUTE stmt;DEALLOCATE PREPARE stmt;SET i = i + 1;END WHILE;SET j = j + 1;END WHILE;
END

CREATE DEFINER=`admin`@`%` PROCEDURE `CreateTradeRecordTables`(IN date_part VARCHAR(10))
BEGINDECLARE i INT DEFAULT 0;DECLARE table_name VARCHAR(64);-- 循环创建表WHILE i < 250 DOSET table_name = CONCAT('trade_record_', date_part, '_', i);SET @sql = CONCAT('CREATE TABLE IF NOT EXISTS ', table_name, ' like trade_record_240101');PREPARE stmt FROM @sql;EXECUTE stmt;DEALLOCATE PREPARE stmt;SET i = i + 1;END WHILE;
END
CREATE DEFINER=`admin`@`%` PROCEDURE `DropTradeRecordTables`(IN date_part VARCHAR(10))
BEGINDECLARE i INT DEFAULT 0;DECLARE table_name VARCHAR(64);-- 循环删除表WHILE i < 250 DOSET table_name = CONCAT('trade_record_', date_part, '_', i);SET @sql = CONCAT('DROP TABLE IF EXISTS ', table_name);PREPARE stmt FROM @sql;EXECUTE stmt;DEALLOCATE PREPARE stmt;SET i = i + 1;END WHILE;
END

2.application.yaml配置

  • 配置文件
spring:port: 8888tomcat:uri-encoding: UTF-8max-http-post-size: 20MBmax-http-header-size: 20MBhttp:encoding:force: truecharset: UTF-8enabled: trueaop:auto: truemain:allow-bean-definition-overriding: truejpa:database-platform: org.hibernate.dialect.MySQL5InnoDBDialectshow-sql: falsehibernate:ddl-auto: nonedsx:olap:type: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.cj.jdbc.DriverjdbcUrl: username: password: hikari:maximum-pool-size: 20minimum-idle: 20shardingsphere:datasource:names: center, ds0, ds1, ds2center:type: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.cj.jdbc.DriverjdbcUrl: username: password: hikari:maximum-pool-size: 20minimum-idle: 20ds0:type: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.cj.jdbc.DriverjdbcUrl: username: password: hikari:maximum-pool-size: 20minimum-idle: 20ds1:type: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.cj.jdbc.DriverjdbcUrl: username: password: hikari:maximum-pool-size: 20minimum-idle: 20ds2:type: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.cj.jdbc.DriverjdbcUrl: username: password: hikari:maximum-pool-size: 20minimum-idle: 20props:sql:show: falsesharding:default-data-source-name: centertables:trade_record:actual-data-nodes: ds$->{0..2}.trade_record_$->{0..10}database-strategy: standard: sharding-column: market_codeprecise-algorithm-class-name: com.zzc.sharding.DbShardingByMarketTypeAlgorithmtable-strategy:complex:sharding-columns: trade_date,symbol_idalgorithm-class-name: com.zzc.sharding.TableShardingByDateAndSymbolAlgorithmkline_m1:actual-data-nodes: ds$->{0..2}.kline_m1# actual-data-nodes: ds$->{0..1}database-strategy:standard:sharding-column: market_codeprecise-algorithm-class-name: com.zzc.sharding.DbShardingByMarketTypeAlgorithmtable-strategy:complex:sharding-columns: trade_datealgorithm-class-name: com.zzc.sharding.TableShardingByDateAlgkline:actual-data-nodes: ds$->{0..2}.kline_${['M5', 'M30','M60','D','W','M','Y']}_${0..15}# actual-data-nodes: ds$->{0..1}database-strategy:standard:sharding-column: market_codeprecise-algorithm-class-name: com.zzc.sharding.DbShardingByMarketTypeAlgorithmtable-strategy:complex:sharding-columns: kline_type,symbol_idalgorithm-class-name: com.zzc.sharding.TableShardingByKlineTypeAndSymbolIdAlg
  • 创建路由规则 DbShardingByMarketTypeAlgorithm
package com.zzc.sharding;import java.util.Collection;@Slf4j
public class DbShardingByMarketTypeAlgorithm implements PreciseShardingAlgorithm<String> {private DatabaseShardingConfig config;@Overridepublic String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {// 从 sql 中获取 marketTypeString marketType = preciseShardingValue.getValue();if (config == null) {config = SpringContextUtil.getBean(DatabaseShardingConfig.class);}// 依据 marketType 获取配置的数据库名String dbName = config.getDbName(marketType);if (!collection.contains(dbName)) {log.error("Database sharding error. column-value : [{}], DatabaseShardingConfig dbName : [{}], shardingsphere configs : [{}]", marketType, dbName, collection);throw new IllegalArgumentException("Database sharding error.");}return dbName;}
}
  • TableShardingByDateAndSymbolAlgorithm

package com.zzc.sharding;@Slf4j
public class TableShardingByDateAndSymbolAlgorithm implements ComplexKeysShardingAlgorithm {private static final String FIELD_NAME_DATE = "trade_date";private static final String FIELD_NAME_SYMBOL = "symbol_id";private DatabaseShardingConfig config;@Overridepublic Collection<String> doSharding(Collection collection, ComplexKeysShardingValue complexKeysShardingValue) {if (config == null) {config = SpringContextUtil.getBean(DatabaseShardingConfig.class);}// 从 sql 中获取成交日期 data 字段String date = ((List<String>) complexKeysShardingValue.getColumnNameAndShardingValuesMap().get(FIELD_NAME_DATE)).get(0);// 从 sql 中获取成交日期 symbol_id 字段Long symbolId = ((List<Long>) complexKeysShardingValue.getColumnNameAndShardingValuesMap().get(FIELD_NAME_SYMBOL)).get(0);// 以逻辑表名 x + "241118_1" 类似字符串为实际表名,返回最终的表名String logicTable = complexKeysShardingValue.getLogicTableName();DatabaseShardingConfig.TableShardingConfig shardingConfig = config.getTableShardingConfig(logicTable);return Collections.singletonList(logicTable + "_" + date.substring(2).replaceAll("-", "") + "_" + symbolId % shardingConfig.getTableShardingNum());}
}
  • TableShardingByDateAlg
package com.zzc.sharding;@Slf4j
public class TableShardingByDateAlg implements ComplexKeysShardingAlgorithm {@Overridepublic Collection<String> doSharding(Collection collection, ComplexKeysShardingValue complexKeysShardingValue) {// 从 sql 中获取成交日期 trade_date 字段String date = ((List<String>) complexKeysShardingValue.getColumnNameAndShardingValuesMap().get("trade_date")).get(0);// 以逻辑表名 x + "_241118" 类似字符串为实际表名,返回最终的表名String logicTable = complexKeysShardingValue.getLogicTableName();return Collections.singletonList(logicTable+ "_" + date.substring(2).replaceAll("-", ""));}
}
  • TableShardingByKlineTypeAndSymbolIdAlg
package com.zzc.sharding;@Slf4j
public class TableShardingByKlineTypeAndSymbolIdAlg implements ComplexKeysShardingAlgorithm {private DatabaseShardingConfig config;@Overridepublic Collection<String> doSharding(Collection collection, ComplexKeysShardingValue complexKeysShardingValue) {if (config == null) {config = SpringContextUtil.getBean(DatabaseShardingConfig.class);}String klineType = ((List<String>) complexKeysShardingValue.getColumnNameAndShardingValuesMap().get("kline_type")).get(0);Long symbolId = ((List<Long>) complexKeysShardingValue.getColumnNameAndShardingValuesMap().get("symbol_id")).get(0);String logicTable = complexKeysShardingValue.getLogicTableName();DatabaseShardingConfig.TableShardingConfig shardingConfig = config.getTableShardingConfig(logicTable);log.warn("symbolId:{}",symbolId);log.warn("klineType:{}",klineType);log.warn("shardingConfig:{}",shardingConfig);return Collections.singletonList(logicTable+ "_" + klineType + "_" + symbolId % shardingConfig.getTableShardingNum());}
}
  • 定时任务创建表格
package com.zzc.service.schedule;@Slf4j
@Component
@RequiredArgsConstructor
public class QuotationDataManagementJob {/** 获取锁等待时间 */private final static int LOCK_WAIT_SECONDS = 10;/** 获取锁后的锁的自动释放时间 */private final static int LOCK_LEASE_SECONDS = 30 * 60;/** 创建分表语句(使用模版表创建实际表) */private final static String SHARDING_TABLE_CREATE_SQL = "CREATE TABLE IF NOT EXISTS %s LIKE %s;";/** 删除分表语句(数据清理,防止 mysql 磁盘占用过大) */private final static String SHARDING_TABLE_CLEAR_SQL = "DROP TABLE IF EXISTS %s;";private final static String DS_SHARDING = "shardingDataSource";private final static String DS_OLAP = "olapDataSource";private final DatabaseShardingConfig dbShardingConfig;private final RedissonClient redissonClient;private final DataSource shardingDataSource;private final DataSource olapDataSource;/*** 每周五下午12点30分生成下一周的行情表*/@Scheduled(cron = "0 30 12 ? * FRI")public void createShardingTableJob() {RLock lock = redissonClient.getLock(LOCK_CREATE_SHARDING_TABLE);RedisLockUtils.lockExecute(lock, LOCK_WAIT_SECONDS, LOCK_LEASE_SECONDS, TimeUnit.SECONDS, () -> {dbShardingConfig.getTables().forEach((tableName, config) -> {if(config.getRunCreateJob())createShardingTable(tableName, config);});return null;});log.info("createShardingTable job done");}/*** 每天10点清理数据*/@Scheduled(cron = "0 0 10 * * ?")public void clearShardingTableJob() {RLock lock = redissonClient.getLock(LOCK_CLEAR_SHARDING_TABLE);RedisLockUtils.lockExecute(lock, LOCK_WAIT_SECONDS, LOCK_LEASE_SECONDS, TimeUnit.SECONDS, () -> {dbShardingConfig.getTables().forEach((tableName, config) -> {clearShardingTable(tableName, config);});return null;});log.info("clearShardingTable job done");}private void createShardingTable(String tableName, DatabaseShardingConfig.TableShardingConfig config) {if (DS_OLAP.equals(config.getDs())) {try {Connection connection = olapDataSource.getConnection();List<String> nextWeekWorkDays = getNextWeekWorkDays();nextWeekWorkDays.forEach(day -> {createShardingTable("olap", connection, tableName, day, config);});} catch (Throwable t) {log.error("createShardingTable error. db : [olap] tableName : [{}]", tableName, t);}} else {((ShardingDataSource) shardingDataSource).getDataSourceMap().forEach((dbName, myDataSource) -> {if (dbName.equals(dbShardingConfig.getCenterDs())) {// 中心库不生成相关表return;}try {Connection connection = myDataSource.getConnection();List<String> nextWeekWorkDays = getNextWeekWorkDays();nextWeekWorkDays.forEach(day -> {createShardingTable(dbName, connection, tableName, day, config);});} catch (Throwable t) {log.error("createShardingTable error. db : [{}] tableName : [{}]", dbName, tableName, t);}});}}/*** 创建分表** @param dbName     数据库名称* @param connection 数据库连接* @param tableName  表名称* @param day        工作日 - 预留给手动补数据使用*/private void createShardingTable(String dbName, Connection connection, String tableName, String day, DatabaseShardingConfig.TableShardingConfig config) {DatabaseShardingConfig.TableShardingConfig tableShardingConfig = dbShardingConfig.getTableShardingConfig(tableName);if (config.getTableShardingNum() > 1) {for (int i = 0; i < tableShardingConfig.getTableShardingNum(); i++) {String realTableName = tableName + "_" + day.substring(2) + "_" + i;try {String sql = String.format(SHARDING_TABLE_CREATE_SQL, realTableName, tableShardingConfig.getTemplateTable());connection.createStatement().execute(sql);log.info("createShardingTable success. db : [{}] tableName : [{}], realTableName : [{}], sql : [{}]", dbName, tableName, realTableName, sql);} catch (Throwable t) {log.error("createShardingTable error. db : [{}] tableName : [{}], realTableName : [{}]", dbName, tableName, realTableName, t);}}} else {String realTableName = tableName + "_" + day.substring(2);try {String sql = String.format(SHARDING_TABLE_CREATE_SQL, realTableName, tableShardingConfig.getTemplateTable());connection.createStatement().execute(sql);log.info("createShardingTable success. db : [{}] tableName : [{}], realTableName : [{}], sql : [{}]", dbName, tableName, realTableName, sql);} catch (Throwable t) {log.error("createShardingTable error. db : [{}] tableName : [{}], realTableName : [{}]", dbName, tableName, realTableName, t);}}}/*** 获取下一周的全部工作日** @return 下一周的工作日*/private List<String> getNextWeekWorkDays() {LocalDate today = LocalDate.now();// 下周一LocalDate nextMonday = today.with(TemporalAdjusters.next(DayOfWeek.MONDAY));List<String> workDays = new ArrayList<>();DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateUtils.YYYYMMDD);for (int i = 0; i < 5; i++) {// 下周一到下周五LocalDate date = nextMonday.plusDays(i);workDays.add(date.format(formatter));}return workDays;}private void clearShardingTable(String tableName, DatabaseShardingConfig.TableShardingConfig config) {if (DS_OLAP.equals(config.getDs())) {try {Connection connection = olapDataSource.getConnection();List<String> nextWeekWorkDays = getToBeClearDays(tableName);nextWeekWorkDays.forEach(day -> {clearShardingTable("olap", connection, tableName, day, config);});} catch (Throwable t) {log.error("clearShardingTable error. db : [olap] tableName : [{}]", tableName, t);}} else {((ShardingDataSource) shardingDataSource).getDataSourceMap().forEach((dbName, myDataSource) -> {if (dbName.equals(dbShardingConfig.getCenterDs())) {// 中心库不删除相关表return;}try {Connection connection = myDataSource.getConnection();List<String> nextWeekWorkDays = getToBeClearDays(tableName);nextWeekWorkDays.forEach(day -> {clearShardingTable(dbName, connection, tableName, day, config);});} catch (Throwable t) {log.error("clearShardingTable error. db : [{}] tableName : [{}]", dbName, tableName, t);}});}}/*** 清理分表** @param dbName     数据库名称* @param connection 数据库连接* @param tableName  表名称* @param day        工作日 - 预留给手动补数据使用*/private void clearShardingTable(String dbName, Connection connection, String tableName, String day, DatabaseShardingConfig.TableShardingConfig config) {if (config.getTableShardingNum() > 1) {for (int i = 0; i < config.getTableShardingNum(); i++) {String realTableName = tableName + "_" + day.substring(2) + "_" + i;try {String sql = String.format(SHARDING_TABLE_CLEAR_SQL, realTableName);connection.createStatement().execute(sql);log.info("clearShardingTable success. db : [{}] tableName : [{}], realTableName : [{}], sql : [{}]", dbName, tableName, realTableName, sql);} catch (Throwable t) {log.error("clearShardingTable error. db : [{}] tableName : [{}], realTableName : [{}]", dbName, tableName, realTableName, t);}}} else {String realTableName = tableName + "_" + day.substring(2);try {String sql = String.format(SHARDING_TABLE_CLEAR_SQL, realTableName);connection.createStatement().execute(sql);log.info("clearShardingTable success. db : [{}] tableName : [{}], realTableName : [{}], sql : [{}]", dbName, tableName, realTableName, sql);} catch (Throwable t) {log.error("clearShardingTable error. db : [{}] tableName : [{}], realTableName : [{}]", dbName, tableName, realTableName, t);}}}/*** 获取待清理的表对应的日期** @param tableName 逻辑表名称* @return 待清理的日期*/private List<String> getToBeClearDays(String tableName) {List<String> days = new ArrayList<>();DatabaseShardingConfig.TableShardingConfig tableShardingConfig = dbShardingConfig.getTableShardingConfig(tableName);LocalDate today = LocalDate.now();LocalDate startDay = today.minusDays(tableShardingConfig.getClearOffset());LocalDate endDay = today.minusDays(tableShardingConfig.getKeepDays());DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateUtils.YYYYMMDD);for (LocalDate date = startDay; date.isBefore(endDay); date = date.plusDays(1)) {days.add(date.format(formatter));}return days;}}
  • 配置
package com.zzc.service.config;@Data
@Slf4j
@RefreshScope
@Configuration
@ConfigurationProperties(prefix = "refinitiv.api-service.db-sharding")
@PropertySource(value = "classpath:guda-refinitiv-api-db-sharding.yaml", factory = YamlPropertySourceFactory.class)
public class DatabaseShardingConfig {private String centerDs;private Map<String, TableShardingConfig> tables;private Map<String, String> marketConfigs;@Setter(AccessLevel.PRIVATE)private Map<String, String> dbMap;@PostConstructpublic void init() {if (marketConfigs == null || marketConfigs.isEmpty()) {throw new RuntimeException("DatabaseShardingConfig error. configs is empty");}Map<String, String> tmp = new HashMap<>();marketConfigs.forEach((dbName, markets) -> {for (String market : markets.split(",")) {tmp.put(market.trim(), dbName);}});dbMap = tmp;log.info("DatabaseShardingConfig init success. config: [{}]", this);}/*** 根据市场类型获取对应的数据库名称** @param market 市场类型(MarketCodeType 枚举的 name)* @return 数据库名称*/public String getDbName(String market) {return dbMap.get(market);}/*** 根据表名获取对应的分库配置** @param tableName 表名* @return 分库配置*/public TableShardingConfig getTableShardingConfig(String tableName) {return tables.get(tableName);}@Data@NoArgsConstructor@AllArgsConstructorpublic static class TableShardingConfig {/** 模板表名 */private String templateTable;/** 分多少张表 */private int tableShardingNum;/** 数据保留天数 */private int keepDays;/** 从哪一天开始清理 */private int clearOffset;/** 数据库名称 */private String ds;/** 是否按日期分表 */private Boolean runCreateJob = true;}
}
refinitiv.api-service:db-sharding:centerDs: 'center'tables:trade_record:# 模版表templateTable: 'trade_record_240101'# 分多少张表tableShardingNum: 250# 数据保留天数keepDays: 7# 从哪一天开始清理(一直清理到 keepDays 为止)clearOffset: 15ds: 'shardingDataSource'olap_quotation_snapshot:# 模版表templateTable: 'olap_quotation_snapshot_240101'# 分多少张表tableShardingNum: 1# 数据保留天数keepDays: 30# 从哪一天开始清理(一直清理到 keepDays 为止)clearOffset: 40ds: 'olapDataSource'kline_m1:# 模版表templateTable: 'kline_m1'# 分多少张表tableShardingNum: 1# 数据保留天数keepDays: 30# 从哪一天开始清理(一直清理到 keepDays 为止)clearOffset: 40ds: 'shardingDataSource'kline:# 模版表templateTable: 'kline'# 分多少张表tableShardingNum: 16# 数据保留天数keepDays: 30# 从哪一天开始清理(一直清理到 keepDays 为止)clearOffset: 40ds: 'shardingDataSource'runCreateJob: falsemarketConfigs:# db0 存储 US, US_PINK, US_OPTION 相关数据# ds2: 'US, US_PINK, US_OPTION'ds1: 'HK, HK_WRNT, HK_BONDA, HK_TRUST'ds0: 'US, US_PINK, US_OPTION, SH, SZ, SZ_INDEX, SZ_FUND, SZ_GEM, US_ETF'

相关文章:

Spring Boot ShardingJDBC分库分表(草稿)

ShardingJDBC分库分表 1.Maven 引用 <dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.1.1</version></dependency><dependency><…...

Jenkins 环境搭建---基于 Docker

前期准备 提前安装jdk、maven、nodeJs&#xff08;如果需要的话&#xff09; 创建 jenkins 环境目录&#xff0c;用来当做挂载卷 /data/jenkins/ 一&#xff1a;拉取 Jenkins 镜像 docker pull jenkins/jenkins:lts 二&#xff1a;设置 Jenkins挂载目录 mkdir -p ~/jen…...

如何在自定义组件中使用v-model实现双向绑定

在 Vue 2 中&#xff0c;v-model 是双向数据绑定的语法糖&#xff0c;它默认将 value 作为 prop 传入组件&#xff0c;并通过监听 input 事件来更新父组件的数据。若要在自定义组件中实现 v-model 的双向绑定&#xff0c;需遵循以下步骤&#xff1a; 1. 基本实现&#xff1a;va…...

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_pool_t 类型

ngx_pool_t 定义在 src/core/ngx_core.h typedef struct ngx_pool_s ngx_pool_t; ngx_pool_s 定义在 src/core/ngx_palloc.h struct ngx_pool_s {ngx_pool_data_t d;size_t max;ngx_pool_t *current;ngx_chain_t *chain;ng…...

如何在 ubuntu 上使用 Clash 与 docker 开启代理拉起

如何在 ubuntu 上使用 Clash https://github.com/doreamon-design/clash/releases上面是clash 的地址 clash_2.0.24_linux_386.tar.gz 下载 386 的 如果你的电脑是inter tar -xzvf clash_2.0.24_linux_386.tar.gz 启动 ./clash 然后会在电脑上生成一个config的文件 /home/xxx/…...

linux tcpdump抓包

参数说明: -i 指定网卡 -w 指定保存文件 -s0 完整抓包 -G 指定间隔时长(秒) -C 指定每个文件大小(M) 用法1: 指定端口输出到指定文件 tcpdump -i em3 -w 182910.pcap 用法2: 指定端口每10分钟输出到不同文件 tcpdump -i em3 -s0 -G 600 -w %Y_%m%d_%H%M_%S.pcap 用法3: 指…...

PLSQL连接Oracle 19c报错ORA-28040

PLSQL连接Oracle 19c报错ORA-28040 原因解析解决办法原因解析 使用PLSQL Developer连接19c数据库报错: ORA-28040: No matching authentication protocol报错信息解析: [oracle@ora19c ~]$ oerr ora 2804028040, 0000, "No matching authentication protocol" /…...

汽车免拆诊断案例 | 2010 款路虎揽胜车空调偶尔出风异常

故障现象  一辆2010款路虎揽胜车&#xff0c;搭载5.0 L发动机&#xff0c;累计行驶里程约为16万km。车主反映&#xff0c;接通空调开关后&#xff0c;有时出风忽大忽小&#xff0c;有时不出风&#xff0c;有时要等2 min左右才出风&#xff1b;有时两三天出现一次&#xff0c;…...

音视频入门基础:RTP专题(9)——FFmpeg接收RTP流的原理和内部实现

一、引言 由《音视频入门基础&#xff1a;RTP专题&#xff08;2&#xff09;——使用FFmpeg命令生成RTP流》可以知道&#xff0c;推流端通过下面FFmpeg命令可以将一个媒体文件转推RTP&#xff0c;生成RTP流&#xff1a; ffmpeg -re -stream_loop -1 -i input.mp4 -vcodec cop…...

Nginx 安装及配置教程(Windows)【安装】

文章目录 一、 Nginx 下载 1. 官网下载2. 其它渠道 二、 Nginx 安装三、 配置四、 验证五、 其它问题 1. 常用命令2. 跨域问题 软件 / 环境安装及配置目录 一、 Nginx 下载 1. 官网下载 安装地址&#xff1a;https://nginx.org/en/download.html 打开浏览器输入网址 htt…...

《跟李沐学 AI》AlexNet论文逐段精读学习心得 | PyTorch 深度学习实战

前一篇文章&#xff0c;使用 AlexNet 实现图片分类 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 本篇文章内容来自于学习 9年后重读深度学习奠基作之一&#xff1a;AlexNet【下】【论文精读】】的心得。 《跟李沐…...

嵌入式0xDEADBEEF

在嵌入式系统中&#xff0c;0xDEADBEEF 是一个常见的“魔数”&#xff08;magic number&#xff09;&#xff0c;通常用于调试和内存管理。它的含义和用途如下&#xff1a; 1. 调试用途 未初始化内存的标记&#xff1a;在调试时&#xff0c;0xDEADBEEF 常用于标记未初始化或已…...

B+树作为数据库索引结构的优势对比

MySQL作为数据库&#xff0c;它的功能就是做数据存储和数据查找&#xff1b;使用B树作为索引结构是为了实现高效的查找、插入和删除操作。 B树的查找、插入、删除的复杂度都为 O(log n)&#xff0c;它是一个多叉树的结构&#xff0c;能兼顾各种操作的效率的数据结构。如果使用…...

自适应SQL计划管理(Adaptive SQL Plan Management)在Oracle 12c中的应用

在Oracle Database 12c Release 1 (12.1)版本中&#xff0c;引入了对SQL计划管理&#xff08;SPM&#xff09;功能的增强&#xff0c;特别是关于SQL计划基线的自动进化机制。这一改进允许数据库更加智能地管理和优化SQL查询的执行计划&#xff0c;确保即使数据分布发生变化&…...

什么是DeFi (去中心化金融)

DeFi (去中心化金融) 概述 &#x1f4b0; 1. DeFi 基础概念 1.1 什么是 DeFi&#xff1f; DeFi 是建立在区块链上的金融服务生态系统&#xff0c;它&#xff1a; 无需中心化中介开放且透明无需许可即可参与代码即法律 1.2 DeFi 的优势 开放性&#xff1a;任何人都可以参与…...

计算机毕业设计Python农产品推荐系统 农产品爬虫 农产品可视化 农产品大数据(源码+LW文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

LLM论文笔记 15: Transformers Can Achieve Length Generalization But Not Robustly

Arxiv日期&#xff1a;2024.2.14机构&#xff1a;Google DeepMind / University of Toronto 关键词 长度泛化位置编码数据格式 核心结论 1. 实验结论&#xff1a;十进制加法任务上的长度泛化最佳组合&#xff1a; FIRE位置编码 随机化位置编码 反向数据格式 索引提示&…...

SpringAI做对了什么

开发&#xff5c;界面&#xff5c;引擎&#xff5c;交付&#xff5c;副驾——重写全栈法则&#xff1a;AI原生的倍速造应用流 你好&#xff0c;这里是nine[谈架构]系列。 欢迎关注评论私信交流~ SpringAI 在 AI 编程领域延续了Spring的诸多优势&#xff0c;从易于集成、到通用…...

DeepSeek预测25考研分数线

25考研分数马上要出了。 目前&#xff0c;多所大学已经陆续给出了分数查分时间&#xff0c;综合往年情况来看&#xff0c;每年的查分时间一般集中在2月底。 等待出成绩的日子&#xff0c;学子们的心情是万分焦急&#xff0c;小编用最近爆火的“活人感”十足的DeepSeek帮大家预…...

C++笔记之标准库中的std::copy 和 std::assign 作用于 std::vector

C++笔记之标准库中的std::copy 和 std::assign 作用于 std::vector code review! 文章目录 C++笔记之标准库中的std::copy 和 std::assign 作用于 std::vector1. `std::copy`1.1.用法1.2.示例2.`std::vector::assign`2.1.用法2.2.示例3.区别总结4.支持assign的容器和不支持ass…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...