|
@@ -1,22 +1,22 @@ |
|
|
package cc.smtweb.system.canal.example; |
|
|
package cc.smtweb.system.canal.example; |
|
|
|
|
|
|
|
|
import cc.smtweb.framework.core.util.CommUtil; |
|
|
import cc.smtweb.framework.core.util.CommUtil; |
|
|
|
|
|
import cc.smtweb.framework.core.util.DateUtil; |
|
|
import cc.smtweb.framework.core.util.JsonUtil; |
|
|
import cc.smtweb.framework.core.util.JsonUtil; |
|
|
import com.alibaba.otter.canal.client.CanalConnector; |
|
|
import com.alibaba.otter.canal.client.CanalConnector; |
|
|
import com.alibaba.otter.canal.client.CanalConnectors; |
|
|
import com.alibaba.otter.canal.client.CanalConnectors; |
|
|
import com.alibaba.otter.canal.protocol.CanalEntry; |
|
|
import com.alibaba.otter.canal.protocol.CanalEntry; |
|
|
import com.alibaba.otter.canal.protocol.Message; |
|
|
import com.alibaba.otter.canal.protocol.Message; |
|
|
|
|
|
import org.apache.commons.io.FileUtils; |
|
|
import org.apache.commons.lang.StringUtils; |
|
|
import org.apache.commons.lang.StringUtils; |
|
|
import org.slf4j.Logger; |
|
|
import org.slf4j.Logger; |
|
|
import org.slf4j.LoggerFactory; |
|
|
import org.slf4j.LoggerFactory; |
|
|
import org.springframework.util.Assert; |
|
|
import org.springframework.util.Assert; |
|
|
|
|
|
|
|
|
|
|
|
import java.io.File; |
|
|
import java.io.FileInputStream; |
|
|
import java.io.FileInputStream; |
|
|
import java.net.InetSocketAddress; |
|
|
import java.net.InetSocketAddress; |
|
|
import java.util.HashMap; |
|
|
|
|
|
import java.util.List; |
|
|
|
|
|
import java.util.Map; |
|
|
|
|
|
import java.util.Properties; |
|
|
|
|
|
|
|
|
import java.util.*; |
|
|
import java.util.regex.Matcher; |
|
|
import java.util.regex.Matcher; |
|
|
import java.util.regex.Pattern; |
|
|
import java.util.regex.Pattern; |
|
|
|
|
|
|
|
@@ -112,6 +112,7 @@ public class ClientInstance { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
protected void process() { |
|
|
protected void process() { |
|
|
|
|
|
final int batchSize = ClientConsts.getBatchSize(properties); |
|
|
while (running) { |
|
|
while (running) { |
|
|
try { |
|
|
try { |
|
|
connector.disconnect(); |
|
|
connector.disconnect(); |
|
@@ -119,11 +120,11 @@ public class ClientInstance { |
|
|
connector.unsubscribe(); |
|
|
connector.unsubscribe(); |
|
|
connector.subscribe(ClientConsts.getFilter(properties)); |
|
|
connector.subscribe(ClientConsts.getFilter(properties)); |
|
|
while (running) { |
|
|
while (running) { |
|
|
Message message = connector.getWithoutAck(ClientConsts.getBatchSize(properties) * 1024); // 获取指定数量的数据 |
|
|
|
|
|
|
|
|
Message message = connector.getWithoutAck(batchSize * 1024); // 获取指定数量的数据 |
|
|
long batchId = message.getId(); |
|
|
long batchId = message.getId(); |
|
|
int size = message.getEntries().size(); |
|
|
int size = message.getEntries().size(); |
|
|
if (batchId == -1 || size == 0) { |
|
|
if (batchId == -1 || size == 0) { |
|
|
Thread.sleep(3000L);//无数据时,睡眠。 |
|
|
|
|
|
|
|
|
Thread.sleep(10 * 1000L);//无数据时,睡眠10秒。 |
|
|
continue; |
|
|
continue; |
|
|
} else { |
|
|
} else { |
|
|
dataHandle(message.getEntries()); |
|
|
dataHandle(message.getEntries()); |
|
@@ -183,19 +184,26 @@ public class ClientInstance { |
|
|
* @param entrys |
|
|
* @param entrys |
|
|
*/ |
|
|
*/ |
|
|
private void dataHandle(List<CanalEntry.Entry> entrys) throws Exception { |
|
|
private void dataHandle(List<CanalEntry.Entry> entrys) throws Exception { |
|
|
|
|
|
List<ClientVO> data = new ArrayList<>(); |
|
|
for (CanalEntry.Entry entry : entrys) { |
|
|
for (CanalEntry.Entry entry : entrys) { |
|
|
if (CanalEntry.EntryType.ROWDATA == entry.getEntryType()) { |
|
|
|
|
|
CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue()); |
|
|
|
|
|
CanalEntry.EventType eventType = rowChange.getEventType(); |
|
|
|
|
|
if (eventType == CanalEntry.EventType.DELETE) { |
|
|
|
|
|
saveDeleteSql(entry); |
|
|
|
|
|
} else if (eventType == CanalEntry.EventType.UPDATE) { |
|
|
|
|
|
saveUpdateSql(entry); |
|
|
|
|
|
} else if (eventType == CanalEntry.EventType.INSERT) { |
|
|
|
|
|
saveInsertSql(entry); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (CanalEntry.EntryType.ROWDATA != entry.getEntryType()) continue; |
|
|
|
|
|
CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue()); |
|
|
|
|
|
CanalEntry.EventType eventType = rowChange.getEventType(); |
|
|
|
|
|
ClientVO row = null; |
|
|
|
|
|
if (eventType == CanalEntry.EventType.DELETE) { |
|
|
|
|
|
row = saveDeleteSql(entry); |
|
|
|
|
|
} else if (eventType == CanalEntry.EventType.UPDATE) { |
|
|
|
|
|
row = saveUpdateSql(entry); |
|
|
|
|
|
} else if (eventType == CanalEntry.EventType.INSERT) { |
|
|
|
|
|
row = saveInsertSql(entry); |
|
|
} |
|
|
} |
|
|
|
|
|
if (row == null) continue; |
|
|
|
|
|
data.add(row); |
|
|
} |
|
|
} |
|
|
|
|
|
CanalEntry.Entry entry = entrys.get(entrys.size() - 1); |
|
|
|
|
|
logger.debug("sync data size:" + data.size() + ",canal position:filename:" + entry.getHeader().getLogfileName() + ",offset:" + entry.getHeader().getLogfileOffset()); |
|
|
|
|
|
if (data.size() == 0) return; |
|
|
|
|
|
saveToFile(data); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
@@ -203,7 +211,7 @@ public class ClientInstance { |
|
|
* |
|
|
* |
|
|
* @param entry |
|
|
* @param entry |
|
|
*/ |
|
|
*/ |
|
|
private void saveUpdateSql(CanalEntry.Entry entry) { |
|
|
|
|
|
|
|
|
private ClientVO saveUpdateSql(CanalEntry.Entry entry) { |
|
|
try { |
|
|
try { |
|
|
CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue()); |
|
|
CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue()); |
|
|
List<CanalEntry.RowData> rowDatasList = rowChange.getRowDatasList(); |
|
|
List<CanalEntry.RowData> rowDatasList = rowChange.getRowDatasList(); |
|
@@ -218,10 +226,12 @@ public class ClientInstance { |
|
|
List<CanalEntry.Column> oldColumnList = rowData.getBeforeColumnsList(); |
|
|
List<CanalEntry.Column> oldColumnList = rowData.getBeforeColumnsList(); |
|
|
ClientVO update = ClientVO.ok(entry.getHeader().getTableName(), "UPDATE", data, oldColumnList.get(0).getValue()); |
|
|
ClientVO update = ClientVO.ok(entry.getHeader().getTableName(), "UPDATE", data, oldColumnList.get(0).getValue()); |
|
|
System.out.println("更新返回 : " + JsonUtil.encodeString(update)); |
|
|
System.out.println("更新返回 : " + JsonUtil.encodeString(update)); |
|
|
|
|
|
return update; |
|
|
} |
|
|
} |
|
|
} catch (Exception e) { |
|
|
} catch (Exception e) { |
|
|
e.printStackTrace(); |
|
|
e.printStackTrace(); |
|
|
} |
|
|
} |
|
|
|
|
|
return null; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
@@ -229,7 +239,7 @@ public class ClientInstance { |
|
|
* |
|
|
* |
|
|
* @param entry |
|
|
* @param entry |
|
|
*/ |
|
|
*/ |
|
|
private void saveDeleteSql(CanalEntry.Entry entry) { |
|
|
|
|
|
|
|
|
private ClientVO saveDeleteSql(CanalEntry.Entry entry) { |
|
|
try { |
|
|
try { |
|
|
CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue()); |
|
|
CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue()); |
|
|
List<CanalEntry.RowData> rowDatasList = rowChange.getRowDatasList(); |
|
|
List<CanalEntry.RowData> rowDatasList = rowChange.getRowDatasList(); |
|
@@ -237,10 +247,12 @@ public class ClientInstance { |
|
|
List<CanalEntry.Column> oldColumnList = rowData.getBeforeColumnsList(); |
|
|
List<CanalEntry.Column> oldColumnList = rowData.getBeforeColumnsList(); |
|
|
ClientVO delete = ClientVO.ok(entry.getHeader().getTableName(), "DELETE", null, oldColumnList.get(0).getValue()); |
|
|
ClientVO delete = ClientVO.ok(entry.getHeader().getTableName(), "DELETE", null, oldColumnList.get(0).getValue()); |
|
|
System.out.println("删除返回 : " + JsonUtil.encodeString(delete)); |
|
|
System.out.println("删除返回 : " + JsonUtil.encodeString(delete)); |
|
|
|
|
|
return delete; |
|
|
} |
|
|
} |
|
|
} catch (Exception e) { |
|
|
} catch (Exception e) { |
|
|
e.printStackTrace(); |
|
|
e.printStackTrace(); |
|
|
} |
|
|
} |
|
|
|
|
|
return null; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
@@ -248,7 +260,7 @@ public class ClientInstance { |
|
|
* |
|
|
* |
|
|
* @param entry |
|
|
* @param entry |
|
|
*/ |
|
|
*/ |
|
|
private void saveInsertSql(CanalEntry.Entry entry) { |
|
|
|
|
|
|
|
|
private ClientVO saveInsertSql(CanalEntry.Entry entry) { |
|
|
try { |
|
|
try { |
|
|
CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue()); |
|
|
CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue()); |
|
|
List<CanalEntry.RowData> rowDatasList = rowChange.getRowDatasList(); |
|
|
List<CanalEntry.RowData> rowDatasList = rowChange.getRowDatasList(); |
|
@@ -262,10 +274,12 @@ public class ClientInstance { |
|
|
}); |
|
|
}); |
|
|
ClientVO insert = ClientVO.ok(entry.getHeader().getTableName(), "INSERT", data, null); |
|
|
ClientVO insert = ClientVO.ok(entry.getHeader().getTableName(), "INSERT", data, null); |
|
|
System.out.println("插入返回 : " + JsonUtil.encodeString(insert)); |
|
|
System.out.println("插入返回 : " + JsonUtil.encodeString(insert)); |
|
|
|
|
|
return insert; |
|
|
} |
|
|
} |
|
|
} catch (Exception e) { |
|
|
} catch (Exception e) { |
|
|
e.printStackTrace(); |
|
|
e.printStackTrace(); |
|
|
} |
|
|
} |
|
|
|
|
|
return null; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
@@ -285,6 +299,34 @@ public class ClientInstance { |
|
|
matcher.appendTail(sb); |
|
|
matcher.appendTail(sb); |
|
|
return sb.toString(); |
|
|
return sb.toString(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static synchronized File createFile(String basePath) throws Exception { |
|
|
|
|
|
String path = basePath; |
|
|
|
|
|
if (!path.endsWith("/")) { |
|
|
|
|
|
path = path + "/"; |
|
|
|
|
|
} |
|
|
|
|
|
File file = new File(path + DateUtil.getNowYm() + "/" + DateUtil.nowDateLong() + "/" + DateUtil.toLongDateTimeString(null) + ".cf"); |
|
|
|
|
|
if (!file.getParentFile().exists()) { // 如果父目录不存在,创建父目录 |
|
|
|
|
|
file.getParentFile().mkdirs(); |
|
|
|
|
|
} |
|
|
|
|
|
while (file.exists()) { |
|
|
|
|
|
Thread.sleep(1); |
|
|
|
|
|
file = new File(path + DateUtil.getNowYm() + "/" + DateUtil.nowDateLong() + "/" + DateUtil.toLongDateTimeString(null) + ".cf"); |
|
|
|
|
|
/*if (file.exists()) { |
|
|
|
|
|
return file; |
|
|
|
|
|
}*/ |
|
|
|
|
|
} |
|
|
|
|
|
file.createNewFile(); |
|
|
|
|
|
if (file.exists()) logger.debug("canal文件生成成功:" + file.getName()); |
|
|
|
|
|
return file; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void saveToFile(List<ClientVO> rows) throws Exception { |
|
|
|
|
|
// 将格式化后的字符串写入文件 |
|
|
|
|
|
FileUtils.writeStringToFile(createFile(ClientConsts.getFilepath(properties)), JsonUtil.encodeString(rows), "UTF-8"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|