Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow user-provided custom scheduler for periodically binding KafkaMetrics #4976

Closed
vasiliy-sarzhynskyi opened this issue Apr 20, 2024 · 0 comments · Fixed by #4977
Closed
Labels
enhancement A general enhancement instrumentation An issue that is related to instrumenting a component module: micrometer-core An issue that is related to our core module
Milestone

Comments

@vasiliy-sarzhynskyi
Copy link
Contributor

Please describe the feature request.
Currently, KafkaClientMetrics does not provide the possibility to use a custom scheduler for binding metrics. Instead, it uses a default one:

ScheduledExecutorService scheduler = Executors
    .newSingleThreadScheduledExecutor(new NamedThreadFactory("micrometer-kafka-metrics"));

Ideally, it would be great to have the ability to pass an optional custom thread pool, so later Spring-Kafka will be able to propagate optional scheduler into KafkaClientMetrics.

Rationale
I have a Spring-Boot application with multiple consumers with the same consumer group using @KafkaListener from Spring-Kafka. After investigation, I discovered that per each consumer it creates additional Micrometer metrics daemon thread with the name micrometer-kafka-metrics, which is created by io.micrometer:micrometer.core inside KafkaMetrics.

The chain of invocations is the following. KafkaMetricsAutoConfiguration (from spring-boot-actuator-autoconfigure) creates a single instance of MicrometerConsumerListener (from Spring-Kafka) per application, and after that MicrometerConsumerListener has method consumerAdded(..) that is invoked per each Consumer. It creates KafkaClientMetrics (extended from KafkaMetrics). As a result, the number of consumers is the same as the number of threads micrometer-kafka-metrics.

If we have consumer factory concurrency as N (new ConcurrentKafkaListenerContainerFactory<>().setConcurrency(N);) and number of @KafkaListener as M (one per each topic, as we have M topics), as a result we have N * M threads with name micrometer-kafka-metrics. In most cases N * M is not a big number, but in some rare cases, it might be a few hundred (like in my case). I want to leave the number of concurrent consumers as is, but decrease the number of metrics threads, cause metrics threads are quite lightweight and scheduled with a fixed rate (1 minute by default).

So I'm looking at ways how to decrease the number of these metrics threads. Ideally, it would be great to have the ability to pass there optional custom thread pool, that will be shareable for all consumers and with the desired number of threads.

Additional context
I created a demo application to show this issue with the management API endpoint that returns current threads. You could execute the following integration test by your own to see the number of created threads micrometer-kafka-metrics.

References

vasiliy-sarzhynskyi added a commit to vasiliy-sarzhynskyi/micrometer that referenced this issue Apr 20, 2024
@shakuzen shakuzen added enhancement A general enhancement module: micrometer-core An issue that is related to our core module instrumentation An issue that is related to instrumenting a component and removed waiting-for-triage labels Oct 7, 2024
@shakuzen shakuzen added this to the 1.x milestone Oct 7, 2024
vasiliy-sarzhynskyi added a commit to vasiliy-sarzhynskyi/micrometer that referenced this issue Oct 11, 2024
vasiliy-sarzhynskyi added a commit to vasiliy-sarzhynskyi/micrometer that referenced this issue Oct 11, 2024
…oducer and AdminClient KafkaClientMetrics
vasiliy-sarzhynskyi added a commit to vasiliy-sarzhynskyi/micrometer that referenced this issue Oct 11, 2024
…oducer and AdminClient KafkaClientMetrics
@shakuzen shakuzen modified the milestones: 1.x, 1.14.0-RC1 Oct 12, 2024
@shakuzen shakuzen changed the title Consumer KafkaClientMetrics should provide possibility to use custom scheduler for binding metrics KafkaClientMetrics should provide possibility to use custom scheduler for binding metrics Oct 12, 2024
shakuzen added a commit that referenced this issue Oct 15, 2024
With many instances of KafkaMetrics (corresponding to many instances of Kafka clients corresponding to many consumers/producers/streams), many single-thread pools would be created to check and bind metrics from the Kafka client periodically. This allows users to provide their own scheduler which can be shared among instances, which will reduce the overhead of many single-thread schedulers.

Resolves gh-4976

Co-authored-by: Tommy Ludwig <8924140+shakuzen@users.noreply.github.com>
@shakuzen shakuzen changed the title KafkaClientMetrics should provide possibility to use custom scheduler for binding metrics Allow user-provided custom scheduler for periodically binding KafkaMetrics Oct 15, 2024
artembilan added a commit to artembilan/spring-kafka that referenced this issue Oct 16, 2024
Related to: micrometer-metrics/micrometer#4976

* Introduce a `KafkaMetricsSupport` to have a common API for the `MeterBinder` registration
* Rework `MicrometerConsumerListener`, `MicrometerProducerListener` and `KafkaStreamsMicrometerListener`
to extend the `KafkaMetricsSupport` which allows to minimize code duplication
* Expose ctors on those listeners based on the `TaskScheduler`
* Implement a simple `ScheduledExecutorServiceAdapter` to adapt a `TaskScheduler`
to the expected by the `KafkaMetrics` `ScheduledExecutorService`
artembilan added a commit to artembilan/spring-kafka that referenced this issue Oct 17, 2024
Related to: micrometer-metrics/micrometer#4976

* Introduce a `KafkaMetricsSupport` to have a common API for the `MeterBinder` registration
* Rework `MicrometerConsumerListener`, `MicrometerProducerListener` and `KafkaStreamsMicrometerListener`
to extend the `KafkaMetricsSupport` which allows to minimize code duplication
* Expose ctors on those listeners based on the `TaskScheduler`
* Implement a simple `ScheduledExecutorServiceAdapter` to adapt a `TaskScheduler`
to the expected by the `KafkaMetrics` `ScheduledExecutorService`
artembilan added a commit to artembilan/spring-kafka that referenced this issue Oct 17, 2024
Related to: micrometer-metrics/micrometer#4976

* Introduce a `KafkaMetricsSupport` to have a common API for the `MeterBinder` registration
* Rework `MicrometerConsumerListener`, `MicrometerProducerListener` and `KafkaStreamsMicrometerListener`
to extend the `KafkaMetricsSupport` which allows to minimize code duplication
* Expose ctors on those listeners based on the `TaskScheduler`
* Implement a simple `ScheduledExecutorServiceAdapter` to adapt a `TaskScheduler`
to the expected by the `KafkaMetrics` `ScheduledExecutorService`
artembilan added a commit to artembilan/spring-kafka that referenced this issue Oct 17, 2024
Related to: micrometer-metrics/micrometer#4976

* Introduce a `KafkaMetricsSupport` to have a common API for the `MeterBinder` registration
* Rework `MicrometerConsumerListener`, `MicrometerProducerListener` and `KafkaStreamsMicrometerListener`
to extend the `KafkaMetricsSupport` which allows to minimize code duplication
* Expose ctors on those listeners based on the `TaskScheduler`
* Implement a simple `ScheduledExecutorServiceAdapter` to adapt a `TaskScheduler`
to the expected by the `KafkaMetrics` `ScheduledExecutorService`
sobychacko pushed a commit to spring-projects/spring-kafka that referenced this issue Oct 17, 2024
* Add `TaskScheduler` option for Kafka metrics components

Related to: micrometer-metrics/micrometer#4976

* Introduce a `KafkaMetricsSupport` to have a common API for the `MeterBinder` registration
* Rework `MicrometerConsumerListener`, `MicrometerProducerListener` and `KafkaStreamsMicrometerListener`
to extend the `KafkaMetricsSupport` which allows to minimize code duplication
* Expose ctors on those listeners based on the `TaskScheduler`
* Implement a simple `ScheduledExecutorServiceAdapter` to adapt a `TaskScheduler`
to the expected by the `KafkaMetrics` `ScheduledExecutorService`

* * Improve `KafkaMetricsSupport` API to make it more friendly for target projects
* Add more JavaDocs to the `KafkaMetricsSupport`
* Mention `KafkaMetricsSupport` in the docs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement A general enhancement instrumentation An issue that is related to instrumenting a component module: micrometer-core An issue that is related to our core module
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants