【问题标题】:Speed up Elasticsearch Test Containers加速 Elasticsearch 测试容器
【发布时间】:2022-01-21 20:47:05
【问题描述】:

我已将 java 集成测试转移到使用 elasticsearch 测试容器,而不是使用嵌入式 elasticsearch。测试速度变慢了 1 小时,这对生产力造成了巨大影响。我正在寻找加快速度的方法。

我尝试在 Elasticsearch 容器上使用 reuse 之类的参数,但这并没有起到任何作用。我的最新配置是

    private static final String ELASTICSEARCH_VERSION = "7.11.2";
    private static ElasticsearchContainer elasticsearchContainer;
    private static final DockerImageName ELASTICSEARCH_IMAGE =
          DockerImageName
                .parse("docker.elastic.co/elasticsearch/elasticsearch")
                .withTag(ELASTICSEARCH_VERSION);
            elasticsearchContainer = new ElasticsearchContainer(ELASTICSEARCH_IMAGE)
                  .withEnv("foo", "bar").withSharedMemorySize(1000000000L);
            elasticsearchContainer.addExposedPorts(9200, 9300);
            elasticsearchContainer.withStartupTimeout(Duration.of(5, ChronoUnit.MINUTES));
            elasticsearchContainer.start();
    private static RestHighLevelClient getRestHighLevelClient(ElasticsearchContainer container) {
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY,
                                           new UsernamePasswordCredentials(ELASTICSEARCH_USERNAME,
                                                                           ELASTICSEARCH_PASSWORD));
        RestClientBuilder restClientBuilder = RestClient.builder(HttpHost.create(container.getHttpHostAddress()))
              .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder
                    .setDefaultCredentialsProvider(credentialsProvider)
                    .setKeepAliveStrategy((response, context) -> 3 * 60 * 1000));
        // Try to prevent SocketTimeoutException when fetching larger batch size
        restClientBuilder.setRequestConfigCallback(
              requestConfigBuilder -> requestConfigBuilder.setSocketTimeout(2 * 60 * 1000));

        return new RestHighLevelClient(restClientBuilder);
    }

Gradle 配置(gradle 守护程序崩溃一次,因此增加到 2g)

org.gradle.jvmargs=-Xms2g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

对加快测试有什么建议吗?

【问题讨论】:

    标签: java elasticsearch spring-data-elasticsearch testcontainers testcontainers-junit5


    【解决方案1】:

    对于任何性能工作或优化的一般建议是在引入更改之前进行衡量。我建议您在得出结论之前分析您的测试运行。

    其中有一些指标可以在不大量使用分析器的情况下进行估算。

    • Elastic 容器启动多长时间?

    对我来说需要 8.2 秒(我使用了elasticsearch-oss:7.10.2):

    14:35:55.803 [main] INFO  ? [docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2] -
     Container docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2 
     started in PT8.264592S
    
    • 您多久启动一次新容器? Docker 映像会被自然缓存,因此不必担心,但根据您组织测试套件的方式,启动新容器的时间可能会增加。

    您可以阅读更多关于由 Testcontainers in the docs 管理的容器的生命周期。

    例如,如果您使用 JUnit,您可以检查您是在 @BeforeEach@BeforeAll 中启动新容器还是在整个测试套件中使用单例容器。

    • 容器中的应用程序有多快?

    其中一个因素是允许 Docker 使用多少资源。默认情况下,Docker is configured 拥有 2G 内存,这可能是一个瓶颈。 如果容器中没有足够的可用内存,Elastic 的行为可能会比它应有的速度慢(如果它开始交换,甚至会更慢等)。为其提供充足的 CPU 和内存以获得最快的结果。

    如果查看这 3 件事没有帮助,那么也许您可以分析测试运行以检查瓶颈是什么。

    【讨论】:

    • 对我来说非常高:22/01/20 10:12:38 信息? [docker.elastic.co/elasticsearch/elasticsearch:7.11.2]:容器 docker.elastic.co/elasticsearch /elasticsearch:7.11.2 开始于 PT50.984S
    • 对我来说,启动 Elasticsearch 7.16.3 测试容器需要 20 多秒。但是我在所有的集成测试中只使用一个,我认为这是关键点。
    • @AsthaGupta,你能检查一下 Docker 可以访问多少资源吗?如果您提供更多内存/CPU,容器是否启动更快?
    • 这是完美的。我将内存从 2Gb 增加到 4 倍,并将 CPU 从 8 增加到 10,相同的测试在不到一分钟的时间内完成,而之前需要 30 分钟。再次感谢所有有用的链接!
    • 嗨,(免责声明:Co-Founder&CTO @Thundra)您还可以使用 Thundra Foresight 来跟踪、调试和检测测试中的性能瓶颈:thundra.io/foresight
    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    • 2010-10-17
    相关资源
    最近更新 更多