[spring-projects/spring-boot]验证 CassandraProperties 默认值是否与驱动程序内置默认值相同

2024-05-09 88 views
3

修复 gh-24965

开发者文档

我不确定记录“嘿,如果您设置默认值并且它与驱动程序默认值对齐,在 assandraPropertiesTest 中为其添加测试”的最佳方法。现在,我在CasssandraProperties中添加了内嵌注释。

通常与默认值对齐

我假设我们希望与驱动程序默认值保持一致。

我们设置了一些默认值的属性,但驱动程序中没有默认值。由于驱动程序中的默认值为空,以下测试将失败。我省略了这些测试:

assertThat(properties.getRequest().getThrottler().getMaxQueueSize()).isEqualTo(
        optionsMap.get(TypedDriverOption.REQUEST_THROTTLER_MAX_QUEUE_SIZE));

assertThat(properties.getRequest().getThrottler().getMaxConcurrentRequests()).isEqualTo(
        optionsMap.get(TypedDriverOption.REQUEST_THROTTLER_MAX_CONCURRENT_REQUESTS));

assertThat(properties.getRequest().getThrottler().getMaxRequestsPerSecond()).isEqualTo(
        optionsMap.get(TypedDriverOption.REQUEST_THROTTLER_MAX_REQUESTS_PER_SECOND));

assertThat(properties.getRequest().getThrottler().getDrainInterval()).isEqualTo(
        optionsMap.get(TypedDriverOption.REQUEST_THROTTLER_DRAIN_INTERVAL));

此外,我们还有一个与驱动程序不同的属性(也省略了测试):

// This breaks as we have 120s and the driver has 500ms
assertThat(properties.getPool().getIdleTimeout()).isEqualTo(
                optionsMap.get(TypedDriverOption.HEARTBEAT_TIMEOUT));

回答

3

@snicoll 感谢您的反馈。我已做出建议的更改。

另外,您能评论一下我在 PR 描述中添加的 2 点吗?

  1. 我们设置了一些默认值的属性,但驱动程序中没有默认值。

  2. 我们有一个与驱动程序不同的属性。

3

另外,您能评论一下我在 PR 描述中添加的 2 点吗?

抱歉,我错过了那些。

我们设置了一些默认值的属性,但驱动程序中没有默认值。

当我们设置默认值时,我基于它,reference.conf这可能有点难以阅读,因为某些默认值是基于另一个属性的默认值。

以第一个属性为例,它10000在我们的元数据中,与驱动程序的reference.conf具有相同的值。不过,它看起来已经被注释掉了,所以我不太确定我是否做出了正确的决定,记录这些内容。

@adutra 你能帮助我们吗?

我们有一个与驱动程序不同的属性。

要么是一个错误,要么是两者之间的默认更改正是此 PR 应该处理的。

3

要么是一个错误,要么是两者之间的默认更改正是此 PR 应该处理的。

@snicoll 我将创建一个后续的 PR,将值放在奇偶校验中并添加测试来验证。或者您更喜欢我们在此 PR 中这样做?

6

@bono007 感谢您的提问。这是一项改进我们的测试套件并避免回归或不一致的任务。如果属性的默认值无效,则这是一个错误,我们希望另一个问题是它显示在发行说明中的​​适当位置。

让我们最终确定这一点,看看@adutra 对当前事态的看法。

9

你好!

首先,让我们记住,驱动程序中没有有限的“默认值”集,因为您几乎可以用自己的组件替换其任何组件,但第 3 方组件可能需要不同的设置才能正确配置。有时,驱动程序本身也会附带同一组件的 2 或 3 个替代品,每个替代品都有自己的一组设置。这就是为什么许多设置在reference.conf 中被注释掉的原因。我知道这并不能让您更容易地掌握需要定义哪些设置以及何时定义,但这就是达到这种级别的可定制性所付出的代价。

与该概念最接近的是驱动程序读取的所有设置及其值(当没有任何自定义内容时)的概念。这一点OptionsMap#driverDefaults确实体现出来了。但这也意味着在reference.conf中注释掉的设置也不会出现在该映射中。

在心跳超时的情况下,问题又是JAVA-2841:一些超时默认提高到 5 秒。只需在 Spring Boot 中将其设置为 5 秒来修复它,我们应该就可以了。我保证我们绝对不想再碰这些东西(我们这样做是因为云部署)。

在请求节流器的情况下,确实没有设置的默认值,REQUEST_THROTTLER_MAX_QUEUE_SIZE因为默认节流器是不需要它的无操作节流器。您在reference.conf中看到的注释掉的值实际上只是一个建议,并且在很大程度上取决于当前的用例。理想情况下,我认为 Spring Boot 不应该定义驱动程序不一定需要的设置,但我理解这些限制。如果您绝对必须为其提供默认值,那么请选择 10000,但也许您应该在 javadoc 中添加一条注释,鼓励用户对该值进行基准测试,直到他们为自己的情况找到最佳值。

如果我可以提供其他帮助,请告诉我。感谢您发布此公关!

2

感谢@adutra 提供的详细信息和链接 - 这真的很有帮助。

@斯尼科尔

一些观察结果:

  • 在 2.4.x 中,Cassandra 驱动程序版本为 4.9,并具有新的默认值。
  • 在 2.3.x 中,Cassandra 驱动程序版本是 4.6,它没有新的默认值(它们是在4.8.1中添加的)
  • 此 PR 的激励问题是 2.3.x。

这是我的想法:

  1. 在 2.3.x 中使用此 PR 并使用当前默认检查,并且不更改默认值 - 它确实反映了 4.6 驱动程序中的现实。
  2. 在 2.4 中创建一个问题,包含以下详细信息:
  • 决定删除或保留节流器默认值,并根据保留/删除创建/更新适当的文档
    • TypedDriverOption.REQUEST_THROTTLER_MAX_QUEUE_SIZE));
    • TypedDriverOption.REQUEST_THROTTLER_MAX_CONCURRENT_REQUESTS));
    • TypedDriverOption.REQUEST_THROTTLER_MAX_REQUESTS_PER_SECOND));
    • TypedDriverOption.REQUEST_THROTTLER_DRAIN_INTERVAL));
  • 调整以下默认超时值
    spring.data.cassandra.pool.idle-timeout: 5s
    spring.data.cassandra.pool.heartbeat-interval: 5s
  • 更新默认版本测试以涵盖上述情况

一旦我们确定了方向,我很高兴继续努力并实施这些改变。

1

理想情况下,我认为 Spring Boot 不应该定义驱动程序不一定需要的设置,但我理解这些限制。如果您绝对必须为其提供默认值,那么请选择 10000,但也许您应该在 javadoc 中添加一条注释,鼓励用户对该值进行基准测试,直到他们为自己的情况找到最佳值。

不,我们不需要提供值,但我们提供对它们的更高视图,并且默认值应该与 IMO 一致。现在,该类型的默认值NONE显示在元数据中,让用户知道默认情况下我们不使用任何类型的限制。那很好,我们想要这样。

让我们考虑一下用户使用该属性启用节流的用例,例如“速率限制”。我希望我们对队列大小等有合理的默认值。如果我们不为此提供默认值,则队列大小为 0,看起来它将几乎立即拒绝请求。我对吗?

我在这里试图展示的是,使用一个属性可以实现一种应该在 OOB 下工作的行为(或者因为未设置强制属性而失败)。

7

@bono007 让我们继续我们可以测试的内容(即在 中有效可用的默认值OptionsMap#driverDefaults。我们可以为默认值设置一个单独的问题,该问题不一致,因为2.4.x我们可以在合并此问题之前修复它。

我还不确定 4 个节流选项。

8

@snicoll 听起来不错。

让我们继续我们可以测试的内容(即在 OptionsMap#driverDefaults 中有效可用的默认值

我认为我们在这个 PR 中已经做到了这一点 - 唯一的例外是 HEARTBEAT_TIMEOUT 默认值之间的差异(我们有 120 秒,4.6 驱动程序有 500 毫秒)。

5

唯一的例外是 HEARTBEAT_TIMEOUT 默认值之间的差异(我们有 120 秒,4.6 驱动程序有 500 毫秒)。

你能提出另一个 PR 来反对2.4.x修复这个问题吗?如果是的话我可以先合并它,然后我会处理这个。如果没有,请告诉我,我会继续。

9

让我们考虑一下用户使用该属性启用节流的用例,例如“速率限制”。我希望我们对队列大小等有合理的默认值。如果我们不为此提供默认值,则队列大小为 0,看起来它将几乎立即拒绝请求。我对吗?

是的,队列大小为零意味着一旦所有可用许可用完,查询就会被拒绝。绝对不是一个好的默认值。

4

@adutra 谢谢。那么,我们该何去何从? Cassandra 的普通用户是否也会受到此影响?他们会设置属性来切换节流类型,并最终得到相同的行为,据我所知。

1

@adutra 谢谢。那么,我们该何去何从? Cassandra 的普通用户是否也会受到此影响?他们会设置属性来切换节流类型,并最终得到相同的行为,据我所知。

嗯,抱歉我们这里可能有误会。

我之前的评论是指 Spring Boot 会明确定义 的默认值零的假设datastax-java-driver.advanced.throttler.max-queue-size。与启用速率限制的属性相结合,这将导致不良情况,即如果用户启用速率限制但忘记更改默认队列大小,则驱动程序会很乐意根据请求启用速率限制,但最大队列大小为零。

另一方面,普通的驱动程序用户会收到错误。如果他们定义datastax-java-driver.advanced.throttler.class = RateLimitingRequestThrottler但忘记也定义一些值datastax-java-driver.advanced.throttler.max-queue-size(因为在reference.conf中没有默认值),那么驱动程序会抱怨并且无法初始化自身。

简而言之:您可以将最大队列大小设置为某个特殊值吗Optional.empty()?我认为这将是最好的解决方案。无论如何,将其设置为零都是一个坏主意。

抱歉,我希望这次我说得更清楚了。

3

你能针对 2.4.x 提出另一个 PR 来解决这个问题吗?如果是的话我可以先合并它,然后我会处理这个。如果没有,请告诉我,我会继续。

当然。现在就这么做。应该在~30分钟内

8

不,我们当然不会那样做,引用我自己的话

如果我们不为此提供默认值

好吧,失败是我在这次谈话中提到的另一种情况,司机这样做很好。我们不需要Optional.empty。我们有很多没有默认值的属性,如果用户没有设置它们,我们不会对它们做任何事情。我创建了https://github.com/spring-projects/spring-boot/issues/25149,谢谢@adutra!

8

非常感谢@bono007 的跟进!