草庐IT

java - Mongo Connection 在 RESTful API 中创建多次且从未发布

coder 2023-11-05 原文

我使用 Apache Jersey 编写了一个 RESTful API。我使用 MongoDB 作为我的后端。我使用 Morphia (v.1.3.4) 将 POJO 映射并保存到数据库。我尝试按照到处推荐的方式在我的 API 中遵循“1 个应用程序 1 个连接”,但我不确定我是否成功。我在 Tomcat 8 中运行我的 API。我还运行了 Mongostat 来查看详细信息和连接。 一开始,Mongostat 显示了 1 个到 MongoDB 服务器的连接。我使用 Postman 测试了我的 API,它工作正常。然后,我在 SoapUI 中创建了一个负载测试,我每秒模拟 100 个用户。我在 Mongostat 中看到了更新。 我看到有 103 个连接。这是显示此行为的 gif。

我不确定为什么会有这么多连接。有趣的是,mongo 连接数与我在 SoapUI 上创建的用户数成正比。这是为什么?我发现了其他类似的问题,但我想我已经实现了那里的建议。

Mongo connection leak with morphia

Spring data mongodb not closing mongodb connections

我的代码如下所示。

DatabaseConnection.java

// Some imports
public class DatabaseConnection {

    private static volatile MongoClient instance;
    private static String cloudhost="localhost";

    private DatabaseConnection() { }

    public synchronized static MongoClient getMongoClient() {
        if (instance == null ) {
            synchronized (DatabaseConnection.class) {
                if (instance == null) {
                    ServerAddress addr = new ServerAddress(cloudhost, 27017);
                    List<MongoCredential> credentialsList = new ArrayList<MongoCredential>();
                    MongoCredential credentia = MongoCredential.createCredential(
                        "test", "test", "test".toCharArray());
                    credentialsList.add(credentia);
                    instance = new MongoClient(addr, credentialsList); 

                }
            }
        }
        return instance;
    }
}

PourService.java

@Secured
@Path("pours")
public class PourService {

final static Logger logger = Logger.getLogger(Pour.class);
private static final int POUR_SIZE = 30;

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response createPour(String request)
    {
        WebApiResponse response = new WebApiResponse();
        Gson gson = new GsonBuilder().setDateFormat("dd/MM/yyyy HH:mm:ss").create();
        String message = "Pour was not created.";
        HashMap<String, Object> data = null;
        try
        {
            Pour pour = gson.fromJson(request, Pour.class);

            // Storing the pour to 
            PourRepository pourRepository = new PourRepository();           
            String id = pourRepository.createPour(pour);

            data = new HashMap<String, Object>();
            if ("" != id && null != id)
            {
                data.put("id", id);
                message = "Pour was created successfully.";
                logger.debug(message);
                return response.build(true, message, data, 200);
            }

            logger.debug(message);
            return response.build(false, message, data, 500);
        }
        catch (Exception e)
        {
            message = "Error while creating Pour.";
            logger.error(message, e);
            return response.build(false, message, new Object(),500);
        }
    }

PourDao.java

public class PourDao extends BasicDAO<Pour, String>{

    public PourDao(Class<Pour> entityClass, Datastore ds) {
        super(entityClass, ds);
    }
}

PourRepository.java

public class PourRepository {

    private PourDao pourDao;

    final static Logger logger = Logger.getLogger(PourRepository.class);

    public PourRepository ()
    {
        try 
        {
            MongoClient mongoClient = DatabaseConnection.getMongoClient();
            Datastore ds = new Morphia().map(Pour.class)
                    .createDatastore(mongoClient, "tilt45");
            pourDao = new PourDao(Pour.class,ds);
        } 
        catch (Exception e) 
        {
            logger.error("Error while creating PourDao", e);
        }
    }

    public String createPour (Pour pour)
    {
        try
        {
            return pourDao.save(pour).getId().toString();
        }
        catch (Exception e)
        {
            logger.error("Error while creating Pour.", e);
            return null;
        }
    } 
 }

最佳答案

当我使用 Mongo+Morphia 时,我使用数据存储的工厂模式获得了更好的结果,而不是 MongoClient,例如,检查以下类:

public DatastoreFactory(String dbHost, int dbPort, String dbName) {
    final Morphia morphia = new Morphia();
    MongoClientOptions.Builder options = MongoClientOptions.builder().socketKeepAlive(true);
    morphia.getMapper().getOptions().setStoreEmpties(true);
    final Datastore store = morphia.createDatastore(new MongoClient(new ServerAddress(dbHost, dbPort), options.build()), dbName);
    store.ensureIndexes();
    this.datastore = store;
}

通过这种方法,每次您需要数据存储时,您都可以使用工厂提供的数据存储。当然,如果您使用支持工厂模式的框架/库(例如:HK2 with org.glassfish.hk2.api.Factory)和单例绑定(bind),这可以更好地实现。

此外,你可以查看MongoClientOptions的builder方法的文档,也许你可以在那里找到更好的连接控制。

关于java - Mongo Connection 在 RESTful API 中创建多次且从未发布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44901376/

有关java - Mongo Connection 在 RESTful API 中创建多次且从未发布的更多相关文章

  1. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  2. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  3. ruby-on-rails - Rails - 从另一个模型中创建一个模型的实例 - 2

    我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案

  4. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  5. ruby - 如何在 Ruby 中创建无类 DSL? - 2

    我正在尝试找出如何为我的Ruby项目创建一种“无类DSL”,类似于在Cucumber步骤定义文件中定义步骤定义或在Sinatra应用程序中定义路由。例如,我想要一个文件,其中调用了我的所有DSL函数:#sample.rbwhen_string_matches/hello(.+)/do|name|call_another_method(name)end我认为用我的项目特有的一堆方法污染全局(内核)命名空间是一种不好的做法。因此方法when_string_matches和call_another_method将在我的库中定义,并且sample.rb文件将以某种方式在我的DSL方法的上下文中

  6. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  7. ruby-on-rails - 如何在 Rails 3 中创建自定义脚手架生成器? - 2

    有这些railscast。http://railscasts.com/episodes/218-making-generators-in-rails-3有了这个,你就会知道如何创建样式表和脚手架生成器。http://railscasts.com/episodes/216-generators-in-rails-3通过这个,您可以了解如何添加一些文件来修改脚手架View。我想把两者结合起来。我想创建一个生成器,它也可以创建脚手架View。有点像RyanBates漂亮的生成器或web_app_themegem(https://github.com/pilu/web-app-theme)。我

  8. ruby - 为什么在 ruby​​ 中创建 Rational 不需要新方法 - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Rubysyntaxquestion:Rational(a,b)andRational.new!(a,b)我正在阅读ruby镐书,我对创建有理数的语法感到困惑。Rational(3,4)*Rational(1,2)产生=>3/8为什么Rational不需要new方法(我还注意到例如我可以在没有new方法的情况下创建字符串)?

  9. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  10. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

随机推荐