问题
I feel quite uncomfortable with the MongoClient class, certainly because I don't exactly understand what it is and how it works.
The first call to
MongoClient.createSharedwill actually create the pool, and the specified config will be used.Subsequent calls will return a new client instance that uses the same pool, so the configuration won’t be used.
Does that mean that the pattern should be:
In startup function, to create the pool, we make a call
mc = MongoClient.createShared(vx, config, "poolname");Is the returned value
mcimportant for this first call if it succeeds? What is its value if the creation of the pool fails? The documentations doesn't say. There is a socket exception ifmongodis not running, but what about the other cases?In another place in the code (another verticle, for example), can we write
mc = MongoClient.createShared(vx, new JsonObject(), "poolname");to avoid to systematically need to access shared objects.Again, In another verticle where we need to access the database, should we define
MongoClient mc- as a class field in which case it will be released to the pool only in the
stop()method, or - shouldn't it be a variable populated with
MongoClient.createShared(...)and de-allocated withmc.close()once we don't need the connection any more in order release it again to the pool ?
- as a class field in which case it will be released to the pool only in the
What I would write is as follows
// Main startup Verticle
import ...
public class MainVerticle extends AbstractVerticle {
...
@Override
public void start(Future<Void> sf) throws Exception {
...
try {
MongoClient.createShared(vx, config().getJsonObject("mgcnf"), "pool");
}
catch(Exception e) {
log.error("error error...");
sf.fail("failure reason");
return;
}
...
sf.complete();
}
...some other methods
}
and then, in some other place
public class SomeVerticle extends AbstractVerticle {
public void someMethod(...) {
...
// use the database:
MongoClient mc = MongoClient.createShared(vx, new JsonObject(), "pool");
mc.save(the_coll, the_doc, res -> {
mc.close();
if(res.succeeded()) {
...
}
else {
...
}
}
...
}
...
}
Does that make sense ? Yet, this is not what is in the examples that I could find around the internet.
回答1:
Don't worry about pools. Don't use them. They don't do what you think they do.
In your start method of any verticle, set a field (what you call a class field, but you really mean instance field) on the inheritor of AbstractVerticle to MongoClient.createShared(getVertx(), config). Close the client in your stop method. That's it.
The other exceptions you'll see are:
- Bad username/password
- Unhealthy cluster state
- The Java driver has a limit of 500 or 1,000 connections (depending on version), you'll receive an exception if you exceed this connection count
Both will be propagated up from the driver wrapped in a VertxException.
来源:https://stackoverflow.com/questions/53286404/pattern-for-using-properly-mongoclient-in-vert-x