公司数据同步程序的设计思路(三)
在恐慌中度过了一个新年之后,回到了工作岗位,
刚想起来走之前对同步程序的一次改造。
基本上已经接近心目中最完美的状态了,
还有一个需求不太可能需要但很应该比较有用的配置,就是可以配置数据源类型,支持数据库,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 上。