Example #1
0
        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);
        }
Example #2
0
 /// <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;
     }
 }
Example #3
0
        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);
        }