运行太多测试时失去与 mongoDB 的连接
Posted
技术标签:
【中文标题】运行太多测试时失去与 mongoDB 的连接【英文标题】:Losing connection to mongoDB when running too many tests 【发布时间】:2013-09-13 14:09:20 【问题描述】:在运行太多使用本地测试数据库的 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
【问题讨论】:
你是失去连接还是失去连接? @interlude,对不起 :) 当然输了。 ty 进行更正。 你能从 MongoDB 服务器发布涵盖故障期间的日志吗?它是独立的吗?分片?副本集?该异常看起来像是服务器突然断开了连接(例如,服务器崩溃了)。 【参考方案1】:看来我发现问题出在哪里了。 我们的测试客户端有一个愚蠢的错误:为每个测试用例创建了新的 Mongo 对象! 命令
db.serverStatus().connections
向我们展示了可用连接数约为 200,但每个新的 Mongo 实例都会创建新的 10 个(默认情况下)连接。所以我只是超出了日志中显示的限制(例如,您可以通过执行 mongo --eval="printjson(db.adminCommand(getLog:'global'))")
解决方案是创建工厂类,它保留在每个测试用例中使用的 Mongo 对象的单个实例(我也在此处初始化 DB 和 MongoClient 实例,如果您也需要它们,建议您也这样做)。
我强烈推荐阅读这个主题,它解决了一个类似的问题(并且帮助了我很多!): Mongo opens too many connections
感谢@RobMoore 和@interlude 的及时回复和提供帮助的意愿!
【讨论】:
以上是关于运行太多测试时失去与 mongoDB 的连接的主要内容,如果未能解决你的问题,请参考以下文章