4

运行太多使用本地测试数据库的 JUnit 测试时,我遇到了 MongoDb 的问题。当我一个接一个地运行所有测试时,一切都很好,每个测试都通过了。但是当我尝试“运行所有测试”时,在第 80 次测试之后的某个地方,我失去了与 Mongo 的连接,并且所有下一个测试都失败了。这很奇怪,因为据我了解并看到“运行所有测试”只是让所有测试连续运行。

我将我的数据库放在每个测试的@After 中,所以我认为也许为每个测试创建自己的唯一数据库可能会解决问题(在我使用单个数据库之前)。但它没有。经过 80 多次测试后,我仍然失去了连接(每次都不同)。

也许驱动程序在某个时刻没有足够的时间从 Mongo 获得响应并导致失败?

我使用 2.11.3 Mongo Java 驱动程序。需要帮忙。谢谢你。

这是错误堆栈:

Sep 13, 2013 5:32:07 PM com.mongodb.DBTCPConnector initDirectConnection
WARNING: Exception executing isMaster command on /127.0.0.1:27017
java.io.EOFException
     at org.bson.io.Bits.readFully(Bits.java:48)
     at org.bson.io.Bits.readFully(Bits.java:33)
     at org.bson.io.Bits.readFully(Bits.java:28)
     at com.mongodb.Response.<init>(Response.java:40)
     at com.mongodb.DBPort.go(DBPort.java:142)
     at com.mongodb.DBPort.go(DBPort.java:106)
     at com.mongodb.DBPort.findOne(DBPort.java:162)
     at com.mongodb.DBPort.runCommand(DBPort.java:170)
     at com.mongodb.DBTCPConnector.initDirectConnection(DBTCPConnector.java:547)
     at com.mongodb.DBTCPConnector.isMongosConnection(DBTCPConnector.java:334)
     at com.mongodb.Mongo.isMongosConnection(Mongo.java:618)
     at com.mongodb.DB.wrapCommand(DB.java:282)
     at com.mongodb.DB.command(DB.java:260)
     at com.mongodb.DB.command(DB.java:244)
     at com.mongodb.DB.command(DB.java:301)
     at com.mongodb.DB.command(DB.java:199)
     at com.mongodb.DB.dropDatabase(DB.java:557)
     at com.*******.dbconnection.mongodb.BaseMongodbTest.tearDown(BaseMongodbTest.java:102)
     at com.*******.rpcserver.methods.BaseTestClient.tearDown(BaseTestClient.java:57)
     at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at java.lang.reflect.Method.invoke(Method.java:601)
     at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
     at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
     at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
     at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:36)
     at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
     at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
     at org.junit.runners.Suite.runChild(Suite.java:128)
     at org.junit.runners.Suite.runChild(Suite.java:24)
     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
     at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
     at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
     at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77)
     at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
     at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at java.lang.reflect.Method.invoke(Method.java:601)
     at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)




com.mongodb.MongoException$Network: Read operation to server /127.0.0.1:27017 failed on database test_mydb_fb19fd07-6e4f-4
     at com.mongodb.DBTCPConnector.innerCall(DBTCPConnector.java:253)
     at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:216)
     at com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:288)
     at com.mongodb.DB.command(DB.java:262)
     at com.mongodb.DB.command(DB.java:244)
     at com.mongodb.DB.command(DB.java:301)
     at com.mongodb.DB.command(DB.java:199)
     at com.mongodb.DB.dropDatabase(DB.java:557)
     at com.*******.dbconnection.mongodb.BaseMongodbTest.tearDown(BaseMongodbTest.java:102)
     at com.*******.rpcserver.methods.BaseTestClient.tearDown(BaseTestClient.java:57)
     at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
     at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
     at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
     at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:36)
     at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
     at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
     at org.junit.runners.Suite.runChild(Suite.java:128)
     at org.junit.runners.Suite.runChild(Suite.java:24)
     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
     at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
     at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
     at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77)
     at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
     at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
     at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.io.EOFException
     at org.bson.io.Bits.readFully(Bits.java:48)
     at org.bson.io.Bits.readFully(Bits.java:33)
     at org.bson.io.Bits.readFully(Bits.java:28)
     at com.mongodb.Response.<init>(Response.java:40)
     at com.mongodb.DBPort.go(DBPort.java:142)
     at com.mongodb.DBPort.call(DBPort.java:92)
     at com.mongodb.DBTCPConnector.innerCall(DBTCPConnector.java:244)
     ... 42 more 
4

1 回答 1

2

看来我发现问题出在哪里了。我们的测试客户端有一个愚蠢的错误:为每个测试用例创建了新的 Mongo 对象!命令

db.serverStatus().connections

向我们展示了可用连接的数量约为 200,但每个新的 Mongo 实例都会创建新的 10 个(默认情况下)连接。所以我只是超出了日志中显示的限制(例如,您可以通过执行mongo --eval="printjson(db.adminCommand({getLog:'global'}))"来读取它们)

解决方案是创建工厂类,它保留在每个测试用例中使用的 Mongo 对象的单个实例(我也在此处初始化 DB 和 MongoClient 实例,如果您也需要它们,建议您也这样做)。

我强烈推荐阅读这个主题,它解决了一个类似的问题(对我帮助很大!): Mongo opens too many connections

感谢@RobMoore 和@interlude 的及时回复和帮助!

于 2013-09-16T12:23:44.257 回答