Java Mongodb连接失败。

4
我有一个Java应用程序,它使用大约3000个可重用的线程,一直在运行并从队列中处理项目。我使用MongoDB作为我的数据存储,每次运行它时,它都可以完美地工作约40分钟左右,之后MongoDB对象开始返回查询的Nullpointer异常。起初我怀疑可能是由于连接丢失,但正如您在Google监控图中看到的那样,连接仍然处于打开状态,但Mongo查询数量显着减少。这里是否有我遗漏的任何事项?
我MongoDB类像这样:
public class MongoDB {

    private static MongoClient mongoClient; 

    private static MongoClient initMongoClient() {
        ServerAddress server = new ServerAddress("X.X.X.X");

        MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
        builder.threadsAllowedToBlockForConnectionMultiplier(50000);
        builder.socketKeepAlive(true);
        builder.connectionsPerHost(10000);
        builder.minConnectionsPerHost(2500);


        MongoClientOptions options = builder.build();
        MongoClient mc = new MongoClient(server, options);
        mongoClient = mc;
        return mc;
    }

    public static MongoClient getMongoClient() {
        if(mongoClient == null) {
            mongoClient = initMongoClient();
        }

        return mongoClient;
    }

    public static DB getDb() {
        DB db;
        MongoClient mc;
        try {
            mc = getMongoClient();
            mc.getDatabaseNames();
        } catch(MongoException e) {
            mc = initMongoClient();
        }
        db = mc.getDB("tina");
        return db;
    }

}

enter image description here


2
我无法理解你在这里想要问什么。 - Janny
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Rene M.
我认为你混淆了“获取连接”和“获取集合”的概念。你的单例创建了一个保持连接的单一连接,所以我不理解你的断言,“过一段时间后...无法连接到MongoDB”。 - Buzz Moschetti
1个回答

2
你应该转用Morphia!请使用工厂模式生成单个Mongo实例并将其绑定到Morphia Datastore对象。然后,您可以使用Datastore对象与MongoDB进行交互。参见: https://github.com/mongodb/morphia
public class DatastoreFactory {
    private static Datastore ds;

    public static Datastore getDatastore() {
        //Lazy load the datastore
        if(ds == null) {
            try {
                Morphia morphia = new Morphia();
                ds = morphia.createDatastore(
                    new MongoClient("server", port, "database"));
                //... Other datastore options
            } catch(Exception e) {
               // Handle it
            }
    }
    return ds;
}

然后无论您在何处需要您的MongoDB实例,您只需使用Datastore对象,并从工厂获取它即可。

Datastore ds = DatastoreFactory.getDatastore();

你也可以使用CDI来注入数据存储,如果你喜欢的话。
@Singleton
public class DatastoreFactory {
    private Datastore ds;

    @Produces
    public Datastore getDatastore() {
        //Lazy load the datastore
        if(ds == null) {
            try {
                Morphia morphia = new Morphia();
                ds = morphia.createDatastore(
                    new MongoClient("server", port, "database"));
                //... Other datastore options
            } catch(Exception e) {
               // Handle it
            }
    }
    return ds;
}

然后像这样注入它

@Inject
Datastore ds;

奖励

为了更好地将代码与MongoDB解耦,创建数据访问对象(DAO)以访问包含Morphia Datastore对象的数据库是适当的设计。您的DAO将具有您希望在数据库上使用的方法(获取,创建,保存,删除)。这样,如果您决定远离MongoDB,您只需要更改DAO对象而不是所有代码!


谢谢,但是我的问题不是关于将文档映射到数据。 - Pooya Saberian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接