日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

canal入门Demo

發(fā)布時(shí)間:2023/12/13 综合教程 41 生活家
生活随笔 收集整理的這篇文章主要介紹了 canal入门Demo 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

關(guān)于canal具體的原理,以及應(yīng)用場景,可以參考開發(fā)文檔:https://github.com/alibaba/canal

下面給出canal的入門Demo

(一)部署canal服務(wù)器

可以參考官方文檔的QuickStart:https://github.com/alibaba/canal/wiki/QuickStart

為了完整性,下面重復(fù)給出如何配置canal服務(wù)器

開啟mysql的binlog功能,并配置binlog模式為row

1. Windows環(huán)境下,是修改my.ini文件:

[mysqld]
log-bin=mysql-bin #添加這一行就ok
binlog-format=ROW #選擇row模式
server_id=1 #配置mysql replaction需要定義,不能和canal的slaveId重復(fù)

2. 在mysql中 配置canal數(shù)據(jù)庫管理用戶,配置相應(yīng)權(quán)限(repication權(quán)限),運(yùn)行mysql后依次運(yùn)行這四條代碼:

1 CREATE USER canal IDENTIFIED BY 'canal';  
2 GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
3 -- GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%' ;
4 FLUSH PRIVILEGES;

3.下載好canal,修改配置 instance.properties:

#################################################
## mysql serverId
canal.instance.mysql.slaveId = 1234
 
# position info,需要改成自己的數(shù)據(jù)庫信息
canal.instance.master.address = 127.0.0.1:3306 
canal.instance.master.journal.name = 
canal.instance.master.position = 
canal.instance.master.timestamp = 
 
#canal.instance.standby.address = 
#canal.instance.standby.journal.name =
#canal.instance.standby.position = 
#canal.instance.standby.timestamp = 
 
# username/password,需要改成自己的數(shù)據(jù)庫信息
canal.instance.dbUsername = canal  
canal.instance.dbPassword = canal
canal.instance.defaultDatabaseName = canal_test
canal.instance.connectionCharset = UTF-8
 
# table regex
canal.instance.filter.regex = .*\..*
 
#################################################

4. 啟動(dòng)startup.bat,并且查看日志log:

如果日志中有記錄,證明canal服務(wù)器部署成功了。

(二)運(yùn)行canal客戶端

運(yùn)行canal客戶端代碼時(shí),一定要先啟動(dòng)canal服務(wù)器!!!

1.建立實(shí)例maven工程:

  

不選擇任何Maven模板

2.添加pom依賴:

<dependency>
    <groupId>com.alibaba.otter</groupId>
    <artifactId>canal.client</artifactId>
    <version>1.0.12</version>
</dependency>

3.更新依賴

4.canal客戶端代碼:

 1 import java.net.InetSocketAddress;
 2 import java.util.List;
 3 
 4 import com.alibaba.otter.canal.client.CanalConnector;
 5 import com.alibaba.otter.canal.protocol.Message;
 6 import com.alibaba.otter.canal.protocol.CanalEntry.Column;
 7 import com.alibaba.otter.canal.protocol.CanalEntry.Entry;
 8 import com.alibaba.otter.canal.protocol.CanalEntry.EntryType;
 9 import com.alibaba.otter.canal.protocol.CanalEntry.EventType;
10 import com.alibaba.otter.canal.protocol.CanalEntry.RowChange;
11 import com.alibaba.otter.canal.protocol.CanalEntry.RowData;
12 import com.alibaba.otter.canal.client.*;
13 
14 public class canal_client {
15 
16     public static void main(String args[]) {
17         // 創(chuàng)建鏈接
18         CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress("127.0.0.1",
19                 11111), "example", "", "");
20         int batchSize = 1000;
21         int emptyCount = 0;
22         try {
23             connector.connect();
24             connector.subscribe(".*\..*");
25             connector.rollback();
26             int totalEntryCount = 1200;
27             while (emptyCount < totalEntryCount) {
28                 Message message = connector.getWithoutAck(batchSize); // 獲取指定數(shù)量的數(shù)據(jù)
29                 long batchId = message.getId();
30                 int size = message.getEntries().size();
31                 if (batchId == -1 || size == 0) {
32                     emptyCount++;
33                     System.out.println("empty count : " + emptyCount);
34                     try {
35                         Thread.sleep(5000);
36                     } catch (InterruptedException e) {
37                         e.printStackTrace();
38                     }
39                 } else {
40                     emptyCount = 0;
41                     printEntry(message.getEntries());
42                 }
43                 connector.ack(batchId); // 提交確認(rèn)
44             }
45             System.out.println("empty too many times, exit");
46         }catch (Exception e){
47             //connector.rollback(batchId); // 處理失敗, 回滾數(shù)據(jù)
48         }
49         finally {
50             connector.disconnect();
51         }
52     }
53 
54     private static void printEntry( List<Entry> entrys) {
55         for (Entry entry : entrys) {
56             if (entry.getEntryType() == EntryType.TRANSACTIONBEGIN || entry.getEntryType() == EntryType.TRANSACTIONEND) {
57                 continue;
58             }
59             RowChange rowChage = null;
60             try {
61                 rowChage = RowChange.parseFrom(entry.getStoreValue());
62             } catch (Exception e) {
63                 throw new RuntimeException("ERROR ## parser of eromanga-event has an error , data:" + entry.toString(), e);
64             }
65 
66             EventType eventType = rowChage.getEventType();
67             System.out.println(String.format("================> binlog[%s:%s] , name[%s,%s] , eventType : %s",
68                     entry.getHeader().getLogfileName(), entry.getHeader().getLogfileOffset(),
69                     entry.getHeader().getSchemaName(), entry.getHeader().getTableName(),
70                     eventType));
71             for (RowData rowData : rowChage.getRowDatasList()) {
72                 if (eventType == EventType.DELETE) {
73                     printColumn(rowData.getBeforeColumnsList());
74                 } else if (eventType == EventType.INSERT) {
75                     printColumn(rowData.getAfterColumnsList());
76                 } else {
77                     System.out.println("-------> before");
78                     printColumn(rowData.getBeforeColumnsList());
79                     System.out.println("-------> after");
80                     printColumn(rowData.getAfterColumnsList());
81                 }
82             }
83         }
84     }
85 
86     private static void printColumn( List<Column> columns) {
87         for (Column column : columns) {
88             System.out.println(column.getName() + " : " + column.getValue() + "    update=" + column.getUpdated());
89         }
90     }
91 }

View Code

5.運(yùn)行客戶端實(shí)例:

6.觸發(fā)數(shù)據(jù)庫變更:

總結(jié):參考網(wǎng)上的資料,運(yùn)行這個(gè)canal的Demo,對canal的機(jī)制有一點(diǎn)了解;當(dāng)MySQL將binary log發(fā)送給canal服務(wù)器,然后canal client從服務(wù)器獲取binary log,同時(shí)解析出來,尤其是解析的過程對于理解canal會(huì)更深刻一點(diǎn)。

建議運(yùn)行的代碼的過程中打斷點(diǎn)調(diào)試處理!

說明:所有內(nèi)容僅做學(xué)習(xí)記錄

總結(jié)

以上是生活随笔為你收集整理的canal入门Demo的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。