非常慢的Spring Boot应用程序,使用Mongodb。

huangapple go评论78阅读模式
英文:

Very slow Spring Boot application with Mongodb

问题

以下是翻译好的内容:

我有一个基本的独立的 Spring Boot 应用程序,使用了 MongoDB。然而,从数据库中检索数据时非常慢。例如,从一个产品集合中检索五个文档(全部文档)需要 2.5 秒,如下所示(实体类),不包含 getter 和 setter 方法。

@Document(collection = "products")
public class Product {
	private double itemPrice;
	private int quantity;
	@Indexed(unique = true)
	private String name;
	@Id
	private String productId;
	@DBRef
	private Set<ProductTransaction> productTransactions;
}

以下是存储库类:

@Repository
public interface ProductRepository extends MongoRepository<Product, String> {

}

以下是服务类:

@Service
public class ProductServiceImpl implements ProductService {
    @Autowired
    ProductRepository productRepository;

    public List<Product> getProducts() {
        startTime = System.currentTimeMillis();
        Iterable<Product> products = productRepository.findAll();
        endTime = System.currentTimeMillis();
        System.out.println("查找所有产品:" + (endTime - startTime));
        return products;
    }
}

应用程序配置文件 application.properties

spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=productDB

spring.data.mongodb.auto-index-creation=false

以下是 pom.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.spring.mongodb.ims</groupId>
    <artifactId>ims-desktop-application</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ims-desktop-application</name>
    <description>This is an app for managing sales and inventories</description>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <!-- 其他依赖... -->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

请注意,在 MongoDB Shell 中执行相同的查询非常快:

db.products.find()

我一定会感激任何帮助,以解开 Spring Boot 应用程序中查询缓慢的原因。

英文:

I have a basic standalone Spring Boot application with MongoDB. However, it is very slow while retrieving data from the database. For example, it takes 2.5 seconds to retrieve five documents (all) from a collection of products, as shown below (entity class), without getters and setters.

@Document(collection = &quot;products&quot;)
public class Product {
	private double itemPrice;
	private int quantity;
	@Indexed(unique = true)
	private String name;
	@Id
	private String productId;
	@DBRef
	private Set&lt;ProductTransaction&gt; productTransactions;
}

The repository class is shown below:

@Repository
public interface ProductRepository extends MongoRepository&lt;Product, String&gt; {

}

The service class is shown below:

@Service
public class ProductServiceImpl implements ProductService{
   @Autowired
   ProductRepository productRepository;

   public List&lt;Product&gt; getProducts() {
      startTime = System.currentTimeMillis();
	  Iterable&lt;Product&gt; products = productRepository.findAll();
	  endTime = System.currentTimeMillis();
	  System.out.println(&quot;Find all products: &quot; + (endTime - startTime));
      return products;
   }
}

The application.properties file:

spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=productDB

spring.data.mongodb.auto-index-creation=false

The pom.xml is shown below:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
	&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
	&lt;parent&gt;
		&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
		&lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
		&lt;version&gt;2.3.3.RELEASE&lt;/version&gt;
		&lt;relativePath /&gt; &lt;!-- lookup parent from repository --&gt;
	&lt;/parent&gt;
	&lt;groupId&gt;com.spring.mongodb.ims&lt;/groupId&gt;
	&lt;artifactId&gt;ims-desktop-application&lt;/artifactId&gt;
	&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
	&lt;name&gt;ims-desktop-application&lt;/name&gt;
	&lt;description&gt;This is an app for managing sales and inventories&lt;/description&gt;

	&lt;properties&gt;
		&lt;java.version&gt;11&lt;/java.version&gt;
	&lt;/properties&gt;

	&lt;dependencies&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
			&lt;artifactId&gt;spring-boot-starter-data-mongodb&lt;/artifactId&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.modelmapper&lt;/groupId&gt;
			&lt;artifactId&gt;modelmapper&lt;/artifactId&gt;
			&lt;version&gt;2.3.0&lt;/version&gt;
		&lt;/dependency&gt;

		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
			&lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
			&lt;scope&gt;test&lt;/scope&gt;
			&lt;exclusions&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;org.junit.vintage&lt;/groupId&gt;
					&lt;artifactId&gt;junit-vintage-engine&lt;/artifactId&gt;
				&lt;/exclusion&gt;
			&lt;/exclusions&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;io.projectreactor&lt;/groupId&gt;
			&lt;artifactId&gt;reactor-test&lt;/artifactId&gt;
			&lt;scope&gt;test&lt;/scope&gt;
		&lt;/dependency&gt;
	&lt;/dependencies&gt;

	&lt;build&gt;
		&lt;plugins&gt;
			&lt;plugin&gt;
				&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
				&lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
			&lt;/plugin&gt;
		&lt;/plugins&gt;
	&lt;/build&gt;

&lt;/project&gt;

Please note that the same query is very fast when executed in the mongo shell

db.products.find()

I will definitely appreciate any assistance to unravel why the queries from the spring boot app are very slow.

答案1

得分: 1

以下是翻译好的内容:

  1. 确保 Spring Boot 应用程序不会创建其他查询,同时确保 Spring Boot 生成的实际 MongoDB 查询确实与你从命令行界面运行的查询相符。根据这个讨论串,你应该将 org.springframework.data.mongodb 的日志级别设置为 DEBUG

  2. 确保网络不是问题所在,也许你在同一台主机上同时运行 CLI 和 MongoDB 服务器,导致操作非常快速,然而你的 Spring Boot 应用程序托管在存在网络问题的服务器上。因此,创建一个最小的可复现示例(不包括 Spring Boot,只是简单的“main”程序,运行一个简单的 MongoDB 查询),并检查在托管 Spring Boot 应用程序的服务器上运行时的速度。或者,你可以复制 CLI 程序或使用一些 UI 工具,比如 Robomongo。

  3. 检查发送给 MongoDB 的复制/分片参数,例如,也许从应用程序中你对所有分片运行了查询,MongoDB 必须等待最慢的分片检索信息,然后才能将所有分片的结果组合起来,给出“结果”答案。

  4. 性能分析 - 如果你发现 Spring Boot 应用程序是延迟的原因,你将不得不进行性能分析,看看它在哪里卡住了。

英文:

Its hard to tell what exactly happens based on this descriptions, so I'll try to provide some general ideas that can lead to the solution

  1. Make sure that spring boot application does not create other queries, and also make sure that the actual query to mongo that spring boot generates indeed the one that you're running from the CLI. According to this thread you should set the log level for org.springframework.data.mongodb to DEBUG

  2. Make sure that the network is not the issue here, maybe you're running the CLI together with the mongo server(on the same host) and its really fast, whereas your spring boot application is hosted on the server that has network issues. So create a minimal reproducable example (without spring boot, just plain "main" that runs a simple query to the mongo db and check how fast it is when run from the server that host the spring boot application). Alternatively you can copy the CLI program or use some ui tool, style Robomongo.

  3. Check the replication/sharding parameters that you send to mongo, for example maybe from the application you run the query to all the shards and mongo will have to wait for the slowest shard to retrieve the information before it can combine the results from all the shards to give you the "result" answer.

  4. Profile - if you see that spring boot application is the reason of slowness - you'll have to profile and see where it gets stuck.

huangapple
  • 本文由 发表于 2020年9月6日 13:39:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/63761059.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定