import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
-
@Package: com.zks.canal.deploy
-
@ClassName: CanalClient
-
@Author: ZhouKaiShun
-
@CreateTime: 2021/9/13 11:54
-
@Description: canal客户端
*/
@Component
@Slf4j
public class CanalClient implements ApplicationRunner {
@Resource
private KafkaProducer kafkaProducer;
private final static int BATCH_SIZE = 1000;
/**
- sql队列
*/
private Queue SQL_QUEUE = new ConcurrentLinkedQueue<>();
/**
- 订阅的数据库表
*/
public static String SUBSCRIBE_DB_TABLE = “kaishun.tb_user”;
@Override
public void run(ApplicationArguments args) throws Exception {
log.info(“启动canal服务,端口号:7111”);
// 创建链接
CanalConnector connector = CanalConnectors.newSingleConnector(
new InetSocketAddress(“127.0.0.1”, 11111), “example”, “”, “”);
try {
//打开连接
connector.connect();
//订阅数据库表(全库全表:.\… 指定库全表:库名…* 单表:库名.表名 多规则组合使用:库名1…*,库名2.表名1,库名3.表名2 (逗号分隔))
connector.subscribe(SUBSCRIBE_DB_TABLE);
//回滚到未进行ack的地方,下次fetch的时候,可以从最后一个没有ack的地方开始拿
connector.rollback();
while (true) {
//尝试从master那边拉去数据batchSize条记录,有多少取多少
Message message = connector.getWithoutAck(BATCH_SIZE);
//获取批量ID
long batchId = message.getId();
//获取批量的数量
int size = message.getEntries().size();
//如果没有数据
if (batchId == -1 || size == 0) {
try {
//线程休眠2秒
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
//处理数据为sql
dataHandle(message.getEntries());
}
/设置队列sql语句执行最大值/
if (SQL_QUEUE.size() >= 1) {
executeQueueSql();
}
//进行 batch id 的确认。确认之后,小于等于此 batchId 的 Message 都会被确认。
connector.ack(batchId);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
connector.disconnect();
}
System.out.println(“连接canal end”);
}
/**
-
@description: 处理队列里sql
-
@