2013-03-14 42 views
0

我正在使用Eclipse中的Java項目。我有一個登臺服務器和一臺現場服務器。這兩個也有自己的mongodbs,它們在兩個不同端口(29017和27017)上的不同服務器上運行。 通過Junit測試我想從實時mongo複製數據到devel mongo。由於套接字異常,mongodb插入失敗

最奇怪的事情:它有時會起作用,有時候我會遇到套接字錯誤。我想知道爲什麼mongo有時完全拒絕寫入插入,並在其他日子,它完美地工作。這裏是蒙戈日誌文件的摘錄(就是代碼被插入)和JUnit測試腳本:

蒙戈日誌:

Thu Mar 14 21:01:04 [initandlisten] connection accepted from xx.xxx.xxx.183:60848 #1 (1 connection now open) 
Thu Mar 14 21:01:04 [conn1] run command admin.$cmd { isMaster: 1 } 
Thu Mar 14 21:01:04 [conn1] command admin.$cmd command: { isMaster: 1 } ntoreturn:1 keyUpdates:0 reslen:90 0ms 
Thu Mar 14 21:01:04 [conn1] opening db: repgain 
Thu Mar 14 21:01:04 [conn1] query repgain.editorconfigs query: { $and: [ { customer: "nokia" }, { category: "restaurant" } ] } ntoreturn:0 keyUpdates:0 locks(micros) W:5302 r:176 nreturned:0 reslen:20 0ms 
Thu Mar 14 21:01:04 [conn1] Socket recv() errno:104 Connection reset by peer xx.xxx.xxx.183:60848 
Thu Mar 14 21:01:04 [conn1] SocketException: remote: xx.xxx.xxx.183:60848 error: 9001 socket exception [1] server [xx.xxx.xxx.183:60848] 
Thu Mar 14 21:01:04 [conn1] end connection xx.xxx.xxx.183:60848 (0 connections now open) 

JUnit測試腳本:

public class CopyEditorConfig { 

protected final Log logger = LogFactory.getLog(getClass()); 

private static final String CUSTOMER = "customerx"; 
private static final String CATEGORY = "categoryx"; 

@Test 
public void test() { 
    try { 

     ObjectMapper om = new ObjectMapper(); 

     // script copies the config from m2 to m1. 

     Mongo m1 = new Mongo("xxx.xxx.com", 29017); // devel 
     Mongo m2 = new Mongo("yyy.yyy.com", 27017); // live 
     Assert.assertNotNull(m1); 
     Assert.assertNotNull(m2); 

     logger.info("try to connect to db \"dbname\""); 

     DB db2 = m2.getDB("dbname"); 

     logger.info("get collection \"config\""); 
     DBCollection c2 = db2.getCollection("config"); 
     JacksonDBCollection<EditorTabConfig, ObjectId> ec2 = JacksonDBCollection.wrap(c2, EditorTabConfig.class, ObjectId.class); 

     logger.info("find entry with customer {" + CUSTOMER + "} and category {" + CATEGORY + "}"); 
     EditorTabConfig config2 = ec2.findOne(DBQuery.and(DBQuery.is("customer", CUSTOMER), DBQuery.is("category", CATEGORY))); 

     // config 
     if (config2 == null) { 
      logger.info("no customer found to copy."); 
     } else { 
      logger.info("Found config with id: {" + config2.objectId + "}"); 
      config2.objectId = null; 
      logger.info("copy config"); 
      boolean found = false; 

      DB db1 = m1.getDB("dbname"); 

      DBCollection c1 = db1.getCollection("config"); 
      JacksonDBCollection<EditorTabConfig, ObjectId> ec1 = JacksonDBCollection.wrap(c1, EditorTabConfig.class, ObjectId.class); 

      EditorTabConfig config1 = ec1.findOne(DBQuery.and(DBQuery.is("customer", CUSTOMER), DBQuery.is("category", CATEGORY))); 

      if (config1 != null) { 
       found = true; 
      } 

      if (found == false) { 
       WriteResult<EditorTabConfig, ObjectId> result = ec1.insert(config2); 
       ObjectId id = result.getSavedId(); 
       logger.info("INSERT config with id: " + id); 
      } else { 
       logger.info("UPDATE config with id: " + config1.objectId); 
       ec1.updateById(config1.objectId, config2); 
      } 

      StringWriter sw = new StringWriter(); 
      om.writeValue(sw, config2); 
      logger.info(sw); 
     } 

    } catch (Exception e) { 
     logger.error("exception occured: ", e); 
    } 
} 
} 

運行此當我在eclipse中讀取日誌時,腳本似乎很成功。 c1c2我都得到了id,數據也在這裏。日誌甚至說,它沒有在devel上找到配置並插入它。如果我手動將它放在那裏,情況也是如此。它會被「更新」。但是mongo日誌保持不變。 發生套接字異常,數據永遠不會寫入數據庫。

我很好的想法來調試這個。如果可以的話,我會很高興得到一些提示如何從這裏開始。另外,如果缺少任何信息,請告訴我,我很樂意分享。

問候, 亞歷

+1

你好atrioom,有些用戶面臨類似的問題,請檢查這張票:https://jira.mongodb.org/browse/JAVA-499,它正在進行,但有一個解決方法提到那裏。我希望我能幫助你。 – 2013-04-28 04:09:45

回答

1

看來你有蒙戈服務器的連接問題。下面的方法可以幫助你更好地診斷蒙戈服務器:

  1. 嘗試從日誌文件的詳細信息:

    $少/var/log/mongo/mongod.log

    或在mongod.conf定義自定義日誌文件

  2. 嘗試使用mongostat監控服務器狀態:

    $ mongostat -u ADMIN_USER -p ADMIN_PASS

  3. 嘗試使用蒙戈CLI來檢查服務器狀態乳寧:

    $ mongo admin -u ADMIN_USER -p ADMIN_PASS 
    $ db.serverStatus() 
    

    更多有用的命令是:http://docs.mongodb.org/manual/reference/method/

有時可能會遇到Linux系統配置。嘗試調整Linux以獲得更多連接和限制,這可能會有所幫助。 要檢查當前的Linux限制,運行:

$ ulimit -a

下面的建議可能會有所幫助:

每個連接都是用的Linux看作是一個打開的文件。打開文件默認的最大數量爲1024爲了增加此限制:

  1. 修改在/etc/security/limits.conf

    root soft nofile  500000 
    root hard nofile  512000 
    root soft nproc  500000 
    root hard nproc  512000 
    
  2. 修改的/etc/sysctl.conf

    fs.file-max=360000 
    net.ipv4.ip_local_port_range=1024 65000 
    
+0

除了底部的兩條建議之外,這些信息並沒有真正幫助解決已經發生的問題。 – brimble2010 2013-09-17 14:14:17

2

評論在你的mongod.conf中將IP綁定到127.0.0.1。 默認情況下,它通常設置爲127.0.0.1。 對於Linux,這個配置文件的位置應該是/etc/mongod.conf。一旦你發表評論,它將接收來自所有接口的連接。這對我來說是固定的,因爲我也收到了這些套接字異常。