[Kogel.Subscribe.Mssql]SQL Server增量訂閱,資料庫變更監聽

Kogel 發表於 2022-11-28
資料庫 SQL

此框架是SQL Server增量訂閱,用來監聽增刪改資料庫資料變更

目前僅支援SQL Server,Nuget上可以下載安裝

或者使用Nuget命令新增包

dotnet add package Kogel.Subscribe.Mssql --version 0.0.0.1

 

(一)定義需要監聽表的實體類 

 /// <summary>
    /// 
    /// </summary>
    [Display(Rename = "t_oms_order_detail")]
    [ElasticsearchType(RelationName = "t_oms_order_detail", IdProperty = "Id")]
    public class OmsOrderDetail : IBaseEntity<OmsOrderDetail, int>
    {
        /// <summary>
        /// 
        /// </summary>
        [Identity]
        [Display(Rename = "id")]
        [Nest.PropertyName("id")]
        public override int Id { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Display(Rename = "name")]
        [Nest.PropertyName("name")]
        public string Name { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Display(Rename = "trade_id")]
        [Nest.PropertyName("trade_id")]
        public int? TradeId { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Display(Rename = "descption")]
        [Nest.PropertyName("descption")]
        public string Descption { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Display(Rename = "create_time")]
        [Nest.PropertyName("create_time")]
        public DateTime CreateTime { get; set; }
    }

[Display]和[Identity]屬於Kogel.Dapper.Extension的特性如果[想了解更多請點選],[ElasticsearchType]和[Nest.PropertyName]屬於Elasticsearch特性,如果沒用到可以忽略

 

(二)定義表訂閱

    /// <summary>
    /// 定義表訂閱
    /// </summary>
    public class OmsOrderDetailSubscribe : Subscribe<OmsOrderDetail>
    {
        /// <summary>
        /// 設定連線配置
        /// </summary>
        /// <param name="builder"></param>
        public override void OnConfiguring(OptionsBuilder<OmsOrderDetail> builder)
        {
            //此連線字串賬號需要有管理員許可權
            builder.BuildConnection("資料庫連線字串");
        }
    }

如果需要此表對應多張分表可以設定

//配置所有表分片
builder.BuildShards(new List<string>
            {
                "t_oms_order_detail_1",
                "t_oms_order_detail_2",
                "t_oms_order_detail_3"
            })

 

(1).如果想推送訂閱到RabbitMQ中

builder.BuilderRabbitMQ(new RabbitMQ.Client.ConnectionFactory
            {
                HostName = "localhost",
                UserName = "guest",
                Password = "guest"
            })

可以透過BuildTopic設定交換機名稱

builder.BuildTopic("kogel_subscribe_order_detail")

 

(2).如果想推送訂閱到Kafka中

builder.BuildKafka(new ProducerConfig
            {
                BootstrapServers = "localhost:9092",
                Acks = Acks.None
            })

可以透過BuildTopic設定Topic名稱

builder.BuildTopic("kogel_subscribe_order_detail")

 

(3).如果想推送訂閱到Elasticsearch中

 builder.BuildElasticsearch(new ElasticsearchConfig<OmsOrderDetail>
            {
                Settings = new Nest.ConnectionSettings(new Uri("http://localhost:9200/")),
            })

如果有設定Basic授權

builder.BuildElasticsearch(new ElasticsearchConfig<OmsOrderDetail>
            {
                Settings = new Nest.ConnectionSettings(new Uri("http://localhost:9200/"))
                    .BasicAuthentication("賬號","密碼")
            })

如果想根據自己定義的分片邏輯插入到多個ES索引中可以透過WriteInterceptor

/// <summary>
        /// 設定連線配置
        /// </summary>
        /// <param name="builder"></param>
        public override void OnConfiguring(OptionsBuilder<OmsOrderDetail> builder)
        {
            //此連線字串賬號需要有管理員許可權
            builder.BuildConnection("資料庫連線字串");
            //定義推送ES
            builder.BuildElasticsearch(new ElasticsearchConfig<OmsOrderDetail>
            {
                Settings = new Nest.ConnectionSettings(new Uri("http://localhost:9200/"))
                    .BasicAuthentication("賬號", "密碼"),
                WriteInterceptor = message => WriteInterceptor(message)
            });
        }

        /// <summary>
        /// 定義自己的索引邏輯
        /// </summary>
        /// <param name="messages"></param>
        /// <returns></returns>
        private EsSubscribeMessage<OmsOrderDetail> WriteInterceptor(SubscribeMessage<OmsOrderDetail> message)
        {
            string esIndexName;
            //這裡寫自己索引分片的業務邏輯
            if (message.Result.Id % 3 == 0)
            {
                esIndexName = $"kogel_orders_2";
            }
            else
            {
                esIndexName = $"kogel_orders_1";
            }
            return message.ToEsSubscribeMessage(esIndexName);
        }

並且ES索引不存在的時候會動態建立

 

(4).如果想自定義實現訂閱邏輯,在可以Subscribe訂閱類中重寫

/// <summary>
        /// 訂閱變更 (每一次sql的執行會觸發一次Subscribe)
        /// </summary>
        /// <param name="messageList">訊息列表表示所有影響到的資料變更(會受BuildLimit限制,沒有查詢完成的會在下一次查出)</param>
        public override void Subscribes(List<SubscribeMessage<T>> messageList)
        {
            foreach (var message in messageList)
            {
                Console.WriteLine($"執行動作:{message.Operation},更新的表:{message.TableName},更新的id:{message.Result.GetId()}");
            }
        }

 

以上訂閱的優先順序:

[Kogel.Subscribe.Mssql]SQL Server增量訂閱,資料庫變更監聽

 

(三)訂閱啟動

啟動監聽所有繼承自Subscribe<T>的類,在應用程式啟動時執行即可

ApplicationProgram.Run();

如果是基礎BaseSubscribe<T>中間基類需要定義成abstract,例如

  /// <summary>
    /// 基礎配置類需要定義成abstract
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class BaseSubscribe<T> : Subscribe<T>
        where T : class, IBaseEntity
    {
    }

關閉監聽,在應用程式退出時執行即可

ApplicationProgram.Close();

 

(四)其他配置

builder.BuildCdcConfig(new CdcConfig
            {
                //掃描間隔(每次掃描變更表的間隔,單位毫秒) 預設10000毫秒/10秒
                ScanInterval = 10000,

                //變更捕捉檔案在DB儲存的時間(預設三天)
                Retention = 60 * 24 * 3,

                //是否首次掃描表全部資料再監聽變更(預設false)
                IsFirstScanFull = false,

                //每次檢索的變更量(預設10條)
                Limit = 10,

                //變更掃描的偏移量位置(預設從最後中止處開始)
                OffsetPosition = OffsetPositionEnum.Abort
            })

 

 

框架開源,完整框架原始碼可以去Github上下載:

https://github.com/a935368322/Kogel.Subscribe.Mssql

如有問題也可以加QQ群討論:

技術群 710217654