com.alibaba.otter.canal.parse.exception.CanalParseException: java.io.IOException: connect xxxx:3306 failure
- 背景
最近想自己实现一个监听mysql 同步到RabbitMQ 中的功能,
看了看网上的教程觉得没啥难度就上手了
然后三天的痛苦面具就戴上了o(╥﹏╥)o - 异常
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
没错最后又重安了三遍 还是不行 所以还是自己弄吧
- 分析
这里先说明一下- 这个 0.0.0.0 是我改过的 不是填错了
- 使用的是docker mysql canal安装的都是最新版(2021-12-13)
- canal用户已创建 而且可以登录(也是碰到的坑迷惑人的地方)
- canal - example的配置文件改错了
- 很明显 我没有改错 那么我就想是不是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地址对应不上的问题
- 很明显 我没有改错 那么我就想是不是ip需要配内网ip
- 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