Docker整合canal 踩坑实录

com.alibaba.otter.canal.parse.exception.CanalParseException: java.io.IOException: connect xxxx:3306 failure
  1. 背景
    最近想自己实现一个监听mysql 同步到RabbitMQ 中的功能,
    看了看网上的教程觉得没啥难度就上手了
    然后三天的痛苦面具就戴上了o(╥﹏╥)o
  2. 异常
com.alibaba.otter.canal.parse.exception.CanalParseException: java.io.IOException: connect /0.0.0.0:3306 failure
63843 Caused by: java.io.IOException: connect /0.0.0.0:3306 failure
63844         at com.alibaba.otter.canal.parse.driver.mysql.MysqlConnector.connect(MysqlConnector.java:85) ~[canal.parse.driver-1.1.5.jar:na]
63845         at com.alibaba.otter.canal.parse.inbound.mysql.MysqlConnection.connect(MysqlConnection.java:90) ~[canal.parse-1.1.5.jar:na]
63846         at com.alibaba.otter.canal.parse.inbound.mysql.MysqlEventParser.preDump(MysqlEventParser.java:86) ~[canal.parse-1.1.5.jar:na]
63847         at com.alibaba.otter.canal.parse.inbound.AbstractEventParser$1.run(AbstractEventParser.java:176) ~[canal.parse-1.1.5.jar:na]
63848         at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]
63849 Caused by: java.net.ConnectException: Connection refused (Connection refused)
63850         at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_181]
63851         at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_181]
63852         at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:204) ~[na:1.8.0_181]
63853         at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_181]
63854         at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_181]
63855         at java.net.Socket.connect(Socket.java:589) ~
[na:1.8.0_181]
63856         at com.alibaba.otter.canal.parse.driver.mysql.socket.BioSocketChannelPool.open(BioSocketChannelPool.java:18) ~[canal.parse.driver-1.1.5.jar:na]
63857         at com.alibaba.otter.canal.parse.driver.mysql.socket.SocketChannelPool.open(SocketChannelPool.java:18) ~[canal.parse.driver-1.1.5.jar:na]
63858         at com.alibaba.otter.canal.parse.driver.mysql.MysqlConnector.connect(MysqlConnector.java:80) ~[canal.parse.driver-1.1.5.jar:na]
63859         ... 4 common frames omitted

报的异常很简单 就是连接不上 ,那么就开始分析(百度)

  • canal常见问题总结
  • canal问题排查
  • docker整合canal
    没错最后又重安了三遍 还是不行 所以还是自己弄吧
  1. 分析
    这里先说明一下
    • 这个 0.0.0.0 是我改过的 不是填错了
    • 使用的是docker mysql canal安装的都是最新版(2021-12-13)
    • canal用户已创建 而且可以登录(也是碰到的坑迷惑人的地方)
  • canal - example的配置文件改错了
    Docker整合canal 踩坑实录_第1张图片
    Docker整合canal 踩坑实录_第2张图片
    • 很明显 我没有改错 那么我就想是不是ip需要配内网ip
      这里直接说结论 :确实就是公网ip
      localhost ; 0.0.0.0 ; 127.0.0.1 ; 内网ip
      试过的结果都是一样的
      (ps: 这里修改完canal的配置文件记得重启 ->
      docker restart 镜像名)
    • 我的mysql目录挂载在 /opt/mysql 下
    • 我的canal目录挂载在/opt/canal 下
    • 网上的教程很多都是删除canal的example的etc文件 但是我的文件是正常的 没有网上说的和bin_log地址对应不上的问题
  • Mysql
    • 然后我的目光就对准了mysql 配置
这里也是一个坑
要指定忽略大小写和时区 镜像起来后在配置文件中配置是不管用的
docker run --restart=unless-stopped -d --name mysql \
 -v /opt/mysql/conf/my.cnf:/etc/mysql/my.cnf \ 
 -v /opt/mysql/data:/var/lib/mysql -p 3306:3306 \
 -e MYSQL_ROOT_PASSWORD=root \
 -e TZ=Asia/Shanghai mysql \
 --lower_case_table_names=1

这是用到的查看命令 可以粘走存一个sql文件 挺有用的
-- 查看是否开始bin_log
show variables like 'log_bin';

-- 查看是否开启忽略大小写
show variables like "%case%"-- 查看时区
select now();
-- mysql8 这里的时区也需要在启动时指定 这里无效
SET GLOBAL time_zone = 'Asia/Shanghai';
flush privileges;
-- 创建canal用户
create user 'canal'@'%' identified by 'canal';
-- 分配权限
grant SELECT, REPLICATION SLAVE, REPLICATION CLIENT on *.* to 'canal'@'%';
update user set host = 'localhost' where user = 'canal' and host='%';
grant SELECT, REPLICATION SLAVE, REPLICATION CLIENT on *.* to 'canal'@'%';
-- 设置密码加密方式
ALTER USER 'canal'@'%' IDENTIFIED WITH mysql_native_password BY 'canal';
-- 查看canal的状态
show grants for 'canal';

show variables like 'binlog_format%'; 
-- 查看bin_log
show binary logs;

-- 查看所有用户访问权限
 SELECT DISTINCT CONCAT('User: ''',user,'''@''',host,''';') AS query FROM mysql.user;
  • 这里有细心的童鞋们就要问了 为什么你的canal用户设置了两遍访问权限

没错 没错 问题就出在这里!

ε=ε=ε=(#>д<)ノ##

我们设置完canal的访问权限后 是

User: 'canal'@'%';
User: 'root'@'%';
>看这里等下会多一条<
User: 'mysql.infoschema'@'localhost';
User: 'mysql.session'@'localhost';
User: 'mysql.sys'@'localhost';
User: 'root'@'localhost';

但是由于mysql8.0之后 如果只设置了 % 的访问权限,
会导致localhost无法访问
所以 我们需要把当前权限更新为 localhost 再执行一遍

update user set host = 'localhost' where user = 'canal' and host='%';
grant SELECT, REPLICATION SLAVE, REPLICATION CLIENT on *.* to 'canal'@'%';

这样我们再查询canal用户的权限的时候就会多一条

User: 'canal'@'%';
User: 'root'@'%';
User: 'canal'@'localhost';
User: 'mysql.infoschema'@'localhost';
User: 'mysql.session'@'localhost';
User: 'mysql.sys'@'localhost';
User: 'root'@'localhost';

然后刷新配置

flush privileges;
  • 重启canal(个人喜欢重启 这边可能不需要重启)
  • 访问 example 的日志文件
    在这里插入图片描述
  • 成功链接到mysql

你可能感兴趣的:(docker,java,容器,mysql)