Canal 部署(上)

817 阅读13分钟

环境说明

  • JDK 1.8
  • MySQL 5.7.38
  • Elasticsearch 7.10.2
  • Canal 1.1.7 单机模式

Canal官方文档:github.com/alibaba/can…

示例说明:监听MySQL数据库binlog同步表数据到Elasticsearch索引中,走TCP,配置均从本地配置文件读取,下一篇将从远程读取。

数据库准备

1. 监听binlog用户

CREATE USER canal IDENTIFIED BY 'canal';    
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';  
-- GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%' ;  
FLUSH PRIVILEGES; 
-- 查看用户权限
show grants for 'canal' 

MySQL的slave需要的权限说明如下:

  • REPLICATION SLAVE权限,这是Slave服务器必须拥有的最重要的权限。它允许Slave服务器连接到Master服务器并获取复制数据。如果Slave服务器没有REPLICATION SLAVE权限,它将无法连接到Master服务器并执行复制操作。
  • REPLICATION CLIENT权限,这个权限允许Slave服务器向Master服务器发送查询语句以获取复制数据。如果Slave服务器没有REPLICATION CLIENT权限,它将无法向Master服务器发送查询语句,从而无法获取复制数据。
  • SELECT权限,Slave服务器需要SELECT权限来读取Master服务器上的数据。如果Slave服务器没有SELECT权限,它将无法获取Master服务器上的数据,从而无法保持与Master服务器的同步。
  • SHOW VIEW权限,如果Master服务器上有视图(View),Slave服务器需要SHOW VIEW权限来读取这些视图。如果Slave服务器没有SHOW VIEW权限,它将无法读取Master服务器上的视图,从而无法保持与Master服务器的同步。
  • RELOAD权限,这个权限允许Slave服务器重新加载配置文件。如果Slave服务器没有RELOAD权限,它将无法重新加载配置文件,从而无法应用新的配置更改。
  • SUPER权限,这个权限允许Slave服务器执行一些高级操作,如修改全局变量和停止复制。虽然不是必需的权限,但在某些情况下可能会非常有用。

Canal Deployer启动

配置说明官方文档地址:github.com/alibaba/can…

  1. 定义监听实例,在\canal.deployer-1.1.7\conf目录下以实例名命名一个文件夹,创建一个instance.properties文件,配置实例监听的目标数据库信息,在canal.instance.filter.regex通过Perl正则表达式过滤关注的表。
  2. 编辑\canal.deployer-1.1.7\conf\canal.properties,指定实例配置文件读取目录,配置要启用的实例,通过canal.instance.tsdb配置数据库内表结构的镜像存储,每个实例也可自行在instance.properties中控制是否开启tsdb能力,默认存储在h2,可配置为MySQL。
  3. 执行\canal.deployer-1.1.7\bin\startup.bat脚本启动服务。
Canal Deployer启动日志 logs/canal/canal.log
tail -n 300 -f logs/canal/canal.log
2023-11-13 10:10:38.055 [main] INFO  com.alibaba.otter.canal.deployer.CanalLauncher - ## set default uncaught exception handler
2023-11-13 10:10:38.063 [main] INFO  com.alibaba.otter.canal.deployer.CanalLauncher - ## load canal configurations
2023-11-13 10:10:38.088 [main] INFO  com.alibaba.otter.canal.deployer.CanalStarter - ## start the canal server.
2023-11-13 10:10:38.199 [main] INFO  com.alibaba.otter.canal.deployer.CanalController - ## start the canal server[172.29.9.110(172.29.9.110):11111]
2023-11-13 10:10:40.257 [main] INFO  com.alibaba.otter.canal.deployer.CanalStarter - ## the canal server is running now ......
2023-11-13 16:38:18.344 [main] INFO  com.alibaba.otter.canal.deployer.CanalLauncher - ## set default uncaught exception handler
2023-11-13 16:38:18.350 [main] INFO  com.alibaba.otter.canal.deployer.CanalLauncher - ## load canal configurations
2023-11-13 16:38:18.386 [main] INFO  com.alibaba.otter.canal.deployer.CanalStarter - ## start the canal server.
2023-11-13 16:38:18.494 [main] INFO  com.alibaba.otter.canal.deployer.CanalController - ## start the canal server[172.29.9.110(172.29.9.110):11111]
2023-11-13 16:38:20.608 [main] INFO  com.alibaba.otter.canal.deployer.CanalStarter - ## the canal server is running now ......
Canal Deployer启动日志 logs/polarstar/polarstar.log
tail -n 300 -f logs/polarstar/polarstar.log
2023-11-13 10:10:39.101 [main] INFO  c.a.otter.canal.instance.spring.CanalInstanceWithSpring - start CannalInstance for 1-polarstar
2023-11-13 10:10:40.186 [main] WARN  c.a.o.canal.parse.inbound.mysql.dbsync.LogEventConvert - --> init table filter : ^sph_task_platform\.t_monitor_finder$
2023-11-13 10:10:40.186 [main] WARN  c.a.o.canal.parse.inbound.mysql.dbsync.LogEventConvert - --> init table black filter : ^mysql\.slave_.*$
2023-11-13 10:10:40.191 [main] INFO  c.a.otter.canal.instance.core.AbstractCanalInstance - start successful....
2023-11-13 10:10:40.468 [destination = polarstar , address = /139.9.205.116:3306 , EventParser] WARN  c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - ---> begin to find start position, it will be long time for reset or first position
2023-11-13 10:10:40.469 [destination = polarstar , address = /139.9.205.116:3306 , EventParser] WARN  c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - prepare to find start position just show master status
2023-11-13 10:11:13.823 [destination = polarstar , address = /139.9.205.116:3306 , EventParser] WARN  c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - ---> find start position successfully, EntryPosition[included=false,journalName=mysql-bin.050518,position=112006513,serverId=1984873832,gtid=,timestamp=1699841440000] cost : 33337ms , the next step is binlog dump
\canal.deployer-1.1.7\conf\canal.properties 配置内容
#################################################
#########         common argument        #############
#################################################
# tcp bind ip
canal.ip =
# register ip to zookeeper
canal.register.ip =
canal.port = 11111
canal.metrics.pull.port = 11112
# canal instance user/passwd
# canal.user = canal
# canal.passwd = E3619321C1A937C46A0D8BD1DAC39F93B27D4458
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


# network config
canal.instance.network.receiveBufferSize = 16384
canal.instance.network.sendBufferSize = 16384
canal.instance.network.soTimeout = 30


# 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:mysql://127.0.0.1:3306/test_cannal_admin
canal.instance.tsdb.dbUsername = cannal
canal.instance.tsdb.dbPassword = 123456
# 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

#canal.instance.tsdb.spring.xml = classpath:spring/tsdb/h2-tsdb.xml
canal.instance.tsdb.spring.xml = classpath:spring/tsdb/mysql-tsdb.xml

#################################################
#########         destinations        #############
#################################################
canal.destinations = polarstar
# 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 = false

canal.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
\canal.deployer-1.1.7\conf\polarstar\instance.properties 配置内容
#################################################
## mysql serverId , v1.0.26+ will autoGen
# canal.instance.mysql.slaveId=0

# enable gtid use true/false
canal.instance.gtidon=false

# position info
canal.instance.master.address=127.0.0.1:3306
canal.instance.master.journal.name=
canal.instance.master.position=
canal.instance.master.timestamp=
canal.instance.master.gtid=

# rds oss binlog
canal.instance.rds.accesskey=
canal.instance.rds.secretkey=
canal.instance.rds.instanceId=

# table meta tsdb info
canal.instance.tsdb.enable=true

# username/password
canal.instance.dbUsername=cannal
canal.instance.dbPassword=123456
canal.instance.connectionCharset = UTF-8
# enable druid Decrypt database password
canal.instance.enableDruid=false
#canal.instance.pwdPublicKey=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALK4BUxdDltRRE5/zXpVEVPUgunvscYFtEip3pmLlhrWpacX7y7GCMo2/JM6LeHmiiNdH1FWgGCpUfircSwlWKUCAwEAAQ==

# table regex
canal.instance.filter.regex=test_crm\\.t_user_logs
# table black regex
canal.instance.filter.black.regex=mysql\\.slave_.*
# table field filter(format: schema1.tableName1:field1/field2,schema2.tableName2:field1/field2)
#canal.instance.filter.field=test1.t_product:id/subject/keywords,test2.t_company:id/name/contact/ch
# table field black filter(format: schema1.tableName1:field1/field2,schema2.tableName2:field1/field2)
#canal.instance.filter.black.field=test1.t_product:subject/product_image,test2.t_company:id/name/contact/ch

# mq config
canal.mq.topic=polarstar
# dynamic topic route by schema or table regex
#canal.mq.dynamicTopic=mytest1.user,topic2:mytest2\\..*,.*\\..*
canal.mq.partition=0
# hash partition config
#canal.mq.enableDynamicQueuePartition=false
#canal.mq.partitionsNum=3
#canal.mq.dynamicTopicPartitionNum=test.*:4,mycanal:6
#canal.mq.partitionHash=test.table:id^name,.*\\..*
#
# multi stream for polardbx
canal.instance.multi.stream.on=false
#################################################

Canal Adapter启动

目前提供的适配器有:logger、es6、es7、es8、hbase、kudu、phoenix、rdb、tablestore,也可参考源码自行扩展其他的适配器,使用方式是将\canal.adapter-1.1.7\plugin目录下提供的你所需的fat jar复制到\canal.adapter-1.1.7\lib目录下,程序启动时会通过SPI的方式来加载对应的适配器,一个group会启动一个canal连接。

启动操作

以我这边MySQL数据同步到Elasticsearch为例:

  1. 将\canal.adapter-1.1.7\plugin目录下的client-adapter.logger-1.1.7-jar-with-dependencies.jar与client-adapter.es7x-1.1.7-jar-with-dependencies.jar复制到\canal.adapter-1.1.7\lib目录下。
  2. 编辑\canal.adapter-1.1.7\conf目录下的bootstrap.yml文件配置MySQL数据库的连接信息,用于远程配置中心统一管理配置(将本地application.yml文件和其他子配置文件删除或清空, 启动工程将自动从远程加载配置,查询配置的SQL:select name, content, modified_time from canal_config where id=2,目前默认是提供了MySQL数据库的支持,也可自行实现RemoteConfigLoader接口进行其他支持的扩展)。
  3. 编辑\canal.adapter-1.1.7\conf目录下的application.yml文件配置对于实例数据的处理适配器,可以对同一个实例配置多个group进行并行处理(类似Kafka的消费组),也可一个group多个适配器串行处理;srcDataSources为目标待同步数据源,执行全量同步时会用到
  4. 编辑\canal.adapter-1.1.7\conf\es7\test_es7.yml文件,配置数据库表与ES索引的映射。
  5. 双击\canal.adapter-1.1.7\bin\startup.bat启动Adapter Launcher服务,对应的源码目录:client-adapter/launcher
Adapter Launcher启动日志:
2023-11-13 10:12:51.014 [main] INFO  c.a.otter.canal.adapter.launcher.CanalAdapterApplication - Starting CanalAdapterApplication using Java 1.8.0_181 on OS-20200615TKXS with PID 9548 (F:\work\canal\canal.adapter-1.1.7\lib\client-adapter.launcher-1.1.7.jar started by Administrator in F:\work\canal\canal.adapter-1.1.7\bin)
2023-11-13 10:12:51.018 [main] INFO  c.a.otter.canal.adapter.launcher.CanalAdapterApplication - No active profile set, falling back to default profiles: default
2023-11-13 10:12:51.431 [main] INFO  org.springframework.cloud.context.scope.GenericScope - BeanFactory id=00d91651-0d64-37f4-8c2b-414d3b7cef67
2023-11-13 10:12:51.735 [main] INFO  o.s.boot.web.embedded.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8081 (http)
2023-11-13 10:12:51.742 [main] INFO  org.apache.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8081"]
2023-11-13 10:12:51.742 [main] INFO  org.apache.catalina.core.StandardService - Starting service [Tomcat]
2023-11-13 10:12:51.742 [main] INFO  org.apache.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.52]
2023-11-13 10:12:51.743 [main] INFO  org.apache.catalina.core.AprLifecycleListener - An older version [1.2.25] of the Apache Tomcat Native library is installed, while Tomcat recommends a minimum ve       rsion of [1.2.30]
2023-11-13 10:12:51.744 [main] INFO  org.apache.catalina.core.AprLifecycleListener - Loaded Apache Tomcat Native library [1.2.25] using APR version [1.7.0].
2023-11-13 10:12:51.744 [main] INFO  org.apache.catalina.core.AprLifecycleListener - APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true], UDS [false].
2023-11-13 10:12:51.744 [main] INFO  org.apache.catalina.core.AprLifecycleListener - APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
2023-11-13 10:12:51.746 [main] INFO  org.apache.catalina.core.AprLifecycleListener - OpenSSL successfully initialized [OpenSSL 1.1.1g  21 Apr 2020]
2023-11-13 10:12:51.813 [main] INFO  o.a.catalina.core.ContainerBase.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2023-11-13 10:12:51.813 [main] INFO  o.s.b.w.s.context.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 764 ms
2023-11-13 10:12:52.499 [main] INFO  com.alibaba.druid.pool.DruidDataSource - {dataSource-1} inited
2023-11-13 10:12:53.277 [main] INFO  org.apache.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8081"]
2023-11-13 10:12:53.288 [main] INFO  o.s.boot.web.embedded.tomcat.TomcatWebServer - Tomcat started on port(s): 8081 (http) with context path ''
2023-11-13 10:12:53.292 [main] INFO  c.a.o.canal.adapter.launcher.loader.CanalAdapterService - ## syncSwitch refreshed.
2023-11-13 10:12:53.292 [main] INFO  c.a.o.canal.adapter.launcher.loader.CanalAdapterService - ## start the canal client adapters.
2023-11-13 10:12:53.296 [main] INFO  c.a.otter.canal.client.adapter.support.ExtensionLoader - extension classpath dir: F:\work\canal\canal.adapter-1.1.7\plugin
2023-11-13 10:12:53.344 [main] INFO  c.a.o.canal.adapter.launcher.loader.CanalAdapterLoader - Load canal adapter: logger succeed
2023-11-13 10:12:53.456 [main] INFO  c.a.o.c.client.adapter.es.core.config.ESSyncConfigLoader - ## Start loading es mapping config ...
2023-11-13 10:12:53.471 [main] INFO  c.a.o.c.client.adapter.es.core.config.ESSyncConfigLoader - ## ES mapping config loaded
2023-11-13 10:12:53.852 [main] INFO  c.a.o.canal.adapter.launcher.loader.CanalAdapterLoader - Load canal adapter: es7 succeed
2023-11-13 10:12:53.859 [main] INFO  c.alibaba.otter.canal.connector.core.spi.ExtensionLoader - extension classpath dir: F:\work\canal\canal.adapter-1.1.7\plugin
2023-11-13 10:12:53.979 [main] INFO  c.a.o.canal.adapter.launcher.loader.CanalAdapterLoader - Start adapter for canal-client mq topic: polarstar-g1 succeed
2023-11-13 10:12:53.979 [Thread-4] INFO  c.a.otter.canal.adapter.launcher.loader.AdapterProcessor - =============> Start to connect destination: polarstar <=============
2023-11-13 10:12:53.979 [main] INFO  c.a.o.canal.adapter.launcher.loader.CanalAdapterService - ## the canal client adapters are running now ......
2023-11-13 10:12:53.986 [main] INFO  c.a.otter.canal.adapter.launcher.CanalAdapterApplication - Started CanalAdapterApplication in 3.244 seconds (JVM running for 3.607)
2023-11-13 10:12:54.146 [Thread-4] INFO  c.a.otter.canal.adapter.launcher.loader.AdapterProcessor - =============> Subscribe destination: polarstar succeed <=============
\canal.adapter-1.1.7\conf\bootstrap.yml 配置内容:
canal:
  manager:
    jdbc:
      url: jdbc:mysql://127.0.0.1:3306/test_canal_admin?useUnicode=true&characterEncoding=UTF-8
      username: canal
      password: 123456
\canal.adapter-1.1.7\conf\application.yml 配置内容:
server:
  port: 8081

logging:
  level:
    com.alibaba.otter.canal.client.adapter: DEBUG

spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
    default-property-inclusion: non_null

canal.conf:
  mode: tcp #tcp kafka rocketMQ rabbitMQ
  flatMessage: true
  zookeeperHosts:
  syncBatchSize: 1000
  retries: -1
  timeout:
  accessKey:
  secretKey:
  consumerProperties:
    # canal tcp consumer
    canal.tcp.server.host: 127.0.0.1:11111
    canal.tcp.batch.size: 500
    canal.tcp.username:
    canal.tcp.password:
  srcDataSources:
    defaultDS:
      url: jdbc:mysql://127.0.0.1:3306/test_crm?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
      username: canal
      password: 123456
  canalAdapters:
    - instance: polarstar # canal instance Name or mq topic name
      groups:
        - groupId: g1
          outerAdapters:
            - name: logger
            - name: es7
              key: test_user_logs
              hosts: http://127.0.0.1:9200
              properties:
                mode: rest
                security.auth: elastic:123456
                cluster.name: elasticsearch
\canal.adapter-1.1.7\conf\es7\test_es7.yml 配置内容:
dataSourceKey: defaultDS
outerAdapterKey: test_user_logs
destination: polarstar
groupId: g1
esMapping:
  _index: idx-test-user-logs
  _id: _id
#  upsert: true
#  pk: id
  sql: "select id, username, nickname, avatar_url as avatarUrl, sex, country, province, city, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as createdAt, DATE_FORMAT(updated_at, '%Y-%m-%d %H:%i:%s') as updatedAt from t_user_logs"
#  objFields:
#    _labels: array:;
  etlCondition: "where created_at >= {}"
  commitBatch: 3000
全量同步数据

Adapter Launcher启动成功后,执行命令:curl http://127.0.0.1:8081/etl/es7/test_es7.yml -X POST -d "params=2023-10-11 14:49:26"

curl http://127.0.0.1:8081/etl/es7/test_es7.yml -X POST -d "params=2023-10-11 14:49:26"
{"succeeded":true,"resultMessage":"导入ES 数据:539 条"} 

查询Elasticsearch

GET /idx-test-user-logs/_count
{
  "query": {
    "match_all": {}
  }
}
--------------------------------------------------
{
  "count" : 539,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  }
}
问题

1、启动Adapter Launcher时控制台(/canal.adapter-1.1.7/logs/adapter/adapter.log)可能会输出如下异常信息,这是因为plugin里面提供的client-adapter.es7x-1.1.7-jar-with-dependencies.jar与lib底下的Jackson包版本冲突,client-adapter.es7x-1.1.7-jar-with-dependencies.jar里面使用的Elasticsearch客户端依赖版本:7.3.0,我这边是下载源码将其升级到我对应的7.10.2(client-adapter/es7x),其依赖的Jackson版本号也升高了,虽然与lib底下的版本不一致但是我这边没有过多停留在依赖版本不一致的问题上,升级Elasticsearch客户端后org.elasticsearch.cluster.metadata.MappingMetaData类被重命名为org.elasticsearch.cluster.metadata.MappingMetadata,涉及到要修改的类是\canal\client-adapter\es7x\src\main\java\com\alibaba\otter\canal\client\adapter\es7x\support\ES7xTemplate.java和\canal\client-adapter\es7x\src\main\java\com\alibaba\otter\canal\client\adapter\es7x\support\ESConnection.java,重新打包jar复制到lib目录下,启动没有问题。

2023-11-10 10:39:59.837 [main] INFO  c.a.otter.canal.adapter.launcher.CanalAdapterApplication - Starting CanalAdapterApplication using Java 1.8.0_181 on OS-20200615TKXS with PID 15492 (F:\work\canal\canal.adapter-1.1.7\lib\client-adapter.launcher-1.1.7.jar started by Administrator in F:\work\canal\canal.adapter-1.1.7\bin)
2023-11-10 10:39:59.848 [main] INFO  c.a.otter.canal.adapter.launcher.CanalAdapterApplication - No active profile set, falling back to default profiles: default
2023-11-10 10:40:00.503 [main] INFO  org.springframework.cloud.context.scope.GenericScope - BeanFactory id=00d91651-0d64-37f4-8c2b-414d3b7cef67
2023-11-10 10:40:01.064 [main] INFO  o.s.boot.web.embedded.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8081 (http)
2023-11-10 10:40:01.072 [main] INFO  org.apache.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8081"]
2023-11-10 10:40:01.074 [main] INFO  org.apache.catalina.core.StandardService - Starting service [Tomcat]
2023-11-10 10:40:01.075 [main] INFO  org.apache.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.52]
2023-11-10 10:40:01.079 [main] INFO  org.apache.catalina.core.AprLifecycleListener - An older version [1.2.25] of the Apache Tomcat Native library is installed, while Tomcat recommends a minimum version of [1.2.30]
2023-11-10 10:40:01.079 [main] INFO  org.apache.catalina.core.AprLifecycleListener - Loaded Apache Tomcat Native library [1.2.25] using APR version [1.7.0].
2023-11-10 10:40:01.080 [main] INFO  org.apache.catalina.core.AprLifecycleListener - APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true], UDS [false].
2023-11-10 10:40:01.080 [main] INFO  org.apache.catalina.core.AprLifecycleListener - APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
2023-11-10 10:40:01.082 [main] INFO  org.apache.catalina.core.AprLifecycleListener - OpenSSL successfully initialized [OpenSSL 1.1.1g  21 Apr 2020]
2023-11-10 10:40:01.180 [main] INFO  o.a.catalina.core.ContainerBase.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2023-11-10 10:40:01.180 [main] INFO  o.s.b.w.s.context.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1280 ms
2023-11-10 10:40:01.204 [main] ERROR o.springframework.boot.web.embedded.tomcat.TomcatStarter - Error starting Tomcat context. Exception: org.springframework.beans.factory.BeanCreationException. Message: Error creating bean with name 'formContentFilter' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.servlet.filter.OrderedFormContentFilter]: Factory method 'formContentFilter' threw exception; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.fasterxml.jackson.datatype.jsr310.JavaTimeModule]: Constructor threw exception; nested exception is java.lang.VerifyError: Stack map does not match the one at exception handler 81
Exception Details:
  Location:
    com/fasterxml/jackson/databind/deser/std/StdDeserializer._parseDate(Lcom/fasterxml/jackson/core/JsonParser;Lcom/fasterxml/jackson/databind/DeserializationContext;)Ljava/util/Date; @81: astore
  Reason:
    Type 'com/fasterxml/jackson/core/JsonParseException' (current frame, stack[0]) is not assignable to 'com/fasterxml/jackson/core/exc/StreamReadException' (stack map, stack[0])
  Current Frame:
    bci: @72
    flags: { }
    locals: { 'com/fasterxml/jackson/databind/deser/std/StdDeserializer', 'com/fasterxml/jackson/core/JsonParser', 'com/fasterxml/jackson/databind/DeserializationContext' }
    stack: { 'com/fasterxml/jackson/core/JsonParseException' }
  Stackmap Frame:
    bci: @81
    flags: { }
    locals: { 'com/fasterxml/jackson/databind/deser/std/StdDeserializer', 'com/fasterxml/jackson/core/JsonParser', 'com/fasterxml/jackson/databind/DeserializationContext' }
    stack: { 'com/fasterxml/jackson/core/exc/StreamReadException' }
  Bytecode:
    0x0000000: 2bb6 0048 aa00 0000 0000 0095 0000 0001
    0x0000010: 0000 000b 0000 0080 0000 0095 0000 008e
    0x0000020: 0000 0095 0000 0095 0000 003c 0000 0044
    0x0000030: 0000 0095 0000 0095 0000 0095 0000 0077
    0x0000040: 2bb6 0049 4ea7 0061 2bb6 008a 3704 a700
    0x0000050: 233a 062c 2ab4 0002 2bb6 00b9 12ba 03bd
    0x0000060: 0004 b600 bbc0 007d 3a07 1907 b600 8c37
    0x0000070: 04bb 00bc 5916 04b7 00bd b02a 2cb6 0012
    0x0000080: c000 bcb0 2c2b 2a2a b400 02b6 004f 4ea7
    0x0000090: 0017 2a2b 2cb6 00be b02c 2ab4 0002 2bb6
    0x00000a0: 0051 c000 bcb0 2a2d b600 292c b600 bfb0
    0x00000b0:
  Exception Handler Table:
    bci [72, 78] => handler: 81
    bci [72, 78] => handler: 81
  Stackmap Table:
    same_frame_extended(@64)
    same_frame(@72)
    same_locals_1_stack_item_frame(@81,Object[#496])
    append_frame(@113,Top,Long)
    chop_frame(@123,2)
    same_frame(@132)
    same_frame(@146)
    same_frame(@153)
    append_frame(@166,Object[#423])

2023-11-10 10:40:01.236 [main] INFO  org.apache.catalina.core.StandardService - Stopping service [Tomcat]
2023-11-10 10:40:01.354 [main] WARN  o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
2023-11-10 10:40:01.366 [main] INFO  o.s.b.a.logging.ConditionEvaluationReportLoggingListener -

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2023-11-10 10:40:01.398 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:163)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:338)
        at com.alibaba.otter.canal.adapter.launcher.CanalAdapterApplication.main(CanalAdapterApplication.java:22)
Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:142)
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104)
        at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:450)
        at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:199)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:182)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:160)
        ... 6 common frames omitted