/// <summary> /// 插入队列信息到mysql数据库 /// </summary> /// <param name="item"></param> public void QueueInfo2DB(baseQueue.QueueItem item) { mySql.Model.syn_queue queue_model = new mySql.Model.syn_queue(); queue_model.create_time = item.dtTime; queue_model.exc_state = (int)item.excState; queue_model.queid = item.queueNo; queue_model.snowid = item.snowflakeId; queue_model.syn_direction = (int)item.iDirection; queue_model.syn_state = (int)item.syncState; queue_model.syn_times = (int)item.syncTimes; new BLL.syn_queue().Add(queue_model); }
/// <summary> /// 校验索引文件所包含内容是否完整 /// </summary> /// <param name="item"> 由上位函数控制不为空</param> private void CheckFile(baseQueue.QueueItem item) { try { string strIndexPath = item.strIndexFile; //返回文件格式 // string strResJosn = $"{{\"queueno\":\"{222}\",\"lost_count\"{2},\"count\":{5},\"syncstate\":{0},\"synctimes\":{2},\"lostfiles\":\"{23}\"}}"; string lostfiles = "";//丢失文件名称 int lost_count = 0; if (File.Exists(strIndexPath)) { int iCount = 0; string strJosn = File.ReadAllText(strIndexPath, Encoding.UTF8); //采用UTF-8编码解析得到的json数据 JObject jobject = (JObject)JsonConvert.DeserializeObject(strJosn); //得到索引文件中的json格式数据 string strQueue = jobject["queueno"].ToString(); //得到全局唯一的 批次号 if (strIndexPath.Contains("request")) //请求文件索引 { //_readPath string strfiles = jobject["files"].ToString(); //得到文件名 if (!string.IsNullOrWhiteSpace(strfiles) && strfiles.Contains(",")) //不为空 且有多个文件 { iCount = strfiles.Split(',').Length; foreach (string str in strfiles.Split(',')) { // ExecuteSql($"{_readPath}\\{str}"); //遍历执行sql if (!File.Exists($"{_readPath}\\{str}")) //遍历查看当前文件是否存在 { //发现文件不存在 lostfiles += str + ","; lost_count++; } } if (!string.IsNullOrWhiteSpace(lostfiles) && lostfiles.Length > 0) { lostfiles = lostfiles.Substring(0, lostfiles.Length - 1);//去掉字符串最后的逗号 } } else if (!string.IsNullOrWhiteSpace(strfiles)) //不为空 { iCount = 1; // ExecuteSql($"{_readPath}\\{strfiles}"); //遍历执行sql if (!File.Exists($"{_readPath}\\{strfiles}")) //遍历查看当前文件是否存在 { //发现文件不存在 lostfiles = strfiles; lost_count++; } } else //空 { lost_count = 0; iCount = 0; log.Info("no file need to be synced."); } int isyncstate = lost_count == 0 ? 1 : 0; string stritype = "insert"; try { stritype = jobject["itype"].ToString(); } catch { } //给对端写response string strResJosn = $"{{\"queueno\":\"{strQueue}\",\"lost_count\":{lost_count},\"count\":{iCount},\"syncstate\":{isyncstate},\"synctimes\":{item.syncTimes},\"lostfiles\":\"{lostfiles}\",\"itype\":\"{stritype}\"}}"; string strMsg = ""; string strjsonFileName = $"index_response_{strQueue}_{item.syncTimes}.txt"; Task.Run(() => { //另一个进程写文件到本地对应文件夹 // new common.util.FileHelper().WriteFile(strjsonFileName, $"{_writePath}\\", strResJosn, out strMsg); new common.util.FileHelper().WriteFile(strjsonFileName, $"{_ftpUpload}\\", strResJosn, out strMsg); }); if (isyncstate == 0) //同步失败 { //1.更新对应队列的同步次数,同时更新数据对应数据 //2.不做其他处理 等待下次同步执行 } else //同步完成 { //1.从 read 文件夹中找request中对应的文件列表 parsIndexFile(strIndexPath); //解析头文件并执行sql //3.执行完成后更新队列及本端对应的数据库结构 //4. 移出read队列中的 // event_removeInsertList(strQueue);// 已经完成的数据移出 出队列 //event_removeReaadList(strQueue); //标记读取队列为同步完成 event_UpdateSyncStatus(strQueue, 1); //更新改条数据的读取同步状态为1,同步成功 } } else if (strIndexPath.Contains("response")) //响应文件索引 { //因为是监听到的文件所有该索引文件肯定存在 try { //string strResJson = File.ReadAllText(item.strIndexFile, Encoding.UTF8); //JObject jobj_res = (JObject)JsonConvert.DeserializeObject(strResJson); int iSyncstate = Convert.ToInt32(jobject["syncstate"]); //得到同步状态 if (iSyncstate == 1) //同步完成 { //同步完成 删除对应的文件 并标记数据库和队列为完成 try { baseQueue.QueueItem queItem = event_getListByQueNo(strQueue); //得到对应的QueueItem List <string> arrFiles = new List <string>(); foreach (string str in arrFiles) { if (File.Exists(str)) { File.Delete(str); } } if (File.Exists(queItem.strIndexFile)) { File.Delete(queItem.strIndexFile); } File.Delete(strIndexPath);//删除返回索引 index_response_ log.Info($"{strQueue} related files are all deleted ."); //从插入队列中移出 try { event_removeInsertList(strQueue); event_removeReaadList(strQueue); //移除读取队列 } catch (Exception ex) { log.Error("***remove queue.error ." + ex); } // 更新本地mysql数据库,根据批次id 更新表内该记录为同步成功 Task.Run(() => { //更新数据库对应批次数据状态为同步完成 new mySql.BLL.syn_queue().UpdateStateByQueId(strQueue, 1, 0); }); } catch (Exception ex) { log.Error("delete file error", ex); } } else //同步失败 { //根据批次号 queueno从队列或数据库中找到对应的索引信息 并找到丢失的文件 再次上传 //1. 解析返回日志得到丢失文件名称 string strLostfiles = jobject["lostfiles"].ToString();//得到index_response 中失败文件内容 string[] arrLostFiles = { }; if (!string.IsNullOrWhiteSpace(strLostfiles)) { arrLostFiles = strLostfiles.Split(',');//得到用逗号分割的文件名 } //2. 从write文件夹移动文件到ftp上传文件夹 if (arrLostFiles.Length > 0) //存在传输丢失的文件名 { foreach (string str in arrLostFiles) { string waitMoveFile = $"{_writePath}\\{str}"; if (File.Exists(waitMoveFile)) { File.Copy(waitMoveFile, $"{_ftpUpload}\\{str}", true); //移动文件到ftp上传文件夹 } //更新对应的mysql同步次数(暂时不更新,后期完善) } } event_addSyncTimes(strQueue);//更新同步次数 +1 //3. 删除当前返回的index_response_ 文件 (暂时不删除,先存放在当前文件夹内,后期完善) } } catch (Exception ex) { log.Error(ex.Message); } } else //未知索引文件 { //未知文件暂不处理 } } else { log.Error($" index file[{strIndexPath}] is not exist"); } } catch (Exception ex) { log.Error(ex.Message); } }
/// <summary> /// 1:insert 2:update /// </summary> /// <param name="itype">类型 1:insert 2:update</param> /// <param name="_iDirection">数据传输方向</param> private void pushList(int itype, int _iDirection) { try { string[] arrTables = null; if (itype == 1) //insert { if (_iDirection == 1) //1 由内到外 2 由外到内 { arrTables = InTableName_insert; } else { arrTables = OutTableName_insert; } } else //update { if (_iDirection == 1) //1 由内到外 2 由外到内 { arrTables = InTableName_update; } else { arrTables = OutTableName_update; } } baseQueue.QueueItem item = new baseQueue.QueueItem(); strQueueNo = event_getSnowflakeId() + ""; //得到批次号 List <string> _listFilePath = new List <string>(); foreach (string strTableName in arrTables) { string strFilePath = ""; if (itype == 1) //insert 队列 { Task task = Task.Run(() => { WriteInsertSql(strTableName, dic_table_time.ContainsKey(strTableName) ? dic_table_time[strTableName].ToString() : DateTime.Now.AddDays(-iDays).ToString(), out strFilePath); }); task.Wait(); } else //update 队列 { Task task = Task.Run(() => { WriteUpdateSql(strTableName, tb_tm_update.ContainsKey(strTableName) ? tb_tm_update[strTableName].ToString() : DateTime.Now.AddDays(-iDays).ToString(), out strFilePath); }); task.Wait(); } if (!string.IsNullOrWhiteSpace(strFilePath)) { _listFilePath.Add(strFilePath); } } //_listFilePath 为空或者没有内容,即没有需要更新的内容 if (_listFilePath == null || _listFilePath.Count < 1) { log.Info("no data to sync"); } else { item.FileList = _listFilePath; item.dtTime = DateTime.Now; item.excState = 0; item.iDirection = (uint)iDirection; item.msgState = 0; // item.queType = "insert"; item.queueNo = strQueueNo; item.snowflakeId = event_getSnowflakeId() + ""; //得到唯一的雪花算法 item.syncState = 0; item.syncTimes = 1; //同步次数 try { Task.Run(() => { new DataExchange.mySql.OperData2DB().QueueInfo2DB(item); //异步插入队列数据到mysql数据库,数据持久化 }); //得到列表中的所有文件名 string strFiles = "";//文件名 int iLength = 0; foreach (string str in _listFilePath) { iLength++; strFiles += str.Substring(str.LastIndexOf('\\') + 1) + ","; //得到文件名 } if (strFiles.Length > 0) { strFiles = strFiles.Substring(0, strFiles.Length - 1); } string strType = itype == 1 ? "insert" : "update"; //本地写入一个汇总json string strJosn = $"{{\"queueno\":\"{strQueueNo}\",\"itype\":\"{strType}\",\"synctimes\":1,\"count\":{iLength},\"files\":\"{strFiles}\"}}"; string strjsonFileName = $"index_request_{strQueueNo}_1.txt"; //请求文件 string strMsg = ""; new common.util.FileHelper().WriteFile(strjsonFileName, $"{writePath}\\", strJosn, out strMsg); log.Info($"successfully write json data to a local file,the json file name is {strjsonFileName}"); item.queType = strType; item.strIndexFile = $"{writePath}\\{strjsonFileName}"; event_addQueueInsert(strQueueNo, item);//插入队列 log.Info($"insert queue[{strQueueNo}] to the insertqueue"); //把当前文件夹内的文件转存到ftp上传同步文件夹 //try //{ // File.Move($"{writePath}\\sqlInsert\\{strjsonFileName}", $"{ftpUpload}\\{strjsonFileName}"); // log.Info($"move file[{strjsonFileName}] success"); //} //catch (Exception ex) //{ // log.Error(ex.Message); //} File.Copy(item.strIndexFile, $"{ftpUpload}\\{strjsonFileName}", true);//移动文件到上传文件夹 } catch (Exception ex) { log.Error(ex.Message); } } // Thread.Sleep(interval * 1000); } catch (Exception ex) { log.Error(ex.Message); // Thread.Sleep(20 * 1000); //continue; } }