private bool PreparedAndEnqueue() { if (_canalConnector == null) { return(false); } Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); var messageList = _canalConnector.GetWithoutAck(_canalOption.GetCountsPerTimes); var batchId = messageList.Id; if (batchId < 1) { return(false); } CanalBody body = new CanalBody(null, batchId); if (messageList.Entries.Count <= 0) { _canalQueue.Enqueue(new CanalQueueData { CanalBody = body }); return(false); } var canalBody = GetCanalBodyList(messageList.Entries, batchId); if (canalBody.Message == null || canalBody.Message.Count < 1) { _canalQueue.Enqueue(new CanalQueueData { CanalBody = body }); return(false); } stopwatch.Stop(); var doutime = (int)stopwatch.Elapsed.TotalSeconds; var time = doutime > 1 ? ParseTimeSeconds(doutime) : stopwatch.Elapsed.TotalMilliseconds + "ms"; var canalQueueData = new CanalQueueData { Time = time, CanalBody = canalBody }; _canalQueue.Enqueue(canalQueueData); return(true); }
/// <summary> /// 发送数据 /// 如果handler处理失败就停止 保证消息 /// </summary> /// <param name="canalBody">一个entry表示一个数据库变更</param> private void Send(CanalBody canalBody) { try { foreach (var type in _registerTypeList) { var service = _scope.ServiceProvider.GetRequiredService(type) as INotificationHandler <CanalBody>; service?.Handle(canalBody).ConfigureAwait(false).GetAwaiter().GetResult(); } } catch (Exception e) { _logger.LogError(e, "canal produce error,end process!"); Dispose(); return; } }
private List <CanalBody> GetCanalBodyList(List <Entry> entrys) { var result = new List <CanalBody>(); foreach (var entry in entrys) { if (entry.EntryType == EntryType.Transactionbegin || entry.EntryType == EntryType.Transactionend) { continue; } //没有拿到db名称或者表名称的直接排除 if (string.IsNullOrEmpty(entry.Header.SchemaName) || string.IsNullOrEmpty(entry.Header.TableName)) { continue; } RowChange rowChange = null; try { //获取行变更 rowChange = RowChange.Parser.ParseFrom(entry.StoreValue); } catch (Exception e) { _logger.LogError(e, $"DbName:{entry.Header.SchemaName},TbName:{entry.Header.TableName} RowChange.Parser.ParseFrom error"); continue; } if (rowChange != null) { //变更类型 insert/update/delete 等等 EventType eventType = rowChange.EventType; //输出binlog信息 表名 数据库名 变更类型 //输出 insert/update/delete 变更类型列数据 foreach (var rowData in rowChange.RowDatas) { var dataChange = new DataChange { DbName = entry.Header.SchemaName, TableName = entry.Header.TableName, CanalDestination = _canalOption.Destination }; if (eventType == EventType.Delete) { dataChange.EventType = "DELETE"; dataChange.BeforeColumnList = DoConvertDataColumn(rowData.BeforeColumns.ToList()); } else if (eventType == EventType.Insert) { dataChange.EventType = "INSERT"; dataChange.AfterColumnList = DoConvertDataColumn(rowData.AfterColumns.ToList()); } else if (eventType == EventType.Update) { dataChange.EventType = "UPDATE"; dataChange.BeforeColumnList = DoConvertDataColumn(rowData.BeforeColumns.ToList()); dataChange.AfterColumnList = DoConvertDataColumn(rowData.AfterColumns.ToList()); } else { continue; } var cloumns = dataChange.AfterColumnList == null || !dataChange.AfterColumnList.Any() ? dataChange.BeforeColumnList : dataChange.AfterColumnList; var primaryKey = cloumns.FirstOrDefault(r => r.IsKey); if (primaryKey == null || string.IsNullOrEmpty(primaryKey.Value)) { //没有主键 _logger.LogError($"DbName: {dataChange.DbName},TbName:{dataChange.TableName} without primaryKey :" + JsonConvert.SerializeObject(dataChange)); continue; } var message = new CanalBody(dataChange); result.Add(message); } } } return(result); }