Mysql实时数据同步工具Alibaba Canal 使用

目录

  • Mysql实时数据同步工具Alibaba Canal 使用
    • Canal是什么?
      • 工作原理
      • 重要版本更新说明
    • 环境准备
    • 安装Canal
      • window
    • Java : Canal Client 集成
      • 依赖
      • 编码
    • 工作流程
    • 开启原生MQ
      • RocketMQ 安装部署
    • canal配置说明
      • 1.1 canal.properties常用配置介绍:
      • 2.common参数定义,比如可以将instance.properties的公用参数,抽取放置到这里,这样每个instance启动的时候就可以共享.(instance.properties配置定义优先级高于`canal.properties`)
      • 1.2 `instance.properties`常用配置介绍
    • 其他学习canal资料

个人主页: 【⭐️个人主页】
需要您的【💖 点赞+关注】支持 💯


在这里插入图片描述

Mysql实时数据同步工具Alibaba Canal 使用

📖 本文核心知识点:

  • Canal 是什么
  • 安装Canal 服务
  • 使用Canal 客户端
  • 原生集成数据MQ
  • 同步数据客户端服务【业务】

Canal是什么?

canal [kə’næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费

早期阿里巴巴因为杭州和美国双机房部署,存在跨机房同步的业务需求,实现方式主要是基于业务 trigger 获取增量变更。从 2010 年开始,业务逐步尝试数据库日志解析获取增量变更进行同步,由此衍生出了大量的数据库增量订阅和消费业务。

基于日志增量订阅和消费的业务包括

  • 数据库镜像
  • 数据库实时备份
  • 索引构建和实时维护(拆分异构索引、倒排索引等)
  • 业务 cache 刷新
  • 带业务逻辑的增量数据处理

当前的 canal 支持源端 MySQL 版本包括 5.1.x , 5.5.x , 5.6.x , 5.7.x , 8.0.x

工作原理

MySQL主备复制原理

  • MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事件binary log events,可以通过 show binlog events 进行查看)
  • MySQL slave 将 master 的 binary log events 拷贝到它的中继日志(relay log)
  • MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据
    canal 工作原理
  • canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议
  • MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
  • canal 解析 binary log 对象(原始为 byte 流)

重要版本更新说明

canal 1.1.x 版本(release_note),性能与功能层面有较大的突破,重要提升包括:

  • 整体性能测试&优化,提升了150%. #726 参考: Performance
  • 原生支持prometheus监控 #765 Prometheus QuickStart
  • 原生支持kafka消息投递 #695 Canal Kafka/RocketMQ QuickStart
  • 原生支持aliyun rds的binlog订阅 (解决自动主备切换/oss binlog离线解析) 参考: Aliyun RDS QuickStart
  • 原生支持docker镜像 #801 参考: Docker QuickStart
    canal 1.1.4版本,迎来最重要的WebUI能力,引入canal-admin工程,支持面向WebUI的canal动态管理能力,支持配置、任务、日志等在线白屏运维能力, Canal admin guide

环境准备

安装Canal

DownLoad

版本: 1.1.7

window

  1. 下载 tar.gz包,解压
    GitHub Canal
  2. 配置文件设置:
    解压完后修改配置文件
    查看conf/canal.properties,其中canal.port是客户端连接的端口,需要放开,canal.admin.usercanal.admin.passwd是客户端连接的账号
    在这里插入图片描述
    再打开conf/example/ instance.properties, master.address填数据库地址,dbUsernamedbPassword是数据库账号,flter.regex可以用来过滤数据库,默认是监听所有数据库,如果想监听db_开头的数据可以这么写db_.*\\..*,多个用逗号分隔
    在这里插入图片描述
  3. 启动服务 bin/startup.bat
    log/canal.log
    在这里插入图片描述

Java : Canal Client 集成

依赖

    implementation 'com.alibaba.otter:canal.client:1.1.7'implementation 'com.alibaba.otter:canal.protocol:1.1.7'

具体的数据库数据变化 业务实现方面需要 自己手动去实现,仅展示自己使用的部分。

需要注意: 如果是多个客户端同时使用,要注意:多个客户端会出现某个客户端 把消息全部消费,而别的客户端没有消息消费的情况,这里需要特别注意

编码

package com.kongxiang.infrastructure.canal;import com.alibaba.otter.canal.client.CanalConnector;
import com.alibaba.otter.canal.client.CanalConnectors;
import com.alibaba.otter.canal.protocol.CanalEntry;
import com.alibaba.otter.canal.protocol.Message;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ThreadUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.List;
import java.util.function.Consumer;/*** @author 孔翔* @since 2023-12-27* copyright for author : 孔翔 at 2023-12-27* study-spring3*/
@Component
@Slf4j
public class CanalService {private String canalMonitorHost = "localhost";private int canalMonitorPort = 11111;private String filterRegexTable = "xkongdb\\..*";private final static int BATCH_SIZE = 10000;@Async("canalTask")public void startCanal() {Consumer<CanalConnector> connectorConsumer = new ConsumerTask();while (true) {executeCanal(connectorConsumer);try {//防止频繁访问数据库链接: 线程睡眠 10秒ThreadUtils.sleep(Duration.ofSeconds(10));log.debug("防止频繁访问数据库链接: 线程睡眠 10秒");} catch (InterruptedException e) {e.printStackTrace();Thread.currentThread().interrupt();}}}public void executeCanal(Consumer<CanalConnector> runnable) {CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress(canalMonitorHost, canalMonitorPort), "example", "admin", "4ACFE3202A5FF5CF467898FC58AAB1D615029441");try {//打开连接connector.connect();log.debug("数据库检测连接成功!" + filterRegexTable);//订阅数据库表,全部表qconnector.subscribe(filterRegexTable);//回滚到未进行ack的地方,下次fetch的时候,可以从最后一个没有ack的地方开始拿connector.rollback();if (runnable != null) {runnable.accept(connector);}} catch (Exception e) {e.printStackTrace();log.error("成功断开监测连接!尝试重连");} finally {connector.disconnect();}}public static class ConsumerTask implements Consumer<CanalConnector> {public void handleMessage(List<CanalEntry.Entry> entries) throws InvalidProtocolBufferException {for (CanalEntry.Entry entry : entries) {if (entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONBEGIN || entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONEND) {continue;}//根据数据库名获取租户名String databaseName = entry.getHeader().getSchemaName();String tableName = entry.getHeader().getTableName();log.info("数据库: {}, 表名: {}", databaseName, tableName);// 获取类型CanalEntry.EntryType entryType = entry.getEntryType();// 获取序列化后的数据ByteString storeValue = entry.getStoreValue();if (CanalEntry.EntryType.ROWDATA.equals(entryType)) {// 反序列化数据CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(storeValue);// 获取当前事件的操作类型CanalEntry.EventType eventType = rowChange.getEventType();if (eventType == CanalEntry.EventType.INSERT || eventType == CanalEntry.EventType.UPDATE|| eventType == CanalEntry.EventType.DELETE) {// 获取数据集List<CanalEntry.RowData> rowDataList = rowChange.getRowDatasList();// 遍历rowDataList,并打印数据集for (CanalEntry.RowData rowData : rowDataList) {List<CanalEntry.Column> afterColumnsList = rowData.getAfterColumnsList();List<CanalEntry.Column> beforeColumnsList = rowData.getBeforeColumnsList();// 变更前数据for (CanalEntry.Column column : beforeColumnsList) {log.info("变更前数据: name: {}, value: {} ,update {}", column.getName(), column.getValue(), column.getUpdated());}// 变更后数据for (CanalEntry.Column column : afterColumnsList) {log.info("变更后数据: name: {}, value: {} ,update {}", column.getName(), column.getValue(), column.getUpdated());}}}}}}@Overridepublic void accept(CanalConnector connector) {while (true) {// 获取指定数量的数据Message message = connector.getWithoutAck(BATCH_SIZE);long batchId = message.getId();int size = message.getEntries().size();if (batchId == -1 || size == 0) {} else {try {log.debug("从canal接收到: {} 条消息,消息批次: {},开始处理", size, message.getId());handleMessage(message.getEntries());} catch (Exception e) {connector.rollback(batchId); // 处理失败, 回滚数据}}// 提交确认connector.ack(batchId);}}}
}

测试代码

@Test
public class CanalTest {@Testpublic void testListener() {CanalService canalService = new CanalService();canalService.startCanal();}
}

测试结果

  1. xkongdb的数据表的数据进行 insert,update,delete的时候,就会触发canal任务执行。
  2. 日志 在这里插入图片描述

工作流程

在这里插入图片描述

开启原生MQ

canal 1.1.1版本之后, 默认支持将canal server接收到的binlog数据直接投递到MQ, 目前默认支持的MQ系统有:

  • kafka
  • RocketMQ官网RocketMQ

RocketMQ 安装部署

使用MQ: RocketMQ 。 安装下载
这里使用版本: RocketMQ: 5.1.4
安装教程可以参考:

  • RocketMQ(1) 基础介绍和单机-集群安装
  • 官网教程
  • 官网文档:部署方式

问题:windows11环境下rocketmq启动start mqnamesrv.cmd报错此时不应有 \rocketmq-all-5.0.0-ALPHA-bin-release\bin)
保证目录路径不能有 空格字符

canal配置说明

Canal的启动,是以创建实例(instance)的方式,每个实例都有自己单独的工作环境,

而配置也分成两个部分

  • canal.properties (系统根配置文件)
  • instance.properties (instance级别的配置文件,每个instance一份)

1.1 canal.properties常用配置介绍:

参数名字参数说明默认值
canal.destinations当前server上部署的instance列表
canal.conf.dirconf/目录所在的路径…/conf
canal.auto.scan开启instance自动扫描 如果配置为true,canal.conf.dir目录下的instance配置变化会自动触发: a. instance目录新增: 触发instance配置载入,lazy为true时则自动启动 b. instance目录删除:卸载对应instance配置,如已启动则进行关闭 c. instance.properties文件变化:reload instance配置,如已启动自动进行重启操作true
canal.auto.scan.intervalinstance自动扫描的间隔时间,单位秒5
canal.instance.global.mode全局配置加载方式spring
canal.instance.global.lazy全局lazy模式false
canal.instance.global.manager.address全局的manager配置方式的链接信息
canal.instance.global.spring.xml全局的spring配置方式的组件文件classpath:spring/memory-instance.xml (spring目录相对于canal.conf.dir)
canal.instance.example.mode canal.instance.example.lazy canal.instance.example.spring.xml …instance级别的配置定义,如有配置,会自动覆盖全局配置定义模式 命名规则:canal.instance.{name}.xxx
canal.instance.tsdb.spring.xmlv1.0.25版本新增,全局的tsdb配置方式的组件文件classpath:spring/tsdb/h2-tsdb.xml (spring目录相对于canal.conf.dir)

2.common参数定义,比如可以将instance.properties的公用参数,抽取放置到这里,这样每个instance启动的时候就可以共享.(instance.properties配置定义优先级高于canal.properties)

参数名字参数说明默认值
canal.id每个canal server实例的唯一标识,暂无实际意义1
canal.ipcanal server绑定的本地IP信息,如果不配置,默认选择一个本机IP进行启动服务
canal.register.ipcanal server注册到外部zookeeper、admin的ip信息 (针对docker的外部可见ip)
canal.portcanal server提供socket服务的端口11111
canal.zkServerscanal server链接zookeeper集群的链接信息 例子:10.20.144.22:2181,10.20.144.51:2181
canal.zookeeper.flush.periodcanal持久化数据到zookeeper上的更新频率,单位毫秒1000
canal.instance.memory.batch.modecanal内存store中数据缓存模式 1. ITEMSIZE : 根据buffer.size进行限制,只限制记录的数量 2. MEMSIZE : 根据buffer.size * buffer.memunit的大小,限制缓存记录的大小MEMSIZE
canal.instance.memory.buffer.sizecanal内存store中可缓存buffer记录数,需要为2的指数16384
canal.instance.memory.buffer.memunit内存记录的单位大小,默认1KB,和buffer.size组合决定最终的内存使用大小1024
canal.instance.transactionn.size最大事务完整解析的长度支持 超过该长度后,一个事务可能会被拆分成多次提交到canal store中,无法保证事务的完整可见性1024
canal.instance.fallbackIntervalInSecondscanal发生mysql切换时,在新的mysql库上查找binlog时需要往前查找的时间,单位秒 说明:mysql主备库可能存在解析延迟或者时钟不统一,需要回退一段时间,保证数据不丢60
canal.instance.detecting.enable是否开启心跳检查false
canal.instance.detecting.sql心跳检查sqlinsert into retl.xdual values(1,now()) on duplicate key update x=now()
canal.instance.detecting.interval.time心跳检查频率,单位秒3
canal.instance.detecting.retry.threshold心跳检查失败重试次数3
canal.instance.detecting.heartbeatHaEnable心跳检查失败后,是否开启自动mysql自动切换 说明:比如心跳检查失败超过阀值后,如果该配置为true,canal就会自动链到mysql备库获取binlog数据false
canal.instance.network.receiveBufferSize网络链接参数,SocketOptions.SO_RCVBUF16384
canal.instance.network.sendBufferSize网络链接参数,SocketOptions.SO_SNDBUF16384
canal.instance.network.soTimeout网络链接参数,SocketOptions.SO_TIMEOUT30
canal.instance.filter.druid.ddl是否使用druid处理所有的ddl解析来获取库和表名true
canal.instance.filter.query.dcl是否忽略dcl语句false
canal.instance.filter.query.dml是否忽略dml语句 (mysql5.6之后,在row模式下每条DML语句也会记录SQL到binlog中,可参考MySQL文档)false
canal.instance.filter.query.ddl是否忽略ddl语句false
canal.instance.filter.table.error是否忽略binlog表结构获取失败的异常(主要解决回溯binlog时,对应表已被删除或者表结构和binlog不一致的情况)false
canal.instance.filter.rows是否dml的数据变更事件(主要针对用户只订阅ddl/dcl的操作)false
canal.instance.filter.transaction.entry是否忽略事务头和尾,比如针对写入kakfa的消息时,不需要写入TransactionBegin/Transactionend事件false
canal.instance.binlog.format支持的binlog format格式列表 (otter会有支持format格式限制)ROW,STATEMENT,MIXED
canal.instance.binlog.image支持的binlog image格式列表 (otter会有支持format格式限制)FULL,MINIMAL,NOBLOB
canal.instance.get.ddl.isolationddl语句是否单独一个batch返回(比如下游dml/ddl如果做batch内无序并发处理,会导致结构不一致)false
canal.instance.parser.parallel是否开启binlog并行解析模式(串行解析资源占用少,但性能有瓶颈, 并行解析可以提升近2.5倍+)true
canal.instance.parser.parallelBufferSizebinlog并行解析的异步ringbuffer队列 (必须为2的指数)256
canal.instance.tsdb.enable是否开启tablemeta的tsdb能力true
canal.instance.tsdb.dir主要针对h2-tsdb.xml时对应h2文件的存放目录,默认为conf/xx/h2.mv.db c a n a l . f i l e . d a t a . d i r : . . / c o n f / {canal.file.data.dir:../conf}/ canal.file.data.dir:../conf/
canal.instance.tsdb.urljdbc url的配置(h2的地址为默认值,如果是mysql需要自行定义)jdbc:h2:${canal.instance.tsdb.dir}/h2;CACHE_SIZE=1000;MODE=MYSQL;
canal.instance.tsdb.dbUsernamejdbc url的配置(h2的地址为默认值,如果是mysql需要自行定义)canal
canal.instance.tsdb.dbPasswordjdbc url的配置(h2的地址为默认值,如果是mysql需要自行定义)canal
canal.instance.rds.accesskeyaliyun账号的ak信息(如果不需要在本地binlog超过18小时被清理后自动下载oss上的binlog,可以忽略该值
canal.instance.rds.secretkeyaliyun账号的sk信息(如果不需要在本地binlog超过18小时被清理后自动下载oss上的binlog,可以忽略该值)
canal.admin.managercanal链接canal-admin的地址 (v1.1.4新增)
canal.admin.portadmin管理指令链接端口 (v1.1.4新增)11110
canal.admin.useradmin管理指令链接的ACL配置 (v1.1.4新增)admin
canal.admin.passwdadmin管理指令链接的ACL配置 (v1.1.4新增)密码默认值为admin的密文
canal.usercanal数据端口订阅的ACL配置 (v1.1.4新增)如果为空,代表不开启
canal.passwdcanal数据端口订阅的ACL配置 (v1.1.4新增)如果为空,代表不开启

1.2 instance.properties常用配置介绍

在canal.properties定义了canal.destinations后,需要在canal.conf.dir对应的目录下建立同名的文件

比如:

·canal.destinations = example1,example2
这时需要创建example1和example2两个目录,每个目录里各自有一份instance.properties.

参数名字参数说明默认值
canal.instance.mysql.slaveIdmysql集群配置中的serverId概念,需要保证和当前mysql集群中id唯一 (v1.1.x版本之后canal会自动生成,不需要手工指定)
canal.instance.master.addressmysql主库链接地址127.0.0.1:3306
canal.instance.master.journal.namemysql主库链接时起始的binlog文件
canal.instance.master.positionmysql主库链接时起始的binlog偏移量
canal.instance.master.timestampmysql主库链接时起始的binlog的时间戳
canal.instance.gtidon是否启用mysql gtid的订阅模式false
canal.instance.master.gtidmysql主库链接时对应的gtid位点
canal.instance.dbUsernamemysql数据库帐号canal
canal.instance.dbPasswordmysql数据库密码canal
canal.instance.defaultDatabaseNamemysql链接时默认schema
canal.instance.connectionCharsetmysql 数据解析编码UTF-8
canal.instance.filter.regexmysql 数据解析关注的表,Perl正则表达式.多个正则之间以逗号(,)分隔,转义符需要双斜杠() 常见例子:1. 所有表:.* or . 2. canal schema下所有表: canal…* 3. canal下的以canal打头的表:canal.canal.* 4. canal schema下的一张表:canal.test15. 多个规则组合使用:canal…*,mysql.test1,mysql.test2 (逗号分隔).
canal.instance.filter.black.regexmysql 数据解析表的黑名单,表达式规则见白名单的规则
canal.instance.rds.instanceIdaliyun rds对应的实例id信息(如果不需要在本地binlog超过18小时被清理后自动下载oss上的binlog,可以忽略该值)

其他学习canal资料

  • 【开源实战】阿里开源MySQL中间件Canal快速入门
    mysql的binlog开启方式
  • Canal连接MQ
  • RocketMQ(1) 基础介绍和单机-集群安装

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/587474.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分库分表之Mycat应用学习一

1 为什么要分库分表 1.1 数据库性能瓶颈的出现 对于应用来说&#xff0c;如果数据库性能出现问题&#xff0c;要么是无法获取连接&#xff0c;是因为在高并发的情况下连接数不够了。要么是操作数据变慢&#xff0c;数据库处理数据的效率除了问题。要么是存储出现问题&#xf…

C#中使用is关键字检查对象是否与给定类型兼容

目录 一、定义 二、示例 三、生成 在程序的开发过程中经常会使用类型转换&#xff0c;如果类型转换不成功则会出现异常&#xff0c;从抛出异常到捕获并处理异常&#xff0c;无形中增加了系统的开销&#xff0c;而且太过频繁地处理异常还会严重地影响系统的稳定性。is关键字可…

双指针刷题(三)

所有算法文章链接&#xff08;最底部&#xff09; http://t.csdnimg.cn/IbllR 1.有效三角形个数 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 1.分析题意 给一个非负的数组&#xff0c;判断这个数组能组成多少个三角形。 2.解题思路 补充知识…

前端vue uni-app使用Vue和ECharts构建交互式树形结构图

题目&#xff1a;使用Vue和ECharts构建交互式树形结构图 摘要&#xff1a;本文介绍了如何使用Vue.js和ECharts构建一个交互式的树形结构图。通过整合ECharts的强大可视化功能&#xff0c;我们创建了一个可拖拽移动、点击展开和收缩的树形结构图&#xff0c;并实现了无限添加子…

【ARMv8M Cortex-M33 系列 2.1 -- Cortex-M33 使用 .hex /.srec 文件介绍】

请阅读【嵌入式开发学习必备专栏 之Cortex-M33 专栏】 文章目录 HEX 文件介绍英特尔十六进制文件格式记录类型hex 示例Cortex-M 系列hex 文件的使用 hex 文件和srec 文件生成Motorola S-Record (srec) 格式 HEX 文件介绍 .hex 文件通常用于微控制器编程&#xff0c;包括 ARM C…

蜕变,我的2023

作者&#xff1a;苍何&#xff0c;前大厂高级 Java 工程师&#xff0c;阿里云专家博主&#xff0c;CSDN 2023 年 实力新星&#xff0c;土木转码&#xff0c;现任部门技术 leader&#xff0c;专注于互联网技术分享&#xff0c;职场经验分享。 &#x1f525;热门文章推荐&#xf…

react-router-dom5升级到6

前言 升级前版本为5.1.2 下载与运行 下载 npm install react-router-dom6运行 运行发现报错: 将node_modules删除&#xff0c;重新执行npm i即可 运行发现如下报错 这是因为之前有引用react-router-dom.min&#xff0c;v6中取消了该文件&#xff0c;所以未找到文件导致报错。…

抖音详情API:开发环境搭建与工具选择

随着短视频的流行&#xff0c;抖音已经成为了一个备受欢迎的社交媒体平台。对于开发人员而言&#xff0c;利用抖音详情API开发定制化的抖音应用具有巨大的潜力。本文将为你详细介绍开发抖音应用的开发环境搭建与工具选择&#xff0c;帮助你顺利地开始开发工作。 一、开发环境搭…

【网络安全 | Misc】miss_01 太湖杯

解压时提示输入密码&#xff1a; 如果 frFlags 或 deFlags 不为0会导致zip的伪加密 将deFlags的值修改为0 将9改为0&#xff0c;另存为123.zip&#xff1a; 即可绕过加密&#xff1a; 得到一个zip一个docx&#xff0c;但zip需要密码&#xff1a; 因此看docx有无敏感信息&#x…

机器学习、人工智能、深度学习的关系

人工智能(Artificial Intelligence&#xff0c;AI) 人工智能范围很广&#xff0c;它是一门新的科学与工程&#xff0c;是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的技术科学&#xff0c;研究内容涵盖语音识别、图像识别、自然语言处理、智能搜索和…

计算机毕业设计------ssm茶叶溯源系统

项目介绍 茶叶溯源系统&#xff0c;分为前台与后台。普通用户可在前台通过18位的编码查询茶叶的出售历史。 后台分为两种角色&#xff0c;管理员与经销商&#xff1b; 管理员主要功能包括&#xff1a; 主界面&#xff1b; 管理员管理&#xff1a;管理员列表、添加管理员&am…

跨域请求:Go语言下的“通天大道”

开场白&#xff1a;嘿&#xff0c;各位Go语言的爱好者们&#xff0c;你们是否曾经遇到过这样的困扰&#xff1a;当你的Go应用试图与另一个域的API进行交流时&#xff0c;突然跳出一个“未允许的跨域请求”的警告&#xff1f;别担心&#xff0c;今天&#xff0c;我们将一起在这条…

005、数据类型

1. 关于数据类型 Rust中&#xff0c;每个值都有其特定的数据类型&#xff0c;Rust会根据数据的类型来决定如何处理它们。 Rust是一门静态类型语言&#xff0c;它在编译程序的过程中就需要知道所有变量的具体类型。在大部分情况下&#xff0c;编译器可以根据我们如何绑定、使用变…

软件测试/测试开发丨Python 内置装饰器 学习笔记

内置类装饰器 不用实例化、直接调用提升代码的可读性 内置装饰器含义classmethod类方法staticmethod静态方法 普通方法 定义&#xff1a; 第一个参数为self&#xff0c;代表 实例本身 调用&#xff1a; 要有实例化的过程&#xff0c;通过 实例对象.方法名 调用 # 1. 定义 c…

unity控制摄像机几种视角实现方式

目录 1、按下鼠标右键可以实现摄像机上下左右旋转 2、自由视角 3、摄像头跟随视角 4、跟随自由视角 5、第一人称跟随视角 python学习汇总连接&#xff1a; 1、按下鼠标右键可以实现摄像机上下左右旋转 这段代码定义了一个名为CameraRotate的脚本&#xff0c;用于控制摄像…

2023年终总结 —— 我和CSDN相遇的第一年之“技术学习和个人成长的回顾与展望”

​ ​ &#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 &#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 &#x1f38a;对2023的总结与回顾&#x1f38a; &#x1f3c5;获奖记录 &#x1f4da;学…

机器学习库【03】:-NumPy-算术运算

一、说明 与常规数学一样&#xff0c;数组算术本质上是关于加法、减法、乘法和除法。在 中NumPy&#xff0c;此类操作是按元素执行的 [2]&#xff1a; NumPy 是 Numerical Python 的缩写&#xff0c;是 Python 生态系统中一个功能强大的库&#xff0c;它提供对大型多维数组和矩…

CentOS虚拟机硬盘管理

CentOS虚拟机硬盘管理 一、创建虚拟机时分配硬盘 创建虚拟机时&#xff0c;在下图这个页面需要重新选择一下硬盘&#xff0c;可以对硬盘进行配置。 默认自动分区 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/e9ce72af3d934e75be95f7f86860e92b.png 选择确认分…

EasyExcel详解(结合官方文档)

EasyExcel 零、前言 文章是根据官方文档&#xff0c;加上自己的测试运行总结出来的&#xff0c;目前只总结的EasyExcel读的部分&#xff0c;写的部分还未完结&#xff0c;后续会更新1、官方文档 https://easyexcel.opensource.alibaba.com/2、EasyExcel的maven依赖 <!--…

私有部署ELK,搭建自己的日志中心(三)-- Logstash的安装与使用

一、部署ELK 上文把采集端filebeat如何使用介绍完&#xff0c;现在随着数据的链路&#xff0c;继续~~ 同样&#xff0c;使用docker-compose部署&#xff1a; version: "3" services:elasticsearch:container_name: elasticsearchimage: elastic/elasticsearch:7.9…