canal的远程配置canal.instance.global.mode = manager。。。canal源码追踪解析

一、canal的程序入口

在官网给的GitHub里面的deployer模块里面,官网:https://github.com/alibaba/canal/tree/master/deployer

其中的main方法在:com.alibaba.otter.canal.deployer.CanalLauncher类里面

二、加载canal的全局配置文件

追踪源码发现canal加载配置文件有两种方法:一种加载的是本地的./conf/canal.properties;另一种是加载一个指定数据库的某个字段的值。第一种:称为本地加载,第二种是远程加载。

1、本地加载(默认加载方式)

官网的简易教程就是本地加载的方式:https://github.com/alibaba/canal

2、远程加载

远程加载的配置内容是在一个canal_manager的数据库里面,里面有canal_config、canal_instance_config表

(1)、配置远程加载的数据库的信息,修改./conf/canal.properties文件里面的前三行(加载了远程配置文件的就会覆盖本地的)

canal.manager.jdbc.url=jdbc:mysql://127.0.0.1:3306/canal_manager?useUnicode=true&characterEncoding=UTF-8
canal.manager.jdbc.username=root
canal.manager.jdbc.password=121212

改成自己的数据库,用户和密码(去掉备注),默认数据库是canal_manager

 

(2)、创建远程数据库和表

create database if not EXISTS canal_manager;

create table if not EXISTS canal_manager.canal_config(
id BIGINT,
name VARCHAR(20),
content LONGTEXT,
modified_time TIMESTAMP
);

create table if not EXISTS canal_manager.canal_instance_config(
id BIGINT,
name VARCHAR(20),
content LONGTEXT,
modified_time TIMESTAMP
);

其中canal_config里面的content值就是canal.properties的内容,并且这个表的数据只能有一行,id必须是1

其中canal_instance_config里面的content的值是instance.properties的内容,instance的个数就是数据的行数,也就是每一行对应一个instance。这样在数据库里面修改content的值就可以实现动态的远程的加载配置文件。(配置的这个数据库服务和同步的数据库服务不是一个,ip不一样)

三、官网给的配置方式

1、canal配置方式有两种:

  1. ManagerCanalInstanceGenerator: 基于manager管理的配置方式,目前alibaba内部配置使用这种方式。大家可以实现CanalConfigClient,连接各自的管理系统,即可完成接入。
  2. SpringCanalInstanceGenerator:基于本地spring xml的配置方式,目前开源版本已经自带该功能所有代码,建议使用

针对于以上两种方式:网上更多的是第二种,目前没有看到任何关于第一种manager的配置,以下是个人对于manager的配置。

2、manager配置

这个过程需要修改源码,准备工作需要先把官网的源码下载到本地,源码clone地址:https://github.com/alibaba/canal.git

(1)、修改canal.properties文件

canal.instance.global.mode = manager
canal.instance.global.lazy = false

(2)、重写com.alibaba.otter.canal.instance.manager.CanalConfigClient类(在instance里面)

public class CanalConfigClient {

    /**
     * 根据对应的destinantion查询Canal信息
     */
    public Canal findCanal(String destination) {
        // TODO 根据自己的业务实现
        //获取Apollo的配置
        System.setProperty("app.id","canal");
        System.setProperty("apollo.cluster","default");
        System.setProperty("apollo.meta","http://*.*.*.*:8080,http://*.*.*.*:8080");
        Config config = ConfigService.getConfig(destination+".properties"); //config instance is singleton for each namespace and is never null
        Long slaveId = Long.parseLong(config.getProperty("canal.instance.mysql.slaveId", "123456"));
        String USERNAME = config.getProperty("canal.instance.dbUsername", "canal");
        String PASSWORD = config.getProperty("canal.instance.dbPassword", "canal");
        String MYSQL_ADDRESS = config.getProperty("canal.instance.master.address", "*.*.*.*:3306").split(":")[0];
        int port = Integer.parseInt(config.getProperty("canal.instance.master.address", "*.*.*.*:3306").split(":")[1]);


        Canal canal = new Canal();
        canal.setId(1L);
        canal.setName(destination);
        canal.setDesc("test");

        CanalParameter parameter = new CanalParameter();

        parameter.setZkClusters(Arrays.asList("127.0.0.1:2188"));
        parameter.setMetaMode(CanalParameter.MetaMode.MEMORY);
        parameter.setHaMode(CanalParameter.HAMode.HEARTBEAT);
        parameter.setIndexMode(CanalParameter.IndexMode.MEMORY);

        parameter.setStorageMode(CanalParameter.StorageMode.MEMORY);
        parameter.setMemoryStorageBufferSize(32 * 1024);

        parameter.setSourcingType(CanalParameter.SourcingType.MYSQL);
        parameter.setDbAddresses(Arrays.asList(new InetSocketAddress(MYSQL_ADDRESS, 3306),
                new InetSocketAddress(MYSQL_ADDRESS, 3306)));
        parameter.setDbUsername(USERNAME);
        parameter.setDbPassword(PASSWORD);
        //parameter.setPositions(Arrays.asList("{\"journalName\":\"mysql-bin.000001\",\"position\":6163L,\"timestamp\":1322803601000L}",
        //        "{\"journalName\":\"mysql-bin.000001\",\"position\":6163L,\"timestamp\":1322803601000L}"));


        System.out.println(USERNAME+PASSWORD);
        parameter.setSlaveId(1234L);

        parameter.setDefaultConnectionTimeoutInSeconds(30);
        parameter.setConnectionCharset("UTF-8");
        parameter.setConnectionCharsetNumber((byte) 33);
        parameter.setReceiveBufferSize(8 * 1024);
        parameter.setSendBufferSize(8 * 1024);

        parameter.setDetectingEnable(false);
        parameter.setDetectingIntervalInSeconds(10);
        parameter.setDetectingRetryTimes(3);
        //parameter.setDetectingSQL(DETECTING_SQL);
        canal.setCanalParameter(parameter);

       /* System.out.println(username+password+host+port);
        CanalParameter canalParameter = new CanalParameter();
        canalParameter.setSlaveId(slaveId);
        canalParameter.setDbUsername(username);
        canalParameter.setDbPassword(password);
        canalParameter.setIndexMode(CanalParameter.IndexMode.MEMORY);
        List<InetSocketAddress> dbAddresses = new ArrayList<>();
        dbAddresses.add(new InetSocketAddress(host,port));
        canalParameter.setDbAddresses(dbAddresses);
        canal.setCanalParameter(canalParameter);
        canal.setName(destination);*/
        return  canal;
    }

    /**
     * 根据对应的destinantion查询filter信息
     */
    public String findFilter(String destination) {
        // TODO 根据自己的业务实现
        Config config = ConfigService.getConfig(destination+".properties");
        return config.getProperty("canal.instance.filter.regex",".*\\..*");
    }
}

这两个方法的实现比较简单,但是在运行不成功,可能官网给的源码的关于manager的不是太全,毕竟阿里自己用的是manager配置文件的方式。官网也推荐使用spring的方式,自己修改源码,用manager的方式总是会有意想不到的问题(也可能自己解读源码不全)。

四、总结

对于canal来说配置文件有两部分,一个是:全局的canal.properties(也可以说是canal-server配置),另一个是:instance.properties(也可以说是canal-client配置,也即instance配置)

总的来说有四种加载配置文件的方式:

1、本地加载+spring:默认加载../conf下的所有配置文件,canal.instance.global.mode = spring

2、本地加载+manager:默认加载../conf下的所有配置文件,canal.instance.global.mode = manager,需要重写CanalConfigClient类

3、远程加载+spring:需要在数据库配置,canal_instance_config表里面canal.instance.global.mode = spring

4、远程加载+manager:需要在数据库配置,canal_instance_config表里面canal.instance.global.mode = manager,需要重写CanalConfigClient类

 

个人提醒:重写CanalConfigClient类比较复杂,有写的可以交流一下:QQ群

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值