2016-08-18 97 views
2

我試圖將所有數據從ServiceNow CMDB數據表中抽取到我自己的SQL數據庫中。我計劃在數據在需要與新SN實現同步的客戶遺留系統中進行維護時將其用於自動更新。ServiceNow Table API返回重複/不返回所有記錄

我們的SN環境有很多領域,很多客戶等等,這些轉化爲大量的數據。試圖在單個API調用中拉取所有記錄自然會導致超時異常,因爲數據太大。在Web API建議分批的數據,這是我已經實現:

 ... 
     var offset = 0; 

     while (true) 
     { 
      var requestUrl = string.Format("{0}/api/now/table/cmdb_ci_vm_instance?sysparm_offset={1}&sysparm_limit={2}&sysparm_exclude_reference_link=true", url, offset, batchSize); 
      var result = ApiRequest.Get(new Uri(requestUrl), _credential, null, out response); 
      if (result == HttpStatusCode.OK) 
      { 
       var virtualmachineRo = JsonConvert.DeserializeObject<VirtualMachineRootObject>(response); 

       if (virtualmachineRo.result.Count < batchSize) 
       { 
        virtualmachines.AddRange(virtualmachineRo.result); 
        break; 
       } 

       virtualmachines.AddRange(virtualmachineRo.result); 
       offset += virtualmachineRo.result.Count; 
      } 
      else 
      { 
       break; 
      } 
     } 
     .... 

我有不同的批量工作,它給了我不同的結果。根據我打的是哪張桌子,有時候我會得到重複的東西,有時我不會,有時會得到不同的重複。在幾乎所有情況下,當我DO得到一個副本時,副本會替換流中的有效記錄,這意味着我'缺少'有效記錄。

我已經通過查看來自serviceNow的原始數據流並查看重複內容並驗證ServiceNow中沒有顯示在我的流中的記錄(通常在我嘗​​試創建丟失的記錄和SN響應與「忽略 - 沒有領域變化」,表明該記錄已經存在)

我試圖搜索並找到任何有類似問題但沒有找到任何東西的人。在直接打開SN的票之前,我希望看看是否有一些錯誤的代碼,或者我認爲這是一個與平臺相關的bug。

回答

2

因此,這是幾乎可以肯定他們的API相關的服務帳戶訪問中的錯誤。 (!和我的工作圍繞)這是我做了什麼,什麼我認爲是存在的

一些不同的邏輯玩耍後,我遇到了以下:在第二次

{0}/api/now/table/cmdb_ci_vm_instance?sysparm_offset=0&sysparm_limit=750&sysparm_exclude_reference_link=true&sysparm_query=ORDERBYsys_id 
2016-08-19 12:46:15,277 [INFO ] Returned Records Count: 750 

{0}/api/now/table/cmdb_ci_vm_instance?sysparm_offset=750&sysparm_limit=750&sysparm_exclude_reference_link=true&sysparm_query=ORDERBYsys_id 
2016-08-19 12:46:28,243 [INFO ] Returned Records Count: 746 

公告我詢問了750條記錄,但只得到了746條(相差4條)。其他批次繼續按照正常情況返回750條,最終在5200條記錄中找到了4條重複記錄。因爲第二次傳回的數據少於我要求的750,我的代碼因爲認爲數據已完成而破了...

爲了解決這個問題(最初)我對以上代碼做了如下處理:

if (virtualmachineRo.result.Count == 0) 
{ 
    //AddRange(virtualmachineRo.result); 
    break; 
} 

我不再信任,僅僅因爲返回記錄的數量明顯少於我已經檢索到的所有記錄的sysparm_limit。

它看起來像從數據庫中提取數據時,單獨的進程根據您的權限過濾數據。因此,第二批刪除4條記錄 - 但數據庫不知道更好...所以在下一個階段,當我通過從746調用返回的實際計數增加我的偏移量時,它將返回相同的數據集,批次的最後4個記錄將被複製爲下一頁數據中的前4條記錄。 (在數據流中確認 - 在訂購數據時,會導致重複出現在不同的地方,並根據批量大小/順序重複不同的記錄!)

我不敢相信這是預期的行爲並且它在Wiki中肯定沒有記錄。無論採用哪種方法,解決此問題的解決方法都很簡單:即使返回的計數小於批處理大小,您也必須繼續提取數據,並繼續返回0條記錄。然後你必須用一些簡單的東西來過濾掉重複的東西:

yourrecords.GroupBy(x => x.sys_id).Select(x => x.First()).ToList(); 

問題就解決了。

0

您可以嘗試在主鍵(sys_id)上添加顯式排序以確保每個批處理查詢。您可以通過添加URL參數sysparm_query=ORDERBYsys_id

你的URL看起來像這樣: "{0}/api/now/table/cmdb_ci_vm_instance?sysparm_offset={1}&sysparm_limit={2}&sysparm_exclude_reference_link=true&sysparm_query=ORDERBYsys_id"

+0

這聽起來像一個很好的解決方法 - 我現在要試一試。會回到你身邊。 (這也符合我的假設 - 他們沒有在批量購買前在SN端訂購數據。) –

+0

不幸的是,這並沒有奏效 - 更奇怪的是,如果我不批量並試圖拖動整個數據集(這太大),它會超時......但會返回一個包含2000-4000條記錄的部分數據集。每次都不一樣。我希望HTTP代碼是408或類似的東西,但是我得到一個部分數據集,其中嵌入了一個錯誤,但仍然是一個HTTP 200.非常令人沮喪= / –