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

Flink CDC 同步 Mysql 数据

文章目录

      • 一、Flink CDC、Flink、CDC各有啥关系
        • 1.1 概述
        • 1.2 和 jdbc Connectors 对比
      • 二、使用
        • 2.1 Mysql 打开 bin-log 功能
        • 2.2 在 Mysql 中建库建表准备
        • 2.3 遇到的坑
        • 2.4 测试
      • 三、番外

一、Flink CDC、Flink、CDC各有啥关系

  Flink:流式计算框架,不包含 Flink CDC,和 Flink CDC没关系

  CDC:是一种思想,理念,不涉及某一门具体的技术。CDC 是变更数据捕获(Change Data Capture)技术的缩写,它可以将源数据库(Source)的增量变动记录,同步到一个或多个数据目的(Sink)。在同步过程中,还可以对数据进行一定的处理,例如过滤、关联、分组、统计等。目前专业做数据库事件接受和解析的中间件是Debezium,如果是捕获Mysql,还有Canal。

  Flink CDC:是 CDC 的一种实现而已,不属于 Flink 子版块。这个技术是阿里开发的。目的是为了丰富 Flink 的生态。

1.1 概述

  Flink CDC 基于数据库日志的 Change Data Caputre 技术,实现了全量和增量的一体化读取能力,并借助 Flink 优秀的管道能力和丰富的上下游生态,支持捕获多种数据库的变更,并将这些变更实时同步到下游存储。

1.2 和 jdbc Connectors 对比

  JDBC Connectors 连接器,确实可以读取外部的 数据库。比如:MySQL、Oracle、SqlServer等。但是,JDBC连数据库,只是瞬时操作,没办法持续监听数据库的数据变化。

  Flink CDC Connectors,可以实现数据库的变更捕获,能够持续不断地把变更数据同步到下游的系统中。

官网概述:https://ververica.github.io/flink-cdc-connectors/
github链接:https://github.com/ververica/flink-cdc-connectors

二、使用

  FlinkCDC 同步数据,有两种方式,一种是 FlinkSQL 的方式,一种是Flink DataStream 和 Table API 的方式。

  我这里直接用的是 ieda 测试的 DataStream 方式。

  代码来自:https://github.com/yclxiao/flink-cdc-demo/tree/main/src/main/java/com/yclxiao/flinkcdcdemo

  CloudAcctProfit2DwsHdjProfitRecordAPI.java

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ververica.cdc.connectors.mysql.source.MySqlSource;
import com.ververica.cdc.debezium.JsonDebeziumDeserializationSchema;
import com.xiaoqiang.utils.JdbcUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.api.common.functions.FilterFunction;
import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
import org.apache.flink.util.Collector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.*;public class CloudAcctProfit2DwsHdjProfitRecordAPI {private static final Logger LOG = LoggerFactory.getLogger(CloudAcctProfit2DwsHdjProfitRecordAPI.class);private static String MYSQL_HOST = "x.x.x.x";private static int MYSQL_PORT = 3306;private static String MYSQL_USER = "root";private static String MYSQL_PASSWD = "xiaoqiang";private static String SYNC_DB = "league_test";private static List<String> SYNC_TABLES = Arrays.asList("league_test.oc_settle_profit");public static void main(String[] args) throws Exception {MySqlSource<String> mySqlSource = MySqlSource.<String>builder().hostname(MYSQL_HOST).port(MYSQL_PORT).databaseList(SYNC_DB) // set captured database.tableList(String.join(",", SYNC_TABLES)) // set captured table.username(MYSQL_USER).password(MYSQL_PASSWD).deserializer(new JsonDebeziumDeserializationSchema()) // converts SourceRecord to JSON String.build();StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setParallelism(1);env.enableCheckpointing(5000);DataStreamSource<String> cdcSource = env.fromSource(mySqlSource, WatermarkStrategy.noWatermarks(), "CDC Source" + "xiaoqiang-flink");List<String> tableList = getTableList();System.out.println("tableList--->"+tableList);for (String tbl : tableList) {SingleOutputStreamOperator<String> filterStream = filterTableData(cdcSource, "oc_settle_profit");
//            SingleOutputStreamOperator<String> cleanStream = clean(filterStream);// 流的数据sink出去filterStream.addSink(new CustomDealDataSink()).name("sink " + tbl);}env.execute("xiaoqiang-flink");}/*** 自定义sink*/private static class CustomDealDataSink extends RichSinkFunction<String> {private transient Connection coalitiondbConnection;private transient Statement coalitiondbStatement;private transient Connection cloudConnection;private transient Statement cloudStatement;@Overridepublic void open(Configuration parameters) throws Exception {super.open(parameters);// 在这里初始化 JDBC 连接coalitiondbConnection = DriverManager.getConnection("jdbc:mysql://x.x.x.x:3306/league_test", "root", "");coalitiondbStatement = coalitiondbConnection.createStatement();cloudConnection = DriverManager.getConnection("jdbc:mysql://x.x.x.x:3306/cloud_test", "root", "");cloudStatement = cloudConnection.createStatement();}@Overridepublic void invoke(String value, Context context) throws Exception {// 解析拿到的CDC-JSON数据JSONObject rowJson = JSON.parseObject(value);String outNo = rowJson.getString("out_no");Integer userType = rowJson.getInteger("user_type");String id = rowJson.getString("id");String payOrderNo = rowJson.getString("pay_order_no");String title = rowJson.getString("title");String fromUserId = rowJson.getString("from_user_id");String fromAccountId = rowJson.getString("from_account_id");String userId = rowJson.getString("user_id");String accountId = rowJson.getString("account_id");Integer amount = rowJson.getInteger("amount");Integer profitState = rowJson.getInteger("profit_state");Date profitTime = rowJson.getTimestamp("profit_time");Integer refundState = rowJson.getInteger("refund_state");Date refundTime = rowJson.getTimestamp("refund_time");Date addTime = rowJson.getTimestamp("add_time");String remark = rowJson.getString("remark");String acctCircle = rowJson.getString("acct_circle");Integer fromUserType = rowJson.getInteger("from_user_type");String companyId = rowJson.getString("company_id");String bizCompanyId = rowJson.getString("biz_company_id");
//            if (1 != profitState || !"PG11111".equals(acctCircle)) {
//                return;
//            }
//
//            // 读取相关表的数据(与其他表进行关联)
//            Integer bizType = null;
//            String contributeUserId = null;
//            String relationBrandOwnerId = null;
//            ResultSet virtualOrderResultSet = coalitiondbStatement.executeQuery("select * from tc_virtual_order where order_type != 2 and id = '" + outNo + "'");
//            // 如果是tc_virtual_order订单(上岗卡、安心卡、课程)
//            if (virtualOrderResultSet.next()) {
//                // 处理数据逻辑
//                Integer virtualOrder4OrderType = virtualOrderResultSet.getInt("order_type");
//                String virtualOrder4CompanyId = virtualOrderResultSet.getString("company_id");
//                String virtualOrder4BrandId = virtualOrderResultSet.getString("brand_id");
//                // 上岗卡订单排掉,因为已经有别的任务处理了
//                if (virtualOrder4OrderType == 2) {
//                    return;
//                }
//                // orderType转换
//                if (virtualOrder4OrderType == 6) {
//                    bizType = 10;
//                } else if (virtualOrder4OrderType == 1) {
//                    bizType = 11;
//                } else if (virtualOrder4OrderType == 5) {
//                    bizType = 12;
//                }
//                // userType转换
//                if (virtualOrder4OrderType == 6 && userType == 92) {
//                    contributeUserId = virtualOrder4CompanyId;
//                } else if (virtualOrder4OrderType == 1 && userType == 92) {
//                    contributeUserId = virtualOrder4CompanyId;
//                } else if (virtualOrder4OrderType == 5 && userType == 92) {
//                    contributeUserId = virtualOrder4CompanyId;
//                }
//                // relationBrandOwnerId转换
//                if (virtualOrder4OrderType == 6 && userType == 90) {
//                    relationBrandOwnerId = virtualOrder4BrandId;
//                } else if (virtualOrder4OrderType == 1 && userType == 90) {
//                    relationBrandOwnerId = virtualOrder4BrandId;
//                } else if (virtualOrder4OrderType == 5 && userType == 90) {
//                    relationBrandOwnerId = virtualOrder4BrandId;
//                }
//                // remark转换
//                if (virtualOrder4OrderType == 1 || virtualOrder4OrderType == 5) {
//                    remark = title;
//                }
//            } else {
//                // 如果不是tc_virtual_order的数据,则可能是其他数据,此处只保留好到家实物商品数据
//                if (StringUtils.isBlank(payOrderNo)) {
//                    return;
//                }
//                ResultSet acctPayOrderResultSet = cloudStatement.executeQuery("select * from acct_pay_order t where t.id = '" + payOrderNo + "'");
//                if (!acctPayOrderResultSet.next()) {
//                    return;
//                }
//                Integer payCate = acctPayOrderResultSet.getInt("pay_cate");
//                if (200100 != payCate) { // 好到家实物商品类型
//                    return;
//                }
//
//                bizType = 20;
//                if (userType == 92 && StringUtils.isNotBlank(bizCompanyId)) {
//                    contributeUserId = bizCompanyId;
//                } else if (userType == 90 && StringUtils.isNotBlank(bizCompanyId)) {
//                    ResultSet brandOwnerIdResultSet = cloudStatement.executeQuery("select * from uc_brand_partner t where t.company_id = '" + bizCompanyId + "'");
//                    if (brandOwnerIdResultSet.next()) {
//                        relationBrandOwnerId = brandOwnerIdResultSet.getString("brand_owner_id");
//                    }
//                }
//            }
//            if (StringUtils.isBlank(remark)) {
//                remark = title;
//            }// 数据写入到mysqlString insertSql = "INSERT INTO dws_profit_record_hdj_flink_api (id, show_profit_id, order_no, from_user_id, from_user_type, user_id,\n" +"                                                    user_type, amount, profit_time, state, acct_circle, biz_type,\n" +"                                                    contribute_user_id, relation_brand_owner_id, remark, add_time)\n" +"VALUES ('" + id + "', '" + "JSD" + id + "', '" + outNo + "', '" + fromUserId + "', " + fromUserType + ", '" + userId + "', " + userType + ",\n" +"        " + amount + ", '" + DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss", TimeZone.getTimeZone("GMT")) + "', " + profitState + ", '" + acctCircle + "', " + 1 + ", " + (StringUtils.isBlank("123") ? null : "'" + "contributeUserId" + "'") + ", " + (StringUtils.isBlank("relationBrandOwnerId") ? null : "'" + "relationBrandOwnerId" + "'") + ", '" + remark + "',\n" +"        '" + DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss", TimeZone.getTimeZone("GMT")) + "');";cloudStatement.execute("delete from dws_profit_record_hdj_flink_api where id = '" + id + "'");System.out.println("insertSql--->"+insertSql);cloudStatement.execute(insertSql);}@Overridepublic void close() throws Exception {super.close();// 在这里关闭 JDBC 连接coalitiondbStatement.close();coalitiondbConnection.close();cloudStatement.close();cloudConnection.close();}}/*** 清晰数据** @param source* @return*/private static SingleOutputStreamOperator<String> clean(SingleOutputStreamOperator<String> source) {return source.flatMap(new FlatMapFunction<String, String>() {@Overridepublic void flatMap(String row, Collector<String> out) throws Exception {try {LOG.info("============================row:{}", row);JSONObject rowJson = JSON.parseObject(row);String op = rowJson.getString("op");//history,insert,updateif (Arrays.asList("r", "c", "u").contains(op)) {out.collect(rowJson.getJSONObject("after").toJSONString());} else {LOG.info("filter other op:{}", op);}} catch (Exception ex) {LOG.warn("filter other format binlog:{}", row);}}});}/*** 过滤数据** @param source* @param table* @return*/private static SingleOutputStreamOperator<String> filterTableData(DataStreamSource<String> source, String table) {return source.filter(new FilterFunction<String>() {@Overridepublic boolean filter(String row) throws Exception {try {JSONObject rowJson = JSON.parseObject(row);JSONObject source = rowJson.getJSONObject("source");String tbl = source.getString("table");return table.equals(tbl);} catch (Exception ex) {ex.printStackTrace();return false;}}});}private static List<String> getTableList() {List<String> tables = new ArrayList<>();String sql = "SELECT TABLE_SCHEMA,TABLE_NAME FROM information_schema.tables WHERE TABLE_SCHEMA = '" + SYNC_DB + "'";List<JSONObject> tableList = JdbcUtil.executeQuery(MYSQL_HOST, MYSQL_PORT, MYSQL_USER, MYSQL_PASSWD, sql);for (JSONObject jsob : tableList) {String schemaName = jsob.getString("TABLE_SCHEMA");String tblName = jsob.getString("TABLE_NAME");String schemaTbl = schemaName + "." + tblName;if (SYNC_TABLES.contains(schemaTbl)) {tables.add(tblName);}}return tables;}
}

  JdbcUtil.java

import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.sql.*;
import java.util.ArrayList;
import java.util.List;public class JdbcUtil {static {try {
//            Class.forName("com.mysql.cj.jdbc.Driver");Class.forName("com.mysql.jdbc.Driver");} catch (ClassNotFoundException e) {e.printStackTrace();}}private static final Logger LOG = LoggerFactory.getLogger(JdbcUtil.class);public static void main(String[] args) throws SQLException {}public static List<JSONObject> executeQuery(String hostUrl, int port, String user, String password, String sql) {List<JSONObject> beJson = new ArrayList<>();String connectionUrl = String.format("jdbc:mysql://%s:%s/league_test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai", hostUrl, port);Connection con = null;try {con = DriverManager.getConnection(connectionUrl, user, password);PreparedStatement ps = con.prepareStatement(sql);ResultSet rs = ps.executeQuery();beJson = resultSetToJson(rs);} catch (SQLException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();} finally {try {con.close();} catch (Exception e) {}}return beJson;}private static List<JSONObject> resultSetToJson(ResultSet rs) throws SQLException {List<JSONObject> list = new ArrayList<>();ResultSetMetaData metaData = rs.getMetaData();int columnCount = metaData.getColumnCount();while (rs.next()) {JSONObject jsonObj = new JSONObject();for (int i = 1; i <= columnCount; i++) {String columnName = metaData.getColumnLabel(i);String value = rs.getString(columnName);jsonObj.put(columnName, value);}list.add(jsonObj);}return list;}
}

  pom.xml:

        <dependency><groupId>com.ververica</groupId><artifactId>flink-connector-mysql-cdc</artifactId><version>2.4.0</version></dependency>
2.1 Mysql 打开 bin-log 功能

  og_bin 的Value如果为ON代表开启,如果为OFF代表关闭,MySQL8.0默认是开启的:

# 查看是否开启binlog
mysql> SHOW VARIABLES LIKE '%log_bin%';

  关闭状态:

在这里插入图片描述

  • log_bin为ON代表MySQL已经开启binlog日志记录
  • log_bin_basename配置了binlog的文件路径及文件前缀名
  • log_bin_index配置了binlog索引文件的路径

  开启状态:

在这里插入图片描述

# 在centos中mysql的配置文件一般都在/etc/mysql目录下,如果不在可以通过 find / -name "my.cnf" 查找
vi /etc/mysql/my.cnf# 服务ID
server-id=1
# binlog 配置 只要配置了log_bin地址 就会开启
log_bin = /var/lib/mysql/mysql_bin
# 日志存储天数 默认0 永久保存
# 如果数据库会定期归档,建议设置一个存储时间不需要一直存储binlog日志,理论上只需要存储归档之后的日志
expire_logs_days = 30
# binlog最大值
max_binlog_size = 1024M
# 规定binlog的格式,binlog有三种格式statement、row、mixad,默认使用statement,建议使用row格式
binlog_format = ROW
# 在提交n次事务后,进行binlog的落盘,0为不进行强行的刷新操作,而是由文件系统控制刷新日志文件,如果是在线交易和账有关的数据建议设置成1,如果是其他数据可以保持为0即可
sync_binlog = 1# 重启MySQL服务使配置生效
systemctl restart mysqld / service mysql restart# 查看日志列表
SHOW MASTER LOGS;

可参考:MySQL 开启配置binlog以及通过binlog恢复数据

2.2 在 Mysql 中建库建表准备
CREATE DATABASE IF NOT EXISTS cloud_test;
CREATE DATABASE IF NOT EXISTS league_test;CREATE TABLE league_test.oc_settle_profit (id                           varchar(32),show_profit_id               varchar(32),order_no                     varchar(32),from_user_id                 varchar(32),from_user_type               int(11),user_id                      varchar(32),user_type                    int(11),rate                         int(11),amount                       int(11),type                         int(11),add_time                     datetime,state                        int(11),expect_profit_time           datetime,profit_time                  datetime,profit_mode                  int(11),opt_code                     varchar(32),opt_name                     varchar(32),acct_circle                  varchar(32),process_state                int(11),parent_id                    varchar(32),keep_account_from_user_id    varchar(32),keep_account_from_bm_user_id varchar(32),keep_account_user_id         varchar(32),keep_account_bm_user_id      varchar(32),biz_type                     int(11),remark                       varchar(32),contribute_user_id           varchar(32),relation_brand_owner_id      varchar(32),PRIMARY KEY (id) USING BTREE
);CREATE TABLE cloud_test.dws_profit_record_hdj_flink_api (id                      varchar(32),show_profit_id          varchar(32),order_no                varchar(32),from_user_id            varchar(32),from_user_type          int(11),user_id                 varchar(32),user_type               int(11),amount                  int(11),profit_time             datetime,state                   int(11),acct_circle             varchar(32),biz_type                int(11),contribute_user_id      varchar(32),relation_brand_owner_id varchar(32),remark                  varchar(32),add_time                datetime,PRIMARY KEY (id) USING BTREE);
2.3 遇到的坑

  用 JDBC 连接 Mysql 的时候报错:The MySQL server has a timezone offset (0 seconds ahead of UTC)

  原因:从错误即可知道是时区的错误。

show variables like '%time_zone%';
Variable_name   |Value |
----------------+------+
time_zone       |SYSTEM|// 或者下面这条命令
SELECT @@global.time_zone;

  解决:使用 root 用户登录 mysql,再执行 set global time_zone='+8:00' 命令。

  注意:一开始改成了 SET GLOBAL time_zone = 'Asia/Shanghai',但并不好使。

2.4 测试

  Idea 启动程序后,在 oc_settle_profit 表中插入数据后 dws_profit_record_hdj_flink_api 也可以同步插入相应的数据。

参考:
【博学谷学习记录】超强总结,用心分享|大数据之flinkCDC
一次打通FlinkCDC同步Mysql数据

三、番外

  用 Flink CDC 可以监控 Mysql,但无法监控 StarRocks,和官方询问过,目前 StarRocks 并没有像 Mysql 这样被外部感知 DDL 操作的 bin-log 功能,所以暂时还无法用 Flink CDC 监控 StarRocks。

相关文章:

Flink CDC 同步 Mysql 数据

文章目录 一、Flink CDC、Flink、CDC各有啥关系1.1 概述1.2 和 jdbc Connectors 对比 二、使用2.1 Mysql 打开 bin-log 功能2.2 在 Mysql 中建库建表准备2.3 遇到的坑2.4 测试 三、番外 一、Flink CDC、Flink、CDC各有啥关系 Flink&#xff1a;流式计算框架&#xff0c;不包含 …...

【python实战】-- 根据文件名分类

系列文章目录 文章目录 系列文章目录前言一、根据文件名分类到不同文件夹总结 前言 一、根据文件名分类到不同文件夹 汇总指定目录下所有满足条件的文件到新文件夹 import os import shutil import globsource_dir rD:\Users\gxcaoty\Desktop\39642 # 源目录路径 destinatio…...

蓝桥双周赛 第21场 小白入门赛

1 动态密码 思路&#xff1a;可以直接填空也可以写程序 void solve() {int a 20241111;stack<int> stk;while(a){stk.push(a % 2);a / 2;}while(stk.size()){cout << stk.top();stk.pop();}} 2 购物车里的宝贝 思路&#xff1a;总体异或和为0即可说明可分成一样…...

Linux 进程间通信 共享内存_消息队列_信号量

共享内存 共享内存是一种进程间通信&#xff08;IPC&#xff09;机制&#xff0c;它允许多个进程访问同一块内存区域。这种方法可以提高效率&#xff0c;因为数据不需要在进程之间复制&#xff0c;而是可以直接在共享的内存空间中读写。 使用共享内存的步骤通常包括&#xff1a…...

Mybatis自定义日志打印

一&#xff0c;目标 替换?为具体的参数值统计sql执行时间记录执行时间过长的sql&#xff0c;并输出信息到文档&#xff08;以天为单位进行存储&#xff09; 平常打印出来的sql都是sql一行&#xff0c;参数一行。如图&#xff1a; 二&#xff0c;理论 这里我们主要通过Mybatis…...

【在Linux世界中追寻伟大的One Piece】Socket编程TCP(续)

目录 1 -> V2 -Echo Server多进程版本 2 -> V3 -Echo Server多线程版本 3 -> V3-1 -多线程远程命令执行 4 -> V4 -Echo Server线程池版本 1 -> V2 -Echo Server多进程版本 通过每个请求&#xff0c;创建子进程的方式来支持多连接。 InetAddr.hpp #pragma…...

面试高频问题:C/C++编译时内存五个分区

在面试时,C/C++编译时内存五个分区是经常问到的问题,面试官通过这个问题来考察面试者对底层的理解。在平时开发时,懂编译时内存分区,也有助于自己更好管理内存。 目录 内存分区的定义 内存分区的重要性 代码区 数据区 BSS区 堆区 栈区 静态内存分配 动态内存分配…...

阅读博士论文《功率IGBT模块健康状态监测方法研究》

IGBT的失效可以分为芯片级失效和封装级失效。其中封装级失效是IGBT模块老化的主要原因&#xff0c;是多种因素共同作用的结果。在DBC的这种结构中&#xff0c;流过芯片的负载电流通过键合线传导到 DBC上层铜箔&#xff0c;再经过端子流出模块。DBC与芯片和提供机械支撑的基板之…...

Spring ApplicationContext接口

ApplicationContext接口是Spring框架中更高级的IoC容器接口&#xff0c;扩展了BeanFactory接口&#xff0c;提供了更多的企业级功能。ApplicationContext不仅具备BeanFactory的所有功能&#xff0c;还增加了事件发布、国际化、AOP、资源加载等功能。 ApplicationContext接口的…...

[perl] 数组与哈希

数组变量以 符号开始&#xff0c;元素放在括号内 简单举例如下 #!/usr/bin/perl names ("a1", "a2", "a3");print "\$names[0] $names[0]\n"; print "size: ",scalar names,"\n";$new_names shift(names); …...

电机学习-SPWM原理及其MATLAB模型

SPWM原理及其MATLAB模型 一、SPWM原理二、基于零序分量注入的SPWM三、MATLAB模型 一、SPWM原理 SPWM其实是相电压的控制方式&#xff0c;定义三相正弦相电压的表达式&#xff1a; { V a m V m sin ⁡ ω t V b m V m sin ⁡ ( ω t − 2 3 π ) V c m V m sin ⁡ ( ω t 2…...

群控系统服务端开发模式-应用开发-腾讯云上传工厂及七牛云上传工厂开发

记住业务流程图&#xff0c;要不然不清楚自己封装的是什么东西。 一、腾讯云工厂开发 切记在根目录下要安装腾讯云OSS插件&#xff0c;具体代码如下&#xff1a; composer require qcloud/cos-sdk-v5 在根目录下extend文件夹下Upload文件夹下channel文件夹中&#xff0c;我们修…...

【深度学习滑坡制图|论文解读3】基于融合CNN-Transformer网络和深度迁移学习的遥感影像滑坡制图方法

【深度学习滑坡制图|论文解读3】基于融合CNN-Transformer网络和深度迁移学习的遥感影像滑坡制图方法 【深度学习滑坡制图|论文解读3】基于融合CNN-Transformer网络和深度迁移学习的遥感影像滑坡制图方法 文章目录 【深度学习滑坡制图|论文解读3】基于融合CNN-Transformer网络和…...

《计算机原理与系统结构》学习系列——处理器(下)

系列文章目录 目录 流水线冒险数据冒险数据相关与数据冒险寄存器先读后写旁路取数使用型冒险阻塞 控制冒险分支引发的控制冒险假设分支不发生动态分支预测双预测位动态分支预测缩短分支延迟带冒险控制的单周期流水线图 异常MIPS中的异常MIPS中的异常处理另一种异常处理机制非精…...

JDK新特性(8-21)数据类型-直接内存

目录 Jdk 新特性 JDK 8 特性 默认方法实现作用:可以使接口更加灵活&#xff0c;不破坏现有实现的情况下添加新的方法。 函数式接口 StreamAPI JDK 9 特性 JDK 10 特性 JDK 11 特性 JDK 14 特性 JDK 17 特性 JDK 21 特性 数据类型 基本数据类型和引用数据类型的区别…...

003-Kotlin界面开发之声明式编程范式

概念本源 在界面程序开发中&#xff0c;有两个非常典型的编程范式&#xff1a;命令式编程和声明式编程。命令式编程是指通过编写一系列命令来描述程序的运行逻辑&#xff0c;而声明式编程则是通过编写一系列声明来描述程序的状态。在命令式编程中&#xff0c;程序员需要关心程…...

QT pro项目工程的条件编译

QT pro项目工程的条件编译 前言 项目场景&#xff1a;项目中用到同一型号两个相机&#xff0c;同时导入两个版本有冲突&#xff0c;编译不通过&#xff0c; 故从编译就区分相机导入调用&#xff0c;使用宏区分 一、定义宏 在pro文件中定义宏&#xff1a; DEFINES USE_Cam…...

深度学习之经典网络-AlexNet详解

AlexNet 是一种经典的卷积神经网络&#xff08;CNN&#xff09;架构&#xff0c;在 2012 年的 ImageNet 大规模视觉识别挑战赛&#xff08;ILSVRC&#xff09;中表现优异&#xff0c;将 CNN 引入深度学习的新时代。AlexNet 的设计在多方面改进了卷积神经网络的架构&#xff0c;…...

部署Prometheus、Grafana、Zipkin、Kiali监控度量Istio

1. 模块简介 Prometheus 是一个开源的监控系统和时间序列数据库。Istio 使用 Prometheus 来记录指标&#xff0c;跟踪 Istio 和网格中的应用程序的健康状况。Grafana 是一个用于分析和监控的开放平台。Grafana 可以连接到各种数据源&#xff0c;并使用图形、表格、热图等将数据…...

结合 Spring Boot Native 和 Spring Boot 构建高性能服务器架构

随着云计算和微服务架构的普及&#xff0c;开发者们不断寻求提高应用性能和用户体验的解决方案。Spring Boot Native 的出现&#xff0c;利用 GraalVM 的原生映像特性&#xff0c;使得 Java 应用的启动速度和资源占用得到了显著改善。本文将深入探讨如何将前端应用使用 Spring …...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...