canal1.1.7使用canal-adapter进行mysql同步数据

重要的事情说前面,canal1.1.8需要jdk11以上,大家自行选择,我这由于项目原因只能使用1.1.7兼容版的

文章参考地址:

canal 使用详解_canal使用-CSDN博客

使用canal.deployer-1.1.7和canal.adapter-1.1.7实现mysql数据同步_mysql更新数据时canal.adapter1.1.7不能同步-CSDN博客
canal使用-CSDN博客
 

下载

下载地址:Releases · alibaba/canal · GitHub

下载使用这三个就可以。如果不用管理平台的话可以不下载canal-admin

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 流)

 前置准备

首先要检测mysql是否开启binlog,如果未开启需要修改my.cnf配置文件,进行开启

--查看是否开启bin_log日志,value = on表示开启
SHOW VARIABLES LIKE 'log_bin';

--查看最新的bin_log

show master status;
-- 查看bin_log日志文件
SHOW BINARY LOGS;
--查看bin_log写入状态
SHOW MASTER STATUS;
--查看bin_log存储格式 = row
SHOW VARIABLES LIKE 'binlog_format';

#mysql开启binlog

        # 打开binlog

        log-bin=mysql-bin

        # 选择ROW(行)模式

        binlog-format=ROW

        # 配置MySQL replaction需要定义,不要和canal的slaveId重复

        server_id=1

mysql创建一个用户,也可以使用自己已有的用户

-- 使用命令登录:mysql -u root -p
-- 创建用户 用户名:canal 密码:Canal@123456
create user 'canal'@'%' identified by 'Canal@123456';
-- 授权 *.*表示所有库
grant SELECT, REPLICATION SLAVE, REPLICATION CLIENT on *.* to 'canal'@'%' identified by 'Canal@123456';
FLUSH PRIVILEGES;

 这样前置初始化条件就完成了。

安装canal-admin

将文件下载下来之后解压缩得到如下文件

首先打开conf目录下的application.yml文件,可以看到标准的spring-boot配置

server:port: 8089
spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8spring.datasource:address: 127.0.0.1:3306 #数据库连接地址database: canal_manager #数据库名称username: #用户名password: #密码driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://${spring.datasource.address}/${spring.datasource.database}?useUnicode=true&characterEncoding=UTF-8&useSSL=falsehikari:maximum-pool-size: 30minimum-idle: 1canal:adminUser: admin #管理员登录用户adminPasswd: 123456 #登录密码

首先在修改配置之前要先创建一个canal_manager数据库,用来存储canal的配置,canal_manager数据库的sql脚本在config/canal_manager.sql,与这个配置文件同级。运行一下就好了。运行后的表:

然后将上面的address(数据库连接地址)、username(用户名),password(密码)修改一下,改成你本地的连接。

adminUser和adminPasswd默认用户名密码是:admin和123456。

启动canal-admin:在bin/startup.bat(我是windows系统)双击启动

启动后没有报错就是成功了,在浏览器输入登录地址localhost:8089,用户名密码:admin  123456就进入管理界面了,到这canal-admin算是配置玩了,简单吧

安装canal.deployer

接下来我们可以安装canal的server端了,正常不用ali的管理视图和同步监听,只安装这一个文件就可以,但咱们要做就做全套呀,主打不写一行代码

将canal-deployer压缩包解压得到如下的文件。

还是老样子,打开conf文件夹如下:

文件配置选择二选一

这里有一个canal.properties和canal_local.properties两个文件

如果单机配置使用canal_local.properties配置文件好点,因为配置少,如果使用canal_local.properties配置文件的话,就把canal_local.properties名称改为canal.properties,之前的canal.properties可以换个名字或者删掉。

canal_local.properties

贴一下canal_local.properties的配置让你们感受一下

# register ip
canal.register.ip =

# canal admin config
canal.admin.manager = 127.0.0.1:8089  #canal-admin的连接地址
canal.admin.port = 11110 #默认
canal.admin.user = admin #canal-admin的用户名
canal.admin.passwd = 4ACFE3202A5FF5CF467898FC58AAB1D615029441  #canal-admin的登录密码123456的密文自己去上面说的数据库canal_manager的表canal_user里查看
# admin auto register
canal.admin.register.auto = true
canal.admin.register.cluster =
canal.admin.register.name = 

当然使用默认的canal.properties也可以,自己选择,我们就以默认的canal.properties为例,

canal.properties配置:

单机配置只需要修改这几个参数就可以


canal.admin.manager = 127.0.0.1:8089  #canal-admin的连接地址
canal.admin.port = 11110  #默认
canal.admin.user = admin #canal-admin的用户名
canal.admin.passwd = 6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9  #canal-admin的登录密码123456的密文,取值见上面说明


# 启动端口,也是客户端连接的端口
canal.port = 11111
# tcp, kafka, rocketMQ, rabbitMQ, pulsarMQ 与canal 连接的客户端
# 如果是通过代码进行连接,这里为tcp
canal.serverMode = tcp
# canal 加载mysql 的实例
canal.destinations = example

 canal.destinations理解,引用之前一个博主的说法。

canal.properties的整体配置:

#################################################
######### 		common argument		#############
#################################################
# tcp bind ip
canal.ip =
# register ip to zookeeper
canal.register.ip =127.0.0.1
canal.port = 11111
canal.metrics.pull.port = 11112
# canal instance user/passwd
# canal.user = canal
# canal.passwd = E3619321C1A937C46A0D8BD1DAC39F93B27D4458# canal admin config
canal.admin.manager = 127.0.0.1:8089
canal.admin.port = 11110
canal.admin.user = admin
canal.admin.passwd = 6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9
# admin auto register
canal.admin.register.auto = true
#canal.admin.register.cluster =
#canal.admin.register.name =canal.zkServers =
# flush data to zk
canal.zookeeper.flush.period = 1000
canal.withoutNetty = false
# tcp, kafka, rocketMQ, rabbitMQ, pulsarMQ
canal.serverMode = tcp
# flush meta cursor/parse position to file
canal.file.data.dir = ${canal.conf.dir}
canal.file.flush.period = 1000
## memory store RingBuffer size, should be Math.pow(2,n)
canal.instance.memory.buffer.size = 16384
## memory store RingBuffer used memory unit size , default 1kb
canal.instance.memory.buffer.memunit = 1024 
## meory store gets mode used MEMSIZE or ITEMSIZE
canal.instance.memory.batch.mode = MEMSIZE
canal.instance.memory.rawEntry = true## detecing config
canal.instance.detecting.enable = false
#canal.instance.detecting.sql = insert into retl.xdual values(1,now()) on duplicate key update x=now()
canal.instance.detecting.sql = select 1
canal.instance.detecting.interval.time = 3
canal.instance.detecting.retry.threshold = 3
canal.instance.detecting.heartbeatHaEnable = false# support maximum transaction size, more than the size of the transaction will be cut into multiple transactions delivery
canal.instance.transaction.size =  1024
# mysql fallback connected to new master should fallback times
canal.instance.fallbackIntervalInSeconds = 60# network config
canal.instance.network.receiveBufferSize = 16384
canal.instance.network.sendBufferSize = 16384
canal.instance.network.soTimeout = 30# binlog filter config
canal.instance.filter.druid.ddl = true
canal.instance.filter.query.dcl = false
canal.instance.filter.query.dml = false
canal.instance.filter.query.ddl = false
canal.instance.filter.table.error = false
canal.instance.filter.rows = false
canal.instance.filter.transaction.entry = false
canal.instance.filter.dml.insert = false
canal.instance.filter.dml.update = false
canal.instance.filter.dml.delete = false# binlog format/image check
canal.instance.binlog.format = ROW,STATEMENT,MIXED 
canal.instance.binlog.image = FULL,MINIMAL,NOBLOB# binlog ddl isolation
canal.instance.get.ddl.isolation = false# parallel parser config
canal.instance.parser.parallel = true
## concurrent thread number, default 60% available processors, suggest not to exceed Runtime.getRuntime().availableProcessors()
#canal.instance.parser.parallelThreadSize = 16
## disruptor ringbuffer size, must be power of 2
canal.instance.parser.parallelBufferSize = 256# table meta tsdb info
canal.instance.tsdb.enable = true
canal.instance.tsdb.dir = ${canal.file.data.dir:../conf}/${canal.instance.destination:}
canal.instance.tsdb.url = jdbc:h2:${canal.instance.tsdb.dir}/h2;CACHE_SIZE=1000;MODE=MYSQL;
canal.instance.tsdb.dbUsername = canal
canal.instance.tsdb.dbPassword = canal
# dump snapshot interval, default 24 hour
canal.instance.tsdb.snapshot.interval = 24
# purge snapshot expire , default 360 hour(15 days)
canal.instance.tsdb.snapshot.expire = 360#################################################
######### 		destinations		#############
#################################################
canal.destinations = example
# conf root dir
canal.conf.dir = ../conf
# auto scan instance dir add/remove and start/stop instance
canal.auto.scan = true
canal.auto.scan.interval = 5
# set this value to 'true' means that when binlog pos not found, skip to latest.
# WARN: pls keep 'false' in production env, or if you know what you want.
canal.auto.reset.latest.pos.mode = falsecanal.instance.tsdb.spring.xml = classpath:spring/tsdb/h2-tsdb.xml
#canal.instance.tsdb.spring.xml = classpath:spring/tsdb/mysql-tsdb.xmlcanal.instance.global.mode = spring
canal.instance.global.lazy = false
canal.instance.global.manager.address = ${canal.admin.manager}
#canal.instance.global.spring.xml = classpath:spring/memory-instance.xml
canal.instance.global.spring.xml = classpath:spring/file-instance.xml
#canal.instance.global.spring.xml = classpath:spring/default-instance.xml##################################################
######### 	      MQ Properties      #############
##################################################
# aliyun ak/sk , support rds/mq
canal.aliyun.accessKey =
canal.aliyun.secretKey =
canal.aliyun.uid=canal.mq.flatMessage = true
canal.mq.canalBatchSize = 50
canal.mq.canalGetTimeout = 100
# Set this value to "cloud", if you want open message trace feature in aliyun.
canal.mq.accessChannel = localcanal.mq.database.hash = true
canal.mq.send.thread.size = 30
canal.mq.build.thread.size = 8##################################################
######### 		     Kafka 		     #############
##################################################
kafka.bootstrap.servers = 127.0.0.1:9092
kafka.acks = all
kafka.compression.type = none
kafka.batch.size = 16384
kafka.linger.ms = 1
kafka.max.request.size = 1048576
kafka.buffer.memory = 33554432
kafka.max.in.flight.requests.per.connection = 1
kafka.retries = 0kafka.kerberos.enable = false
kafka.kerberos.krb5.file = ../conf/kerberos/krb5.conf
kafka.kerberos.jaas.file = ../conf/kerberos/jaas.conf# sasl demo
# kafka.sasl.jaas.config = org.apache.kafka.common.security.scram.ScramLoginModule required \\n username=\"alice\" \\npassword="alice-secret\";
# kafka.sasl.mechanism = SCRAM-SHA-512
# kafka.security.protocol = SASL_PLAINTEXT##################################################
######### 		    RocketMQ	     #############
##################################################
rocketmq.producer.group = test
rocketmq.enable.message.trace = false
rocketmq.customized.trace.topic =
rocketmq.namespace =
rocketmq.namesrv.addr = 127.0.0.1:9876
rocketmq.retry.times.when.send.failed = 0
rocketmq.vip.channel.enabled = false
rocketmq.tag = ##################################################
######### 		    RabbitMQ	     #############
##################################################
rabbitmq.host =
rabbitmq.virtual.host =
rabbitmq.exchange =
rabbitmq.username =
rabbitmq.password =
rabbitmq.deliveryMode =##################################################
######### 		      Pulsar         #############
##################################################
pulsarmq.serverUrl =
pulsarmq.roleToken =
pulsarmq.topicTenantPrefix =
配置instance.properties

路径在conf/example/instance.properties,因为我们在canal.properties指定了canal.destinations = example,所以要在对应的example文件夹下配置instance。这里引用了其他博主的文件描述很详细,我就拿过来了

## mysql serverId , v1.0.26+ will autoGen
## v1.0.26版本后会自动生成slaveId,所以可以不用配置
# canal.instance.mysql.slaveId=0
 
# 数据库地址
canal.instance.master.address=127.0.0.1:3306
# binlog日志名称
canal.instance.master.journal.name=mysql-bin.000001
# mysql主库链接时起始的binlog偏移量
canal.instance.master.position=154
# mysql主库链接时起始的binlog的时间戳
canal.instance.master.timestamp=
canal.instance.master.gtid=
 
# username/password
# 在MySQL服务器授权的账号密码
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
# 字符集
canal.instance.connectionCharset = UTF-8
# enable druid Decrypt database password
canal.instance.enableDruid=false
# canal.instance.defaultDatabaseName 默认那个库,这里指定为test(需要在MySQL中建立一个test库)
 
# table regex .*\\..*表示监听所有表 也可以写具体的表名,用,隔开
canal.instance.filter.regex=.*\\..*
# mysql 数据解析表的黑名单,多个表用,隔开
canal.instance.filter.black.regex=

 canal.instance.filter.regex规则事例,主要就是监听哪些表进行复制:

https://github.com/alibaba/canal/wiki/AdminGuide#properties%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6

1.  所有表:.*   or  .*\\..*
2.  canal schema下所有表: canal\\..*
3.  canal下的以canal打头的表:canal\\.canal.*
4.  canal schema下的一张表:canal\\.test1

5.  多个规则组合使用:canal\\..*,mysql.test1,mysql.test2 (逗号分隔)

 这个配置完成之后就可以启动了

双击bin/startup.bat目录下的脚本文件,如果没有报错的话就启动成功了

然后在去刷新我们的canal-admin管理页面,可以看到这个server实例已经注入进来了。

通过canal-admin管理页面管理server的话,需要在instance管理里增加对应的instance配置,至于为什么没有从canal-deployer的example读取过来不了解。

在instance管理里点击‘新建instance’,在页面里点击导入模板修改配置,或者将之前example文件夹下的instance.properties复制过来就可以。然后起一个名字,选择你的实例保存。

成功添加成功之后列表就会显示 你新增的配置

 安装canal.adapter

将canal.adapter-1.1.7解压得到如下的问价夹

老样子打开conf文件夹,首先修改application.yml文件

server:port: 8081
spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8default-property-inclusion: non_nullcanal.conf:mode: tcp #tcp kafka rocketMQ rabbitMQ 指定连接类型  对应consumerProperties下的配置flatMessage: truezookeeperHosts:syncBatchSize: 1000 #批量数量retries: 10  #循环次数 -1表示无线循环timeout:accessKey:secretKey:consumerProperties:# canal tcp consumercanal.tcp.server.host: 127.0.0.1:11111   #canal.deployer的地址和端口canal.tcp.zookeeper.hosts:canal.tcp.batch.size: 500#canal.tcp.username: canal#canal.tcp.password: canal# kafka consumerkafka.bootstrap.servers: 127.0.0.1:9092kafka.enable.auto.commit: falsekafka.auto.commit.interval.ms: 1000kafka.auto.offset.reset: latestkafka.request.timeout.ms: 40000kafka.session.timeout.ms: 30000kafka.isolation.level: read_committedkafka.max.poll.records: 1000# rocketMQ consumerrocketmq.namespace:rocketmq.namesrv.addr: 127.0.0.1:9876rocketmq.batch.size: 1000rocketmq.enable.message.trace: falserocketmq.customized.trace.topic:rocketmq.access.channel:rocketmq.subscribe.filter:# rabbitMQ consumerrabbitmq.host:rabbitmq.virtual.host:rabbitmq.username:rabbitmq.password:rabbitmq.resource.ownerId:
#源数据库连接信息srcDataSources:defaultDS:url: jdbc:mysql://127.0.0.1:3306/zm?useUnicode=true&characterEncoding=UTF-8&useSSL=false  # 对应canal.adapter-1.1.7\conf\rdb下的配置文件中的dataSourceKey的value值username: # 用户名password: # 密码canalAdapters:- instance: example # example对应路径canal.deployer-1.1.7\conf\example 和canal.adapter-1.1.7\conf\rdb下的配置文件中的 destination的value值groups:- groupId: g1 # g1对应canal.adapter-1.1.7\conf\rdb下的配置文件中的 groupId的value值outerAdapters:# - name: logger- name: rdb  #rdb对应路径canal.adapter-1.1.7\conf\rdbkey: mysql1  # mysql1 对应 canal.adapter-1.1.7\conf\rdb下的配置文件中outerAdapterKey的value值#目标数据库连接信息properties:jdbc.driverClassName: com.mysql.jdbc.Driverjdbc.url: jdbc:mysql://目标库地址:3306/zm?useUnicode=true&characterEncoding=UTF-8&useSSL=falsejdbc.username: #用户名jdbc.password: #密码druid.stat.enable: falsedruid.stat.slowSqlMillis: 1000

配置rdb下的mytest_user.yml文件:

dataSourceKey: defaultDS
destination: example
groupId: g1
outerAdapterKey: mysql1
concurrent: true
dbMapping:database: zm #源数据库table: zm_product #源数据库表targetTable: zm_product  #目标数据库表targetPk: #主键id: idmapAll: true #表字段一样全部映射 否则使用targetColumns进行映射
#  targetColumns:
#    id:
#    name:
#    role_id:
#    c_time:
#    test1:
#  etlCondition: "where c_time>={}" #数据查询条件commitBatch: 3000 # 批量提交的大小## Mirror schema synchronize config
#dataSourceKey: defaultDS
#destination: example
#groupId: g1
#outerAdapterKey: mysql1
#concurrent: true
#dbMapping:
#  mirrorDb: true
#  database: mytest

他们说有启动失败的要修改.bat文件,我是直接成功了

启动bin/startup.bat脚本文件,启动成功

 到此就能实现两个库的主从复制了,实验一下

检测验证

使用工具新增一条数据:

canal-adapter控制台会打印出刚才的新增信息,说明监听binlog已经进行了主从复制操作

而我们的目标数据库也会生成一条对应的数据:

到此功成,当然这只是单机配置,集群配置本地没试。 

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

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

相关文章

DevExpress中文教程 - 如何使用AI模型检查HTML编辑中的语法?

DevExpress .NET MAUI多平台应用UI组件库提供了用于Android和iOS移动开发的高性能UI组件,该组件库包括数据网格、图表、调度程序、数据编辑器、CollectionView和选项卡组件等。 目前许多开发人员正在寻找多种方法将AI添加到解决方案中(这通常比想象的要…

【推荐】iptables学习宝典

链接: IPtables-朱双印博客 学习iptables的抗鼎之作,推荐。

二维数组和数组指针数组的关系

在深入理解指针end中&#xff0c;我在最后写了一长段代码 #include<stdio.h> void test1(int arr[][5], int x, int y) //void test1(int(*p)[5], int x, int y) {for (int i 0; i < x; i){for (int j 0; j < y; j){//printf("%d ", *(*(p i) j));p…

vue+websocket实现即时聊天平台

目录 1 什么是websocket 2 实现步骤 2.1 导入依赖 2.2 编写代码 1 什么是websocket WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。它主要用于在客户端和服务器之间建立持久的连接&#xff0c;允许实时数据交换。WebSocket 的设计目的是为了提高 Web 应用程序的…

【D3.js in Action 3 精译_038】4.2 D3 折线图的绘制方法及曲线插值处理

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一部分 D3.js 基础知识 第一章 D3.js 简介&#xff08;已完结&#xff09; 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践&#xff08;上&#xff09;1.3 数据可…

Git 的分支管理

一、分支介绍 1、分支是什么 Git作为一个分布式版本控制系统&#xff0c;提供了强大而灵活的分支管理功能&#xff0c;使得开发团队能够高效地协作开发、管理不同的功能和版本。 2、为什么有分支 一般情况下主分支&#xff08;master/main&#xff09;应始终保持可部署的状…

Linux环境基础和基础开发工具使用

文章目录 一、yum软件管理器1、包管理器2、yum3、apt4、安装源 二、编辑器vim1、各种模式2、打开时直接让光标定位到指定号3、&#xff01;加命令字符 三、命令模式1、i 进入插入模式2、**Shift :** 进入底行模式3、光标定位4、ZZ&#xff08;大写&#xff09;保存并退出vim5、…

【java】哈希<两数之和> 理解哈希

两数之和 题目描述&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案&#xff0c;并且你不能使用两次相同的元素。 你…

【Linux】信号三部曲——产生、保存、处理

信号 1. 信号的概念2. 进程如何看待信号3. 信号的产生3.1. kill命令3.2. 终端按键3.2.1. 核心转储core dump3.2.2. OS如何知道键盘在输入数据 3.3. 系统调用3.3.1. kill3.3.2. raise3.3.3. abort 3.4. 软件条件3.4.1. SIGPIPE信号3.4.2. SIGALRM信号 3.5. 硬件异常3.5.1. 除零异…

Vue 计算属性和监听器

文章目录 一、计算属性1. 计算属性定义2. computed 比较 methods3. 计算属性完整写法 二、监听器1. 普通监听2. 添加额外配置项 一、计算属性 1. 计算属性定义 概念&#xff1a;基于现有的数据&#xff0c;计算出来的新属性&#xff0c;依赖的数据变化&#xff0c;自动重新计…

【计网】实现reactor反应堆模型 --- 框架搭建

没有一颗星&#xff0c; 会因为追求梦想而受伤&#xff0c; 当你真心渴望某样东西时&#xff0c; 整个宇宙都会来帮忙。 --- 保罗・戈埃罗 《牧羊少年奇幻之旅》--- 实现Reactor反应堆模型 1 前言2 框架搭建3 准备工作4 Reactor类的设计5 Connection连接接口6 回调方法 1 …

外包干了2年,快要废了。。。

先说一下自己的情况&#xff0c;普通本科毕业&#xff0c;在外包干了2年多的功能测试&#xff0c;这几年因为大环境不好&#xff0c;我整个人心惊胆战的&#xff0c;怕自己卷铺盖走人了&#xff0c;我感觉自己不能够在这样蹉跎下去了&#xff0c;长时间呆在一个舒适的环境真的会…

linux驱动-i2c子系统框架学习(2)

linux驱动-i2c子系统框架学习(1) 在这篇博客里面已经交代了i2c设备驱动层&#xff0c;主要的功能就是编写具体i2c的外设驱动&#xff0c;和创建设备接点给上层使用 &#xff0c;按之前学习的字符设备&#xff0c;有了设备节点&#xff0c;就可以对硬件操作了&#xff0c;在i2c…

Webserver(4.6)poll和epoll

目录 pollclient.cpoll.c epollepoll.cclient.c epoll的两种工作模式水平触发边沿触发 poll poll是对select的一个改进 select的缺点在于每次都需要将fd集合从用户态拷贝到内核态&#xff0c;开销很大。每次调用select都需要在内核遍历传递进来的所有fd&#xff0c;这个开销也…

Stable Diffusion的解读(一)

Stable Diffusion的解读&#xff08;一&#xff09; 文章目录 Stable Diffusion的解读&#xff08;一&#xff09;摘要Abstract一、机器学习部分1. Stable Diffusion的早期工作1.1 从编码器谈起1.2 第一条路线&#xff1a;VAE和DDPM1.3 第二条路线&#xff1a;VQVAE1.4 路线的交…

计算机网络——TCP篇

TCP篇 基本认知 TCP和UDP的区别? TCP 和 UDP 可以使用同一个端口吗&#xff1f; 可以的 传输层中 TCP 和 UDP在内核中是两个完全独立的软件模块。可以根据协议字段来选择不同的模块来处理。 TCP 连接建立 TCP 三次握手过程是怎样的&#xff1f; 一次握手:客户端发送带有 …

ROS话题通信机制理论模型的学习

话题通信是ROS&#xff08;Robot Operating System&#xff0c;机器人操作系统&#xff09;中使用频率最高的一种通信模式&#xff0c;其实现模型主要基于发布/订阅模式。 一、基本概念 话题通信模型中涉及三个主要角色&#xff1a; ROS Master&#xff08;管理者&#xff0…

【Android】名不符实的Window类

1.“名不符实”的Window类 Window 是一个窗口的概念&#xff0c;是所有视图的载体&#xff0c;不管是 Activity&#xff0c;Dialog&#xff0c;还是 Toast&#xff0c;他们的视图都是附加在 Window 上面的。例如在桌面显示一个悬浮窗&#xff0c;就需要用到 Window 来实现。Wi…

后端java——如何为你的网页设置一个验证码

目录 1、工具的准备 2.基本方法 3.实现类 4.实践 HTML文件&#xff1a; Java文件1:创建验证码 Java文件2:验证验证码 本文通过HUTOOL实现&#xff1a;Hutool参考文档Hutool&#xff0c;Java工具集https://hutool.cn/docs/#/ 1、工具的准备 如果我们通过hutool来实现这个…

【go从零单排】Strings and Runes 字符串和字符

Don’t worry , just coding! 内耗与overthinking只会削弱你的精力&#xff0c;虚度你的光阴&#xff0c;每天迈出一小步&#xff0c;回头时发现已经走了很远。 概念 在Go语言中&#xff0c;rune 是一个内置的数据类型&#xff0c;用于表示一个Unicode字符。它实际上是一个别名…