• 公司数据同步程序的设计思路(三)


    在恐慌中度过了一个新年之后,回到了工作岗位,

    刚想起来走之前对同步程序的一次改造。

    基本上已经接近心目中最完美的状态了,

    还有一个需求不太可能需要但很应该比较有用的配置,就是可以配置数据源类型,支持数据库,csv,excel,接口请求等。

    本篇接第一篇的末尾。

    实现了在每个租户编号下面再做一个数组来配置需要同步的数据。

    代码中使用了 Npoco 的 Fetch<dynamic> 动态查询数据,无需建出实体类。

    然后将数据转换为 Json 字符串,以二进制写进请求流直接发送请求即可。

    配置文件改造后如下:

    目前配置的租户数量已经有十个左右了,为了能够分辨,加了一些描述项。

    推送任务变成了数组,可配置多个。

    还和之前一样,拿到了租户配置对象之后,

    使用 Newtonsoft 的 JArray 转换数组配置项:

                ConfigPushItems = JArray.Parse(ConfigItem["PushItems"].ToString());

    然后是主要循环体:

    运行时输出一些关键的配置信息用来确认没有配置问题,然后循环处理每个任务项:

    使用 Npoco 动态查询数据:

            private List<dynamic> GetData(JToken config)
            {
                Print.LogInfo($"开始获取数据:{config["Name"]}");
                var datas = new List<dynamic>();
                using (var db = DBFactory.GetDB())
                {
                    datas = db.Fetch<dynamic>(config["GetDataSql"].ToString());
                }
                Print.LogInfo("获取数据条数:" + datas.Count);
                return datas;
            }

    二进制推送数据:

    private void PushData(JToken pushConfigItem, List<dynamic> data)
            {
                Print.LogInfo($"开始推送数据:{pushConfigItem["Name"]}");
                var allListGroup = DBFactory.GetListGroup(data, 2500);
                Print.LogInfo($"数据分块组数量: {allListGroup.Count}");
    
                for (int i = 0; i < allListGroup.Count; i++)
                {
                    var item = allListGroup[i];
                    Print.LogInfo($"本次推送数量:{item.Count}");
                    var datastr = JArray.FromObject(item).ToString();
                    var pushAddress = string.Format("{0}{1}", HostConfig.GetHostUrl(ConfigItem["Host"].ToString()), pushConfigItem["PushDataAddress"].ToString());
                    pushAddress = Url.ChangeArgTag(pushAddress, "esccode", ConfigItem["EscCode"].ToString());
                    pushAddress = Url.ChangeArgTag(pushAddress, "accesstoken", ToKen);
    
                    Print.LogInfo($"推送数据URL:{pushAddress}");
                    var result = Http.Post(pushAddress, datastr);
                    if (result == null)
                    { Print.Err("接口返回值为 NULL"); }
                    var resultJobj = JObject.Parse(result);
                    Print.LogInfo($"推送数据完成 返回体:{result.ToString()}");
                }
    
                Print.LogInfo($"推送数据:{pushConfigItem["Name"]} 完成");
            }

    这里还有一个小插曲,

    在正式服务器上执行时总会报 基础链接已关闭 的异常,一开始我还以为是服务器网络设置的问题,

    百度的大多解决方案大多是回收请求GC,主动释放请求对象,使用 ServicePointManager 对象设置请求的一些系统级设置。

    多次尝试后无果,最后发现数据量在3000条往上就会报这个异常,少于这个数量则没有问题。

    所以增加了一道推送数据的分块,每次只推送2500条数据。也算是曲线救国吧。原因的话还不是很清楚,可能是我们平台限制了请求大小?

    至此,这个小玩意应该可以满足我可预见的需求了。

    稍候将会将代码修改成相对通用的放在我的 github 上。

  • 相关阅读:
    Orchard Oracle 支持
    讽刺的是,我在linux下使用最多的命令,竟然是windows的
    学习bash
    提高分布式环境中程序启动性能的一个方法
    MQTT X v1.4.1 正式发布
    社区力量|因为 EMQ,他上了微博热搜
    不止是现在,更关注未来:EMQ 携手高校加强物联网人才培养
    EMQ 助力西安增材制造国家研究院打造增材智能车间平台
    Kuiper 1.0.1 正式发布
    MQTT X v1.4.0 正式发布
  • 原文地址:https://www.cnblogs.com/Aaxuan/p/12502426.html
Copyright © 2020-2023  润新知