From eca5d9d71d93720edde9d5d8ec500cd885291117 Mon Sep 17 00:00:00 2001 From: GuangJie1 Date: Fri, 27 Jun 2025 11:05:01 +0800 Subject: [PATCH] add canal readme --- Others/canal/README.md | 92 ++++++++++++++++++++++++++++ Others/canal/doc/image-info.yml | 98 ++++++++++++++++++++++++++++++ Others/canal/doc/picture/logo.png | Bin 0 -> 12962 bytes 3 files changed, 190 insertions(+) create mode 100644 Others/canal/README.md create mode 100644 Others/canal/doc/image-info.yml create mode 100644 Others/canal/doc/picture/logo.png diff --git a/Others/canal/README.md b/Others/canal/README.md new file mode 100644 index 00000000..a2c4a5cc --- /dev/null +++ b/Others/canal/README.md @@ -0,0 +1,92 @@ + +# Quick reference + +- The official canal docker image. + +- Maintained by: [openEuler CloudNative SIG](https://gitee.com/openeuler/cloudnative). + +- Where to get help: [openEuler CloudNative SIG](https://gitee.com/openeuler/cloudnative), [openEuler](https://gitee.com/openeuler/community). +# canal | openEuler +Current canal images are built on the [openEuler](https://repo.openeuler.org/). This repository is free to use and exempted from per-user rate limits. + +Canal is an open-source project developed by Alibaba for real-time data synchronization. It is designed to capture and parse MySQL binlog (binary logs), allowing downstream systems to consume change data in near real-time. + +# Supported tags and respective Dockerfile links +The tag of each canal docker image is consist of the version of canal and the version of basic image. The details are as follows + +| Tags | Currently | Architectures| +|------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------|--| +| [1.1.8-oe2403sp1](https://gitee.com/openeuler/openeuler-docker-images/blob/master/Others/canal/1.1.8/24.03-lts-sp1/Dockerfile) | canal 1.1.8 on openEuler 24.03-LTS-SP1 | amd64, arm64 | + +# Usage +- Add canal client dependency + + Add the following dependency to your `pom.xml` to include the `Canal Java Client`. + ``` + + com.alibaba.otter + canal.client + 1.1.0 + + ``` + +- Create a standard maven project + + You can create a standard Maven project using the Maven Archetype Plugin. + + **For older Maven versions:** + ``` + mvn archetype:create -DgroupId=com.alibaba.otter -DartifactId=canal.sample + ``` + **For Maven 3.0.5 and above(recommended):** + ``` + mvn archetype:generate -DgroupId=com.alibaba.otter -DartifactId=canal.sample + ``` + This generates a basic Maven project structure. + +- Write the `ClientSample` class + Here is a basic example of a Java client connecting to a Canal server: + ``` + package com.alibaba.otter; + + import com.alibaba.otter.canal.client.CanalConnector; + import com.alibaba.otter.canal.client.CanalConnectors; + import com.alibaba.otter.canal.protocol.Message; + + import java.net.InetSocketAddress; + + public class ClientSample { + public static void main(String[] args) { + CanalConnector connector = CanalConnectors.newSingleConnector( + new InetSocketAddress("127.0.0.1", 11111), + "example", + "", + "" + ); + try { + connector.connect(); + connector.subscribe(".*\\..*"); + connector.rollback(); + while (true) { + Message message = connector.getWithoutAck(100); + long batchId = message.getId(); + int size = message.getEntries().size(); + if (batchId != -1 && size > 0) { + System.out.printf("Received batchId: %d, entry size: %d%n", batchId, size); + } + connector.ack(batchId); + } + } finally { + connector.disconnect(); + } + } + } + ``` + + **Notes:** + * Ensure the `Canal Server` is running and correctly configured (refer to the [QuickStart](https://github.com/alibaba/canal/wiki/QuickStart)). + * The above code connects to `127.0.0.1:11111`, which is the default TCP port for the Canal Server. + * `subscribe(".*\\..*")` means subscribe to all tables in all databases. + +# Question and answering +If you have any questions or want to use some special features, please submit an issue or a pull request on [openeuler-docker-images](https://gitee.com/openeuler/openeuler-docker-images). \ No newline at end of file diff --git a/Others/canal/doc/image-info.yml b/Others/canal/doc/image-info.yml new file mode 100644 index 00000000..422ff587 --- /dev/null +++ b/Others/canal/doc/image-info.yml @@ -0,0 +1,98 @@ +name: busybox +category: others +description: canal主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费 +environment: | + 本应用在Docker环境中运行,安装Docker执行如下命令 + ``` + yum install -y docker + ``` +tags: | + busybox镜像的Tag由其版本信息和基础镜像版本信息组成,详细内容如下 + + | Tag | Currently | Architectures | + |----------|-------------|------------------| + | [1.1.8-oe2403sp1](https://gitee.com/openeuler/openeuler-docker-images/blob/master/Others/canal/1.1.8/24.03-lts-sp1/Dockerfile) | canal 1.1.8 on openEuler 24.03-LTS-SP1 | amd64, arm64 | + + 注意,以下`{Tag}`的值按照需求,替换为上述表格中的tag内容。 + +download: | + 拉取镜像到本地 + ``` + docker pull openeuler/busybox:{Tag} + ``` + +usage: | + - 添加 canal 客户端依赖 + 在你的 pom.xml 中添加以下依赖项,以引入 Canal Java 客户端: + ``` + + com.alibaba.otter + canal.client + 1.1.0 + + ``` + + - 创建标准 Maven 工程 + + 你可以使用 Maven Archetype 插件来创建一个标准的 Maven 工程。 + + **旧版本 Maven:** + ``` + mvn archetype:create -DgroupId=com.alibaba.otter -DartifactId=canal.sample + ``` + **Maven 3.0.5 及以上(推荐):** + ``` + mvn archetype:generate -DgroupId=com.alibaba.otter -DartifactId=canal.sample + ``` + 这将生成一个基础的 Maven 项目结构。 + + - 编写 ClientSample 类 + 以下是一个 Java 客户端连接 `Canal Server` 的基本示例: + ``` + package com.alibaba.otter; + + import com.alibaba.otter.canal.client.CanalConnector; + import com.alibaba.otter.canal.client.CanalConnectors; + import com.alibaba.otter.canal.protocol.Message; + + import java.net.InetSocketAddress; + + public class ClientSample { + public static void main(String[] args) { + CanalConnector connector = CanalConnectors.newSingleConnector( + new InetSocketAddress("127.0.0.1", 11111), + "example", + "", + "" + ); + try { + connector.connect(); + connector.subscribe(".*\\..*"); + connector.rollback(); + while (true) { + Message message = connector.getWithoutAck(100); + long batchId = message.getId(); + int size = message.getEntries().size(); + if (batchId != -1 && size > 0) { + System.out.printf("Received batchId: %d, entry size: %d%n", batchId, size); + } + connector.ack(batchId); + } + } finally { + connector.disconnect(); + } + } + } + ``` + + **注意事项:** + * 请确保 `Canal Server` 已启动并正确配置(参考 [QuickStart](https://github.com/alibaba/canal/wiki/QuickStart))。 + * 上述代码连接的是 `127.0.0.1:11111`,这是 Canal Server 的默认 TCP 端口。 + * `subscribe(".*\\..*")` 表示订阅所有数据库的所有表。 + +license: Apache-2.0 license +similar_packages: + - N/A +dependency: + - openjdk + - maven \ No newline at end of file diff --git a/Others/canal/doc/picture/logo.png b/Others/canal/doc/picture/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..244e9cc8bdb300e268ed414f54f5212a3e722d76 GIT binary patch literal 12962 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 VKhyO^L;3#2VW?-OTYVLU`#;r-{3QSY literal 0 HcmV?d00001 -- Gitee