예제 #1
0
 /// <summary>
 /// 异步ack
 /// </summary>
 private void CanalServerAckStart()
 {
     new Thread(() =>
     {
         _logger.LogInformation("canal-server ack worker thread start ...");
         while (!_isDispose)
         {
             try
             {
                 if (_canalConnector == null)
                 {
                     continue;
                 }
                 if (!_queue.TryDequeue(out var batchId))
                 {
                     continue;
                 }
                 if (batchId > 0)
                 {
                     _canalConnector.Ack(batchId); //如果程序突然关闭 cannal service 会关闭。这里就不会提交,下次重启应用消息会重复推送!
                 }
             }
             catch (Exception)
             {
                 //ignore
             }
         }
     }).Start();
 }
예제 #2
0
        /// <summary>
        /// 发送数据
        /// 如果handler处理失败就停止 保证消息
        /// </summary>
        /// <param name="entrys">一个entry表示一个数据库变更</param>
        /// <param name="batchId"></param>
        private (long, Dictionary <string, ProcessResult>, List <(string, long)>) Send(List <Entry> entrys, long batchId)
        {
            var canalBodyList = GetCanalBodyList(entrys);

            if (canalBodyList.Count < 1)
            {
                return(0, null, null);
            }


            if (_registerTypeList == null || !_registerTypeList.Any())
            {
                return(0, null, null);
            }

            var groupCount = new List <(string, long)>();
            //分组日志
            var group = canalBodyList.Select(r => r.Message).GroupBy(r => new { r.DbName, r.TableName, r.EventType });

            foreach (var g in group)
            {
                groupCount.Add(($"{g.Key.DbName}.{g.Key.TableName}.{g.Key.EventType}", g.Count()));
            }

            Dictionary <string, ProcessResult> result = new Dictionary <string, ProcessResult>();

            foreach (var re in _registerTypeList)
            {
                // ReSharper disable once AssignNullToNotNullAttribute
                result.Add(re.FullName, new ProcessResult());
            }

            try
            {
                foreach (var type in _registerTypeList)
                {
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    // ReSharper disable once AssignNullToNotNullAttribute
                    var re = result[type.FullName];
                    foreach (var message in canalBodyList)
                    {
                        var service = _scope.ServiceProvider.GetRequiredService(type) as INotificationHandler <CanalBody>;
                        service?.Handle(message).ConfigureAwait(false).GetAwaiter().GetResult();
                        re.Total++;
                        if (message.Succ)
                        {
                            re.SuccessCount++;
                        }
                    }
                    stopwatch.Stop();
                    var doutime = (int)stopwatch.Elapsed.TotalSeconds;
                    var time    = doutime > 1 ? ParseTimeSeconds(doutime) : stopwatch.Elapsed.TotalMilliseconds + "ms";
                    re.ProcessTime = time;
                }
            }
            catch (Exception e)
            {
                _logger.LogError(e, "canal produce error,end process!");
                Dispose();
                return(canalBodyList.Count, result, groupCount);
            }

            _canalConnector.Ack(batchId);//如果程序突然关闭 cannal service 会关闭。这里就不会提交,下次重启应用消息会重复推送!
            return(canalBodyList.Count, result, groupCount);
        }