「从零单排canal 04」 启动模块deployer源码解析

基于1.1.5-alpha版本,具体源码笔记可以参考我的github:https://github.com/saigu/JavaKnowledgeGraph/tree/master/code_reading/canal

本文将对canal的启动模块deployer进行分析。

Deployer模块(绿色部分)在整个系统中的角色如下图所示,用来启动canal-server.

在这里插入图片描述
模块内的类如下:

在这里插入图片描述
为了能带着目的看源码,以几个问题开头,带着问题来一起探索deployer模块的源码。

  • CanalServer启动过程中配置如何加载?
  • CanalServer启动过程中涉及哪些组件?
  • 集群模式的canalServer,是如何实现instance的HA呢?
  • 每个canalServer又是怎么获取admin上的配置变更呢?

1.入口类CanalLauncher

这个类是整个canal-server的入口类。负责配置加载和启动canal-server。

主流程如下:

  • 加载canal.properties的配置内容
  • 根据canal.admin.manager是否为空判断是否是admin控制,如果不是admin控制,就直接根据canal.properties的配置来了
    • 如果是admin控制,使用PlainCanalConfigClient获取远程配置
    • 新开一个线程池每隔五秒用http请求去admin上拉配置进行merge(这里依赖了instance模块的相关配置拉取的工具方法)
    • 用md5进行校验,如果canal-server配置有更新,那么就重启canal-server
  • 核心是用canalStarter.start()启动
  • 使用CountDownLatch保持主线程存活
  • 收到关闭信号,CDL-1,然后关闭配置更新线程池,优雅退出
public static void main(String[] args) {
   

    try {
   

        //note:设置全局未捕获异常的处理

        setGlobalUncaughtExceptionHandler();

        /**

         * note:

         * 1.读取canal.properties的配置

         * 可以手动指定配置路径名称

         */

        String conf = System.getProperty("canal.conf", "classpath:canal.properties");

        Properties properties = new Properties();

        if (conf.startsWith(CLASSPATH_URL_PREFIX)) {
   

            conf = StringUtils.substringAfter(conf, CLASSPATH_URL_PREFIX);

            properties.load(CanalLauncher.class.getClassLoader().getResourceAsStream(conf));

        } else {
   

            properties.load(new FileInputStream(conf));

        }

        final CanalStarter canalStater = new CanalStarter(properties);

        String managerAddress = CanalController.getProperty(properties, CanalConstants.CANAL_ADMIN_MANAGER);

        /**

         * note:

         * 2.根据canal.admin.manager是否为空判断是否是admin控制,如果不是admin控制,就直接根据canal.properties的配置来了

         */

        if (StringUtils.isNotEmpty(managerAddress)) {
   

            String user = CanalController.getProperty(properties, CanalConstants.CANAL_ADMIN_USER);

            //省略一部分。。。。。。
          

            /**

             * note:

             * 2.1使用PlainCanalConfigClient获取远程配置

             */

            final PlainCanalConfigClient configClient = new PlainCanalConfigClient(managerAddress,

                    user,

                    passwd,

                    registerIp,

                    Integer.parseInt(adminPort),

                    autoRegister,

                    autoCluster);

            PlainCanal canalConfig = configClient.findServer(null);

            if (canalConfig == null) {
   

                throw new IllegalArgumentException("managerAddress:" + managerAddress

                        + " can't not found config for [" + registerIp + ":" + adminPort

                        + "]");

            }

            Properties managerProperties = canalConfig.getProperties();

            // merge local

            managerProperties.putAll(properties);

            int scanIntervalInSecond = Integer.valueOf(CanalController.getProperty(managerProperties,

                    CanalConstants.CANAL_AUTO_SCAN_INTERVAL,

                    "5"));

            /**

             * note:

             * 2.2 新开一个线程池每隔五秒用http请求去admin上拉配置进行merge(这里依赖了instance模块的相关配置拉取的工具方法)

             */

            executor.scheduleWithFixedDelay(new Runnable() {
   

                private PlainCanal lastCanalConfig;

                public void run() {
   

                    try {
   

                        if (lastCanalConfig == null) {
   

                            lastCanalConfig = configClient.findServer(null);

                        } else {
   

                            PlainCanal newCanalConfig = configClient.findServer(lastCanalConfig.getMd5());

                            /**

                             * note:

                             * 2.3 用md5进行校验,如果canal-server配置有更新,那么就重启canal-server

                             */

                            if (newCanalConfig != null) {
   

                                // 远程配置canal.properties修改重新加载整个应用

                                canalStater.stop();

                                Properties managerProperties = newCanalConfig.getProperties();

                                // merge local

                                managerProperties.putAll(properties);

                                canalStater.setProperties(managerProperties);

                                canalStater.start();

                                lastCanalConfig = newCanalConfig;

                            }

                        }

                    } catch (Throwable e) {
   
                    //....
                    }

                }

            }, 0, scanIntervalInSecond, TimeUnit.SECONDS);

            canalStater.setProperties(managerProperties);

        } else {
   

            canalStater.setProperties(properties);

        }

        canalStater.start();

        //note: 这样用CDL处理和while(true)有点类似

        runningLatch.await();

        executor.shutdownNow();

    } catch (Throwable e) {
   
    //......
    }

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值