Optaplanner cloning solution between afterVariableChanged and calculateScore - optaplanner

We are using OptaPlanner with the IncrementalScoreCalculator model and were working under the assumption that intermediate clones (for saving a new best solution when encontered) were made just after the calculateScore call (therefore using the newly calculated hard/soft score in order to determine whether it is the best solution).
As we are working with a problem state that is only updated in the calculateScore phase (due to performance reasons) this leads to the selection of a new solution with an out of date score.
Is there any way we can configure the best solution to be selected/cloned only just after the calculateScore step?
Update: Running the solver with the FULL_ASSERT directive avoids the issue : cloning always happens after calculateScore(). However, if no directive is used the following happens (each line represents a Solution Id - Iteration key):
2022-10-20 01:05:02.828 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1000 - AfterVariableChanged
2022-10-20 01:05:02.828 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1000 - CalculateScore
2022-10-20 01:05:02.829 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - BeforeVariableChanged
2022-10-20 01:05:02.829 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - AfterVariableChanged
2022-10-20 01:05:02.829 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - BeforeVariableChanged
2022-10-20 01:05:02.829 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - AfterVariableChanged
2022-10-20 01:05:02.829 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - BeforeVariableChanged
2022-10-20 01:05:02.829 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - AfterVariableChanged
2022-10-20 01:05:02.830 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - BeforeVariableChanged
2022-10-20 01:05:02.830 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - AfterVariableChanged
2022-10-20 01:05:02.830 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - BeforeVariableChanged
2022-10-20 01:05:02.830 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - AfterVariableChanged
2022-10-20 01:05:02.830 INFO 86000 --- [nio-5000-exec-5] c.o.p.o.h.s.SNPSchedulingSolutionCloner : 4-1001 - CloneSolution -- here is where the solution is cloned, before a new scoreCalculation and in the same thread --
2022-10-20 01:05:03.089 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - BeforeVariableChanged
2022-10-20 01:05:03.089 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - AfterVariableChanged
2022-10-20 01:05:03.089 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - BeforeVariableChanged
2022-10-20 01:05:03.089 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - AfterVariableChanged
2022-10-20 01:05:03.089 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - BeforeVariableChanged
2022-10-20 01:05:03.089 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - AfterVariableChanged
2022-10-20 01:05:03.089 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1001 - CalculateScore
2022-10-20 01:05:03.263 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1002 - BeforeVariableChanged
2022-10-20 01:05:03.263 INFO 86000 --- [nio-5000-exec-5] .SNPSchedulingIncrementalScoreCalculator : 4-1002 - AfterVariableChanged
We have tested with OptaPlanner 8.29.0.Final and 8.16.1.Final.
Evaluating the BestSolutionRecaller method this is what I've found:
A clone is created as the method understands that the current score (0 hard / 7 soft, from iteration 1000) is better than the best score from SolverScope (0 hard / 0 soft). However, at a prior iteration (741) a best score of (0 hard / 7 soft) had already been found.

From the sequence of operations you posted, I do not (yet) see an issue. The fact that there are multiple variable change events before a score is calculated could be totally normal; a move that switches two vehicle destinations does two variable updates, a pillar move that changes all beds in the same department could possibly update dozens of variables.
It is logical that score calculation would only be called after all of those updates have been triggered, as anywhere in the middle would be an inconsistent solution state. Score calculation must happen after a move finishes, not after events are triggered.
Furthermore, this code is exercised by our users daily, it is also heavily covered with tests. It is the very core of OptaPlanner, it has to work. If we had a bug in here, we would have been notified immediately, and not months after the fact. (I assume your mention of 8.16.1.Final means that you are seeing the issue there as well. That release is, by now, nearly a year old.)
All of the above leads me to conclude that there is no issue on OptaPlanner side. Running NON_INTRUSIVE_FULL_ASSERT environment mode can either point you to an issue in your score calculator implementation, or prove me wrong. That said, if the assert mode passes, I'm going to have to see proof that, when the move finishes, there really is no score calculation. This would be a serious bug, and that would be the answer to your question.

Related

Backpressure on WebClient - applying backpressure to inter-service async web requests

The description below summarizes my novice attempt at applying backpressure on webclient.
Scenario 1: Applying limitRate() on reactive mongodb response. Service #1 runs on port 8080 on my machine
Code:
#GetMapping(path = "/getBooks/{name}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Book> getBooks(#PathVariable("name") final String name)
{
//SERVICE #1
return bookRepo.findByBookName(name)
.log()
.limitRate(3);
}
Logs:
2022-10-04 13:52:28.919 INFO 38716 --- [ restartedMain] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port 8080
2022-10-04 13:52:28.932 INFO 38716 --- [ restartedMain] c.example.demo.ReactiveDemoApplication : Started ReactiveDemoApplication in 3.538 seconds (JVM running for 4.198)
2022-10-04 13:58:20.363 INFO 38716 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onSubscribe(FluxUsingWhen.UsingWhenSubscriber)
2022-10-04 13:58:20.366 INFO 38716 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : request(3)
2022-10-04 13:58:20.424 INFO 38716 --- [ntLoopGroup-3-3] org.mongodb.driver.connection : Opened connection [connectionId{localValue:3, serverValue:276}] to localhost:27017
2022-10-04 13:58:20.474 INFO 38716 --- [ntLoopGroup-3-3] reactor.Flux.UsingWhen.1 : onNext(Book(id=1, bookName=bn2, authorName=an))
2022-10-04 13:58:20.491 INFO 38716 --- [ntLoopGroup-3-3] reactor.Flux.UsingWhen.1 : onNext(Book(id=2, bookName=bn2, authorName=an))
2022-10-04 13:58:20.492 INFO 38716 --- [ntLoopGroup-3-3] reactor.Flux.UsingWhen.1 : onNext(Book(id=3, bookName=bn2, authorName=an))
2022-10-04 13:58:20.554 INFO 38716 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : request(3)
2022-10-04 13:58:20.555 INFO 38716 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=4, bookName=bn2, authorName=an))
2022-10-04 13:58:20.555 INFO 38716 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=5, bookName=bn2, authorName=an))
2022-10-04 13:58:20.555 INFO 38716 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=6, bookName=bn2, authorName=an))
and so on .. until :
2022-10-04 13:58:20.561 INFO 38716 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=14, bookName=bn2, authorName=an))
2022-10-04 13:58:20.561 INFO 38716 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=15, bookName=bn2, authorName=an))
2022-10-04 13:58:20.562 INFO 38716 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=16, bookName=bn2, authorName=an))
2022-10-04 13:58:20.566 INFO 38716 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onComplete()
2022-10-04 13:58:20.568 INFO 38716 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : request(3)
Scenario 2: Applying limitRate() on Service #2's webclient response. Service #2 calls Service #1. Service #1 runs on port 8080 on my machine
Code:
Service #1 endpoint:
#GetMapping(path = "/getBooks/{name}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Book> getBooks(#PathVariable("name") final String name)
{
//SERVICE #1
return bookRepo.findByBookName(name)
.log();
}
Service #2:
#GetMapping("/getBooks")
public Flux<Book> getBooks() {
// SERVICE #2
return webClient.get()
.uri("http://localhost:8080/api/v1/books/getBooks/bn2")
.retrieve()
.bodyToFlux(Book.class)
.log()
.limitRate(3);
}
Logs: SERVICE #1
2022-10-04 16:36:45.386 INFO 17520 --- [ restartedMain] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port 8080
2022-10-04 16:36:45.397 INFO 17520 --- [ restartedMain] c.example.demo.ReactiveDemoApplication : Started ReactiveDemoApplication in 4.894 seconds (JVM running for 6.311)
2022-10-04 16:42:21.718 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onSubscribe(FluxUsingWhen.UsingWhenSubscriber)
2022-10-04 16:42:21.720 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : request(1)
2022-10-04 16:42:21.782 INFO 17520 --- [ntLoopGroup-3-3] org.mongodb.driver.connection : Opened connection [connectionId{localValue:3, serverValue:7}] to localhost:27017
2022-10-04 16:42:21.840 INFO 17520 --- [ntLoopGroup-3-3] reactor.Flux.UsingWhen.1 : onNext(Book(id=1, bookName=bn2, authorName=an))
2022-10-04 16:42:21.913 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : request(31)
2022-10-04 16:42:21.914 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=2, bookName=bn2, authorName=an))
2022-10-04 16:42:21.915 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=3, bookName=bn2, authorName=an))
2022-10-04 16:42:21.916 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=4, bookName=bn2, authorName=an))
2022-10-04 16:42:21.917 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=5, bookName=bn2, authorName=an))
2022-10-04 16:42:21.918 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=6, bookName=bn2, authorName=an))
2022-10-04 16:42:21.919 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=7, bookName=bn2, authorName=an))
2022-10-04 16:42:21.920 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=8, bookName=bn2, authorName=an))
2022-10-04 16:42:21.921 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=10, bookName=bn2, authorName=an))
2022-10-04 16:42:21.921 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=11, bookName=bn2, authorName=an))
2022-10-04 16:42:21.922 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=12, bookName=bn2, authorName=an))
2022-10-04 16:42:21.923 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=13, bookName=bn2, authorName=an))
2022-10-04 16:42:21.923 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=14, bookName=bn2, authorName=an))
2022-10-04 16:42:21.924 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=15, bookName=bn2, authorName=an))
2022-10-04 16:42:21.925 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onNext(Book(id=16, bookName=bn2, authorName=an))
2022-10-04 16:42:21.931 INFO 17520 --- [ctor-http-nio-2] reactor.Flux.UsingWhen.1 : onComplete()
logs: SERVICE #2
2022-10-04 16:45:26.291 INFO 27496 --- [ restartedMain] c.example.demo.ReactiveDemo3Application : Started ReactiveDemo3Application in 3.507 seconds (JVM running for 4.1)
2022-10-04 16:45:43.159 INFO 27496 --- [ctor-http-nio-2] reactor.Flux.MonoFlatMapMany.1 : onSubscribe(MonoFlatMapMany.FlatMapManyMain)
2022-10-04 16:45:43.163 INFO 27496 --- [ctor-http-nio-2] reactor.Flux.MonoFlatMapMany.1 : request(3)
2022-10-04 16:45:43.845 INFO 27496 --- [ctor-http-nio-2] reactor.Flux.MonoFlatMapMany.1 : onNext(Book(id=1, bookName=bn2, authorName=an))
2022-10-04 16:45:43.875 INFO 27496 --- [ctor-http-nio-2] reactor.Flux.MonoFlatMapMany.1 : onNext(Book(id=2, bookName=bn2, authorName=an))
2022-10-04 16:45:43.876 INFO 27496 --- [ctor-http-nio-2] reactor.Flux.MonoFlatMapMany.1 : onNext(Book(id=3, bookName=bn2, authorName=an))
2022-10-04 16:45:45.924 INFO 27496 --- [ parallel-2] reactor.Flux.MonoFlatMapMany.1 : request(3)
and so on..
I was expecting request(3) like Scenario 1, but this time i see request(1) and request (31).
Even after adding delay in SERVICE #2 , the Logs remain the same. :-
return webClient.get()
.uri("http://localhost:8080/api/v1/books/getBooks/bn2")
.retrieve()
.bodyToFlux(Book.class)
.log()
.limitRate(3)
.delayElements(Duration.ofSeconds(1));
What am i missing?
EDIT 1: I am getting similar results with subscriber-controlled backpressure.
It could be hard to control backpreasure using limitRate and delayElements. If your goal is to have more granular control on number of requests, I would suggest to look at recilience4j RateLimiter. It's fully reactive and could be integrated into the flow using RateLimiterOperator
RateLimiterConfig rateLimiterConfig = RateLimiterConfig.custom()
.limitRefreshPeriod(Duration.ofSeconds(1))
.limitForPeriod(2) // 2 requests per second
.timeoutDuration(Duration.ofMinutes(30))
.build();
RateLimiterRegistry registry = RateLimiterRegistry.of(rateLimiterConfig);
RateLimiter rateLimiter = registry.rateLimiter("WebClient");
webClient.get()
.uri("http://localhost:8080/api/v1/books/getBooks/bn2")
.retrieve()
.bodyToFlux(Book.class)
.transform(RateLimiterOperator.of(rateLimiter));

How do I configure HikariCP correctly to work with connections that have to stay active?

I am using Spring Boot 2.4.0 with Spring Boot Data JPA to connect to PostgreSQL and perform typical read and write operations with JPA based repositories. Since the database is also used by other services, I use the LISTEN/NOTIFY functionality (https://www.postgresql.org/docs/9.1/sql-listen.html) to be notified about changes from PostgeSQL. For this I use the driver com.impossibl.postgres.jdbc.PGDriver instead of the default driver and the following code to make Spring listen for changes to the database:
#Service
class PostgresChangeListener(
val dataSource: HikariDataSource,
#Qualifier("dbToPGReceiverQueue") val postgresQueue: RBlockingQueue<String>
) {
init {
listenToNotifyMessage()
}
final fun listenToNotifyMessage() {
val notificationListener = object:PGNotificationListener {
override fun notification(processId: Int, channelName: String, payload: String) {
log.info("Received change from PostgresQL: $processId, $channelName, $payload")
postgresQueue.add(payload)
}
override fun closed() {
log.debug("Connection to Postgres lost! Try to reconnect...")
listenToNotifyMessage()
}
}
try {
val connection = DataSourceUtils.getConnection(dataSource).unwrap(PGConnection::class.java)
connection.addNotificationListener(notificationListener)
connection.createStatement().use { statement -> statement.execute("LISTEN change_notifier;") }
} catch (e: SQLException) {
throw RuntimeException(e)
}
}
}
This is the Kotlin-like implementation of the listener discribed here: https://impossibl.github.io/pgjdbc-ng/docs/current/user-guide/#extensions-notifications
The listener works, however after one or more days I get the following error:
2021-03-03 06:33:00.185 WARN 1 --- [nio-8080-exec-8] o.s.b.a.jdbc.DataSourceHealthIndicator : DataSource health check failed
org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30001ms.
...
To find the problem, i enabled logging from Hikari as recommended on https://github.com/brettwooldridge/HikariCP/issues/1111#issuecomment-569552070. Here is the output of an excerpt of the logs:
2021-03-02 21:31:59.055 DEBUG 1 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Pool stats (total=10, active=1, idle=9, waiting=0)
...
2021-03-02 21:31:59.055 DEBUG 1 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Pool stats (total=10, active=1, idle=9, waiting=0)
2021-03-02 22:00:53.139 DEBUG 1 --- [nnection closer] com.zaxxer.hikari.pool.PoolBase : HikariPool-1 - Closing connection com.impossibl.postgres.jdbc.PGDirectConnection#201ab69f: (connection has passed maxLifetime)
2021-03-02 22:00:53.162 DEBUG 1 --- [onnection adder] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.impossibl.postgres.jdbc.PGDirectConnection#f2ffd1ea
2021-03-02 22:00:54.709 DEBUG 1 --- [nnection closer] com.zaxxer.hikari.pool.PoolBase : HikariPool-1 - Closing connection com.impossibl.postgres.jdbc.PGDirectConnection#3bb847ef: (connection has passed maxLifetime)
2021-03-02 22:00:54.730 DEBUG 1 --- [onnection adder] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.impossibl.postgres.jdbc.PGDirectConnection#fd5932d7
2021-03-02 22:00:59.110 DEBUG 1 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Pool stats (total=10, active=1, idle=9, waiting=0)
2021-03-02 22:00:59.111 DEBUG 1 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Fill pool skipped, pool is at sufficient level.
2021-03-02 22:01:04.782 DEBUG 1 --- [nnection closer] com.zaxxer.hikari.pool.PoolBase : HikariPool-1 - Closing connection com.impossibl.postgres.jdbc.PGDirectConnection#1d081266: (connection has passed maxLifetime)
2021-03-02 22:01:04.803 DEBUG 1 --- [onnection adder] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.impossibl.postgres.jdbc.PGDirectConnection#e0b396bc
2021-03-02 22:01:09.295 DEBUG 1 --- [nnection closer] com.zaxxer.hikari.pool.PoolBase : HikariPool-1 - Closing connection com.impossibl.postgres.jdbc.PGDirectConnection#a2b0bd29: (connection has passed maxLifetime)
2021-03-02 22:01:09.313 DEBUG 1 --- [onnection adder] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.impossibl.postgres.jdbc.PGDirectConnection#ca9c8226
2021-03-02 22:01:10.075 DEBUG 1 --- [nnection closer] com.zaxxer.hikari.pool.PoolBase : HikariPool-1 - Closing connection com.impossibl.postgres.jdbc.PGDirectConnection#ec8746aa: (connection has passed maxLifetime)
2021-03-02 22:01:10.093 DEBUG 1 --- [onnection adder] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.impossibl.postgres.jdbc.PGDirectConnection#aff2bfd8
2021-03-02 22:01:12.820 DEBUG 1 --- [nnection closer] com.zaxxer.hikari.pool.PoolBase : HikariPool-1 - Closing connection com.impossibl.postgres.jdbc.PGDirectConnection#a7e0fc39: (connection has passed maxLifetime)
2021-03-02 22:01:12.840 DEBUG 1 --- [onnection adder] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.impossibl.postgres.jdbc.PGDirectConnection#d637554
2021-03-02 22:01:15.099 DEBUG 1 --- [nnection closer] com.zaxxer.hikari.pool.PoolBase : HikariPool-1 - Closing connection com.impossibl.postgres.jdbc.PGDirectConnection#dadcba66: (connection has passed maxLifetime)
2021-03-02 22:01:15.119 DEBUG 1 --- [onnection adder] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.impossibl.postgres.jdbc.PGDirectConnection#e29805ef
2021-03-02 22:01:21.558 DEBUG 1 --- [nnection closer] com.zaxxer.hikari.pool.PoolBase : HikariPool-1 - Closing connection com.impossibl.postgres.jdbc.PGDirectConnection#762f0753: (connection has passed maxLifetime)
2021-03-02 22:01:21.576 DEBUG 1 --- [onnection adder] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.impossibl.postgres.jdbc.PGDirectConnection#d5b8d008
2021-03-02 22:01:23.351 DEBUG 1 --- [nnection closer] com.zaxxer.hikari.pool.PoolBase : HikariPool-1 - Closing connection com.impossibl.postgres.jdbc.PGDirectConnection#5e4721b0: (connection has passed maxLifetime)
2021-03-02 22:01:23.370 DEBUG 1 --- [onnection adder] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.impossibl.postgres.jdbc.PGDirectConnection#a8606b56
2021-03-02 22:01:29.111 DEBUG 1 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Pool stats (total=10, active=1, idle=9, waiting=0)
2021-03-02 22:01:29.111 DEBUG 1 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Fill pool skipped, pool is at sufficient level.
2021-03-02 22:01:59.112 DEBUG 1 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Pool stats (total=10, active=1, idle=9, waiting=0)
...
For me the log looks correct but after a while the active connections increase more and more...
...
2021-03-03 06:31:29.664 DEBUG 1 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Pool stats (total=10, active=9, idle=1, waiting=0)
2021-03-03 06:31:48.687 DEBUG 1 --- [nnection closer] com.zaxxer.hikari.pool.PoolBase : HikariPool-1 - Closing connection com.impossibl.postgres.jdbc.PGDirectConnection#4fa5ec41: (connection is dead)
2021-03-03 06:31:48.707 DEBUG 1 --- [onnection adder] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.impossibl.postgres.jdbc.PGDirectConnection#693052fe
2021-03-03 06:31:48.709 DEBUG 1 --- [nnection closer] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Fill pool skipped, pool is at sufficient level.
2021-03-03 06:31:59.665 DEBUG 1 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Pool stats (total=10, active=10, idle=0, waiting=1)
2021-03-03 06:31:59.665 DEBUG 1 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Fill pool skipped, pool is at sufficient level.
2021-03-03 06:32:20.199 DEBUG 1 --- [io-8080-exec-10] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Timeout failure stats (total=10, active=10, idle=0, waiting=2)
2021-03-03 06:32:20.208 WARN 1 --- [io-8080-exec-10] o.s.b.a.jdbc.DataSourceHealthIndicator : DataSource health check failed
org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30000ms.
...
... until it comes to the described error message.
I wonder how I need to configure Hikari correctly or change my code to avoid the errors described? I hope you can help.
Not the same issue, but I had a similar problem. When my database was restarted, Hikari couldn't close the active listener connection, and the whole notification stopped working.
I found a possible solution for this. The reason why Hikari can't close the connection when it's dead because you are unwrapping the connection from the proxied Connection here:
DataSourceUtils.getConnection(dataSource).unwrap(PGConnection::class.java)
After this you are attaching a notificationListener to the PGConnection, so it remains alive.
First thing first to avoid hikaripool leaking you should seperate the 2 connection, and after initializing the listener you should close the hikariConnection.
private hikariConnection: Connection;
...
hikariConnection = DataSourceUtils.getConnection(dataSource)
val pgConnection: PGConnection = hikariConnection.unwrap(PGConnection::class.java)
... init the listener
hikariConnection.close()
And in the PGNotificationListener.closed() you have to reinitalize the listener, get a new Connection from the datasource. But beware, getting new connection while the Hikaripool filling it's pool(because the database outage was only a few seconds), can block each other. We solved it by getting the new connection on a dedicated new thread.
override fun closed() {
... get a new PGConnection, and start listening for the notifications
}
Sorry if it's not correctly answering your question, but it may help to some.

Spring Cloud Config Client: Fetching config from wrong server

When I run my Spring Cloud Config Client project config-client, I found these error:
2018-02-09 10:31:09.885 INFO 13933 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:8888
2018-02-09 10:31:10.022 WARN 13933 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Could not locate PropertySource: I/O error on GET request for "http://localhost:8888/config-client/dev/master": 拒绝连接 (Connection refused); nested exception is java.net.ConnectException: 拒绝连接 (Connection refused)
2018-02-09 10:31:10.026 INFO 13933 --- [ main] c.y.c.ConfigClientApplication : No active profile set, falling back to default profiles: default
2018-02-09 10:31:10.040 INFO 13933 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#33b1c5c5: startup date [Fri Feb 09 10:31:10 CST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext#1ffe63b9
2018-02-09 10:31:10.419 INFO 13933 --- [ main] o.s.cloud.context.scope.GenericScope : BeanFactory id=65226c2b-524f-3b14-8e17-9fdbc9f72d85
2018-02-09 10:31:10.471 INFO 13933 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$25380e89] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-02-09 10:31:10.688 INFO 13933 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 10001 (http)
2018-02-09 10:31:10.697 INFO 13933 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2018-02-09 10:31:10.698 INFO 13933 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.27
2018-02-09 10:31:10.767 INFO 13933 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-02-09 10:31:10.768 INFO 13933 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 727 ms
2018-02-09 10:31:10.861 INFO 13933 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2018-02-09 10:31:10.864 INFO 13933 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-02-09 10:31:10.864 INFO 13933 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-02-09 10:31:10.864 INFO 13933 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-02-09 10:31:10.865 INFO 13933 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2018-02-09 10:31:10.895 WARN 13933 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configClientApplication': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'content' in value "${content}"
2018-02-09 10:31:10.896 INFO 13933 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2018-02-09 10:31:10.914 INFO 13933 --- [ main] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2018-02-09 10:31:10.923 ERROR 13933 --- [ main] o.s.boot.SpringApplication : Application startup failed
Apparently, the config server is wrong. However, the Spring Cloud Config Server is running at localhost:10000/ and application.yml of the project(config-client) is below. Why the spring.cloud.config.uri doesn't work?
application.yml [config-client]
server:
port: 10001
spring:
application:
name: config-client
cloud:
config:
label: master
profile: dev
uri: http://localhost:10000
Fur future readers, as answered here, when using Spring Cloud Config Server, we should specify basic bootstrap settings such as : spring.application.name and spring.cloud.config.uri inside bootstrap.yml (or "bootstrap.properties").
Upon startup, Spring Cloud makes an HTTP call to the config server with the name of the application and retrieves back that application's configuration.
That's said, since we're externalizing our settings using Spring Cloud Config Server, any default configurations defined in application.yml (or "application.properties") will be overridden during the bootstrap process upon startup.
IntelliJ Users: add the following override parameter in the run/Debug Configuration:
Name: spring.cloud.config.uri
Value: http://your-server-here/config-server
you can load configuration servers before starting the Application, using bootstrap.yml
just add configuration server and application name
spring:
application:
name: clientTest
cloud:
config:
uri: http://localhost:8889
enabled: true
fail-fast: true
if we are using bootstrap.properties. we have to include this dependency in pom for spring-2.4.0+
agregado para evitar un error al usar spring mayor que 2.4.0
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
in my case i was testing spring consul, which usually runs in 8500, i saw a different port in the log. Found that the different port is due to following deplendency of spring cloud. Hence i just have to remove it.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>

Simple jMeter non gui test ends with Error in NonGUIDriver java.lang.NullPointerException

I am trying to run the simple jMeter test in non gui, I am using a simple command like:
jmeter -n -t davelatal-cz.jmx -Jusers=4 -Jduration=300
I changed thread preferences as you can see on screenshot below:
Thread Preferences
So if I try to run this simple HTTP Request test, bash shows me this error:
Error in NonGUIDriver java.lang.NullPointerException
Screenshot:
Error screenshot
Here is LOG file:
2017/09/19 08:05:15 INFO - jmeter.util.JMeterUtils: Setting Locale to cs_CZ
2017/09/19 08:05:15 ERROR - jmeter.util.JMeterUtils: Could not find resources for 'cs_CZ'
2017/09/19 08:05:15 INFO - jmeter.JMeter: Loading user properties from: /usr/share/jmeter/bin/user.properties
2017/09/19 08:05:15 INFO - jmeter.JMeter: Loading system properties from: /usr/share/jmeter/bin/system.properties
2017/09/19 08:05:15 INFO - jmeter.JMeter: Setting JMeter property: users=4
2017/09/19 08:05:15 INFO - jmeter.JMeter: Setting JMeter property: duration=300
2017/09/19 08:05:15 INFO - jmeter.JMeter: Copyright (c) 1998-2014 The Apache Software Foundation
2017/09/19 08:05:15 INFO - jmeter.JMeter: Version 2.11.20151206
2017/09/19 08:05:15 INFO - jmeter.JMeter: java.version=1.8.0_131
2017/09/19 08:05:15 INFO - jmeter.JMeter: java.vm.name=OpenJDK 64-Bit Server VM
2017/09/19 08:05:15 INFO - jmeter.JMeter: os.name=Linux
2017/09/19 08:05:15 INFO - jmeter.JMeter: os.arch=amd64
2017/09/19 08:05:15 INFO - jmeter.JMeter: os.version=4.4.0-43-Microsoft
2017/09/19 08:05:15 INFO - jmeter.JMeter: file.encoding=UTF-8
2017/09/19 08:05:15 INFO - jmeter.JMeter: Default Locale=čeština (Česká republika)
2017/09/19 08:05:15 INFO - jmeter.JMeter: JMeter Locale=čeština (Česká republika)
2017/09/19 08:05:15 INFO - jmeter.JMeter: JMeterHome=/usr/share/jmeter
2017/09/19 08:05:15 INFO - jmeter.JMeter: user.dir =/mnt/c/Users/latal/Documents/Nigga
2017/09/19 08:05:15 INFO - jmeter.JMeter: PWD =/mnt/c/Users/latal/Documents/Nigga
2017/09/19 08:05:15 INFO - jmeter.JMeter: IP: 127.0.1.1 Name: J5MPJ72 FullName: J5MPJ72.bscpraha.cz
2017/09/19 08:05:15 INFO - jmeter.services.FileServer: Default base='/mnt/c/Users/latal/Documents/Nigga'
2017/09/19 08:05:15 INFO - jmeter.services.FileServer: Set new base='/mnt/c/Users/latal/Documents/Nigga'
2017/09/19 08:05:15 INFO - jmeter.JMeter: Loading file: davelatal-cz.jmx
2017/09/19 08:05:15 INFO - jmeter.save.SaveService: Testplan (JMX) version: 2.2. Testlog (JTL) version: 2.2
2017/09/19 08:05:15 INFO - jmeter.save.SaveService: Using SaveService properties file encoding UTF-8
2017/09/19 08:05:15 INFO - jmeter.save.SaveService: Using SaveService properties version 2.6
2017/09/19 08:05:15 INFO - jmeter.save.SaveService: Using SaveService properties file version 1554411
2017/09/19 08:05:15 INFO - jmeter.save.SaveService: All converter versions present and correct
2017/09/19 08:05:15 ERROR - jmeter.save.SaveService: Conversion error com.thoughtworks.xstream.converters.ConversionException: No field 'sentBytes' found in class 'org.apache.jmeter.samplers.SampleSaveConfiguration' : No field 'sentBytes' found in class 'org.apache.jmeter.samplers.SampleSaveConfiguration'
---- Debugging information ----
message : No field 'sentBytes' found in class 'org.apache.jmeter.samplers.SampleSaveConfiguration'
cause-exception : com.thoughtworks.xstream.converters.reflection.MissingFieldException
cause-message : No field 'sentBytes' found in class 'org.apache.jmeter.samplers.SampleSaveConfiguration'
class : org.apache.jmeter.samplers.SampleSaveConfiguration
required-type : org.apache.jmeter.samplers.SampleSaveConfiguration
converter-type : org.apache.jmeter.save.converters.SampleSaveConfigurationConverter
path : /jmeterTestPlan/hashTree/hashTree/hashTree/ResultCollector/objProp/value/sentBytes
line number : 56
class[1] : org.apache.jmeter.testelement.property.ObjectProperty
converter-type[1] : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
class[2] : org.apache.jmeter.reporters.ResultCollector
converter-type[2] : org.apache.jmeter.save.converters.TestElementConverter
class[3] : org.apache.jorphan.collections.ListedHashTree
converter-type[3] : org.apache.jmeter.save.converters.HashTreeConverter
------------------------------- : No field 'sentBytes' found in class 'org.apache.jmeter.samplers.SampleSaveConfiguration' : No field 'sentBytes' found in class 'org.apache.jmeter.samplers.SampleSaveConfiguration'
---- Debugging information ----
message : No field 'sentBytes' found in class 'org.apache.jmeter.samplers.SampleSaveConfiguration'
cause-exception : com.thoughtworks.xstream.converters.reflection.MissingFieldException
cause-message : No field 'sentBytes' found in class 'org.apache.jmeter.samplers.SampleSaveConfiguration'
class : org.apache.jmeter.samplers.SampleSaveConfiguration
required-type : org.apache.jmeter.samplers.SampleSaveConfiguration
converter-type : org.apache.jmeter.save.converters.SampleSaveConfigurationConverter
path : /jmeterTestPlan/hashTree/hashTree/hashTree/ResultCollector/objProp/value/sentBytes
line number : 56
class[1] : org.apache.jmeter.testelement.property.ObjectProperty
converter-type[1] : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
class[2] : org.apache.jmeter.reporters.ResultCollector
converter-type[2] : org.apache.jmeter.save.converters.TestElementConverter
class[3] : org.apache.jorphan.collections.ListedHashTree
converter-type[3] : org.apache.jmeter.save.converters.HashTreeConverter
-------------------------------
message : No field 'sentBytes' found in class 'org.apache.jmeter.samplers.SampleSaveConfiguration' : No field 'sentBytes' found in class 'org.apache.jmeter.samplers.SampleSaveConfiguration'
---- Debugging information ----
message : No field 'sentBytes' found in class 'org.apache.jmeter.samplers.SampleSaveConfiguration'
cause-exception : com.thoughtworks.xstream.converters.reflection.MissingFieldException
cause-message : No field 'sentBytes' found in class 'org.apache.jmeter.samplers.SampleSaveConfiguration'
class : org.apache.jmeter.samplers.SampleSaveConfiguration
required-type : org.apache.jmeter.samplers.SampleSaveConfiguration
converter-type : org.apache.jmeter.save.converters.SampleSaveConfigurationConverter
path : /jmeterTestPlan/hashTree/hashTree/hashTree/ResultCollector/objProp/value/sentBytes
line number : 56
class[1] : org.apache.jmeter.testelement.property.ObjectProperty
converter-type[1] : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
class[2] : org.apache.jmeter.reporters.ResultCollector
converter-type[2] : org.apache.jmeter.save.converters.TestElementConverter
class[3] : org.apache.jorphan.collections.ListedHashTree
converter-type[3] : org.apache.jmeter.save.converters.HashTreeConverter
-------------------------------
cause-exception : com.thoughtworks.xstream.converters.ConversionException
cause-message : No field 'sentBytes' found in class 'org.apache.jmeter.samplers.SampleSaveConfiguration' : No field 'sentBytes' found in class 'org.apache.jmeter.samplers.SampleSaveConfiguration'
first-jmeter-class : org.apache.jmeter.save.converters.TestElementConverter.unmarshal(TestElementConverter.java:107)
class : org.apache.jmeter.save.ScriptWrapper
required-type : org.apache.jmeter.samplers.SampleSaveConfiguration
converter-type : org.apache.jmeter.save.ScriptWrapperConverter
path : /jmeterTestPlan/hashTree/hashTree/hashTree/ResultCollector/objProp/value/sentBytes
line number : 56
version : 2.11.20151206
-------------------------------
2017/09/19 08:05:15 ERROR - jmeter.JMeter: Error in NonGUIDriver java.lang.NullPointerException
at org.apache.jmeter.gui.tree.JMeterTreeModel.addSubTree(JMeterTreeModel.java:92)
at org.apache.jmeter.JMeter.runNonGui(JMeter.java:755)
at org.apache.jmeter.JMeter.startNonGui(JMeter.java:733)
at org.apache.jmeter.JMeter.start(JMeter.java:392)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.jmeter.NewDriver.main(NewDriver.java:259)
I already tried to change project folder, google it but I'm at the end of the options. Can anybody tell me what I am doing wrong? Or where is the problem?
Thanks
Most probably you are running a test which is created using a newer JMeter version on JMeter 2.11 so my expectation is that you need to upgrade your JMeter.
Current JMeter release is JMeter 3.2.
You can always get the latest JMeter version from JMeter Downloads page.
So I would recommend switching from JMeter which you seem to be getting from your Linux distribution repositories to the binary bundle you can download directly from Apache. Just pull the tarball, unpack it somewhere and run JMeter from this folder. Make sure you're running Jmeter as ./jmeter or add it to your system PATH before the one which is from the repositories.

Turbine AMQP does not receive Hystrix stream

I had a Turbine and Hystrix setup working, but decided to change it over to Turbine AMQP so I could aggregate multiple services into one stream/dashboard.
I have set up a Turbine AMQP server running on localhost:8989, but it doesn't appear to be getting Hystrix data from the client service. When I hit the Turbine server's IP in my browser, I see data: {"type":"Ping"} repeatedly, even while I am polling the URL of the Hystrix. If I attempt to show the Turbine AMQP stream in the Hystrix Dashboard, I get: Unable to connect to Command Metric Stream.
I have a default install of RabbitMQ running on port 5672.
My client service using Hystrix-AMQP has a application.yml file that looks like so:
spring:
application:
name: policy-service
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
spring:
rabbitmq:
addresses: ${vcap.services.${PREFIX:}rabbitmq.credentials.uri:amqp://${RABBITMQ_HOST:localhost}:${RABBITMQ_PORT:5672}}
The tail end of the startup log looks like this:
2015-09-14 16:31:13.030 INFO 52844 --- [ main] com.netflix.discovery.DiscoveryClient : Starting heartbeat executor: renew interval is: 30
2015-09-14 16:31:13.047 INFO 52844 --- [ main] c.n.e.EurekaDiscoveryClientConfiguration : Registering application policy-service with eureka with status UP
2015-09-14 16:31:13.194 INFO 52844 --- [ main] o.s.i.endpoint.EventDrivenConsumer : Adding {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2015-09-14 16:31:13.195 INFO 52844 --- [ main] o.s.i.channel.PublishSubscribeChannel : Channel 'policy-service:8088.errorChannel' has 1 subscriber(s).
2015-09-14 16:31:13.195 INFO 52844 --- [ main] o.s.i.endpoint.EventDrivenConsumer : started _org.springframework.integration.errorLogger
2015-09-14 16:31:13.195 INFO 52844 --- [ main] o.s.i.endpoint.EventDrivenConsumer : Adding {filter} as a subscriber to the 'cloudBusOutboundFlow.channel#0' channel
2015-09-14 16:31:13.195 INFO 52844 --- [ main] o.s.integration.channel.DirectChannel : Channel 'policy- service:8088.cloudBusOutboundFlow.channel#0' has 1 subscriber(s).
2015-09-14 16:31:13.195 INFO 52844 --- [ main] o.s.i.endpoint.EventDrivenConsumer : started org.springframework.integration.config.ConsumerEndpointFactoryBean#0
2015-09-14 16:31:13.195 INFO 52844 --- [ main] o.s.i.endpoint.EventDrivenConsumer : Adding {filter} as a subscriber to the 'cloudBusInboundChannel' channel
2015-09-14 16:31:13.195 INFO 52844 --- [ main] o.s.integration.channel.DirectChannel : Channel 'policy-service:8088.cloudBusInboundChannel' has 1 subscriber(s).
2015-09-14 16:31:13.196 INFO 52844 --- [ main] o.s.i.endpoint.EventDrivenConsumer : started org.springframework.integration.config.ConsumerEndpointFactoryBean#1
2015-09-14 16:31:13.196 INFO 52844 --- [ main] o.s.i.endpoint.EventDrivenConsumer : Adding {message-handler} as a subscriber to the 'cloudBusInboundFlow.channel#0' channel
2015-09-14 16:31:13.196 INFO 52844 --- [ main] o.s.integration.channel.DirectChannel : Channel 'policy-service:8088.cloudBusInboundFlow.channel#0' has 1 subscriber(s).
2015-09-14 16:31:13.196 INFO 52844 --- [ main] o.s.i.endpoint.EventDrivenConsumer : started org.springframework.integration.config.ConsumerEndpointFactoryBean#2
2015-09-14 16:31:13.196 INFO 52844 --- [ main] o.s.i.endpoint.EventDrivenConsumer : Adding {logging-channel-adapter} as a subscriber to the 'cloudBusWiretapChannel' channel
2015-09-14 16:31:13.196 INFO 52844 --- [ main] o.s.integration.channel.DirectChannel : Channel 'policy-service:8088.cloudBusWiretapChannel' has 1 subscriber(s).
2015-09-14 16:31:13.197 INFO 52844 --- [ main] o.s.i.endpoint.EventDrivenConsumer : started org.springframework.integration.config.ConsumerEndpointFactoryBean#3
2015-09-14 16:31:13.197 INFO 52844 --- [ main] o.s.i.endpoint.EventDrivenConsumer : Adding {amqp:outbound-channel-adapter} as a subscriber to the 'cloudBusOutboundChannel' channel
2015-09-14 16:31:13.197 INFO 52844 --- [ main] o.s.integration.channel.DirectChannel : Channel 'policy-service:8088.cloudBusOutboundChannel' has 1 subscriber(s).
2015-09-14 16:31:13.197 INFO 52844 --- [ main] o.s.i.endpoint.EventDrivenConsumer : started org.springframework.integration.config.ConsumerEndpointFactoryBean#4
2015-09-14 16:31:13.198 INFO 52844 --- [ main] o.s.i.endpoint.EventDrivenConsumer : Adding {bridge} as a subscriber to the 'cloudBusAmqpInboundFlow.channel#0' channel
2015-09-14 16:31:13.198 INFO 52844 --- [ main] o.s.integration.channel.DirectChannel : Channel 'policy-service:8088.cloudBusAmqpInboundFlow.channel#0' has 1 subscriber(s).
2015-09-14 16:31:13.198 INFO 52844 --- [ main] o.s.i.endpoint.EventDrivenConsumer : started org.springframework.integration.config.ConsumerEndpointFactoryBean#5
2015-09-14 16:31:13.198 INFO 52844 --- [ main] o.s.i.endpoint.EventDrivenConsumer : Adding {amqp:outbound-channel-adapter} as a subscriber to the 'hystrixStream' channel
2015-09-14 16:31:13.199 INFO 52844 --- [ main] o.s.integration.channel.DirectChannel : Channel 'policy-service:8088.hystrixStream' has 1 subscriber(s).
2015-09-14 16:31:13.199 INFO 52844 --- [ main] o.s.i.endpoint.EventDrivenConsumer : started org.springframework.integration.config.ConsumerEndpointFactoryBean#6
2015-09-14 16:31:13.219 INFO 52844 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 1073741823
2015-09-14 16:31:13.219 INFO 52844 --- [ main] ApplicationEventListeningMessageProducer : started org.springframework.integration.event.inbound.ApplicationEventListeningMessageProducer#0
2015-09-14 16:31:13.555 INFO 52844 --- [cTaskExecutor-1] o.s.amqp.rabbit.core.RabbitAdmin : Auto-declaring a non-durable, auto-delete, or exclusive Queue (4640c1c8-ff8f-45d7-8426-19d1b7a4cdb0) durable:false, auto-delete:true, exclusive:true. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
2015-09-14 16:31:13.572 INFO 52844 --- [ main] o.s.i.a.i.AmqpInboundChannelAdapter : started org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter#0
2015-09-14 16:31:13.573 INFO 52844 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483647
2015-09-14 16:31:13.576 INFO 52844 --- [ main] c.n.h.c.m.e.HystrixMetricsPoller : Starting HystrixMetricsPoller
2015-09-14 16:31:13.609 INFO 52844 --- [ main] ration$HystrixMetricsPollerConfiguration : Starting poller
2015-09-14 16:31:13.803 INFO 52844 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8088 (http)
2015-09-14 16:31:13.805 INFO 52844 --- [ main] com.ml.springboot.PolicyService : Started PolicyService in 22.544 seconds (JVM running for 23.564)
So it looks like PolicyService successfully connects to the message broker.
The Turbine AMQP server's end of log:
2015-09-14 16:58:05.887 INFO 51944 --- [ main] i.reactivex.netty.server.AbstractServer : Rx server started at port: 8989
2015-09-14 16:58:05.991 INFO 51944 --- [ main] o.s.i.endpoint.EventDrivenConsumer : Adding {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2015-09-14 16:58:05.991 INFO 51944 --- [ main] o.s.i.channel.PublishSubscribeChannel : Channel 'bootstrap:-1.errorChannel' has 1 subscriber(s).
2015-09-14 16:58:05.991 INFO 51944 --- [ main] o.s.i.endpoint.EventDrivenConsumer : started _org.springframework.integration.errorLogger
2015-09-14 16:58:05.991 INFO 51944 --- [ main] o.s.i.endpoint.EventDrivenConsumer : Adding {bridge} as a subscriber to the 'hystrixStreamAggregatorInboundFlow.channel#0' channel
2015-09-14 16:58:05.991 INFO 51944 --- [ main] o.s.integration.channel.DirectChannel : Channel 'bootstrap:-1.hystrixStreamAggregatorInboundFlow.channel#0' has 1 subscriber(s).
2015-09-14 16:58:05.991 INFO 51944 --- [ main] o.s.i.endpoint.EventDrivenConsumer : started org.springframework.integration.config.ConsumerEndpointFactoryBean#0
2015-09-14 16:58:05.991 INFO 51944 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 1073741823
2015-09-14 16:58:06.238 INFO 51944 --- [cTaskExecutor-1] o.s.amqp.rabbit.core.RabbitAdmin : Auto-declaring a non-durable, auto-delete, or exclusive Queue (spring.cloud.hystrix.stream) durable:false, auto-delete:false, exclusive:false. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
2015-09-14 16:58:06.289 INFO 51944 --- [ main] o.s.i.a.i.AmqpInboundChannelAdapter : started org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter#0
2015-09-14 16:58:06.290 INFO 51944 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483647
2015-09-14 16:58:06.434 INFO 51944 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): -1 (http)
Any ideas why the Turbine AMQP server is not receiving communication from the Hystrix AMQP client?
EDIT: Turbine-AMQP main looks like:
package com.turbine.amqp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.turbine.amqp.EnableTurbineAmqp;
import org.springframework.context.annotation.Configuration;
#Configuration
#EnableAutoConfiguration
#EnableTurbineAmqp
#EnableDiscoveryClient
public class TurbineAmqpApplication {
public static void main(String[] args) {
SpringApplication.run(TurbineAmqpApplication.class, args);
}
}
Here's its application.yml:
server:
port: 8989
spring:
rabbitmq:
addresses: ${vcap.services.${PREFIX:}rabbitmq.credentials.uri:amqp://${RABBITMQ_HOST:localhost}:${RABBITMQ_PORT:5672}}
Hitting http://localhost:8989/turbine.stream produces a repeating stream of data: {"type":"Ping"}
and shows this in console:
2015-09-15 08:54:37.960 INFO 83480 --- [o-eventloop-3-1] o.s.c.n.t.amqp.TurbineAmqpConfiguration : SSE Request Received
2015-09-15 08:54:38.025 INFO 83480 --- [o-eventloop-3-1] o.s.c.n.t.amqp.TurbineAmqpConfiguration : Starting aggregation
EDIT: The below exception is thrown when I stop listening to the turbine stream, not when I try to listen with the dashboard.
2015-09-15 08:56:47.934 INFO 83480 --- [o-eventloop-3-3] o.s.c.n.t.amqp.TurbineAmqpConfiguration : SSE Request Received
2015-09-15 08:56:47.946 WARN 83480 --- [o-eventloop-3-3] io.netty.channel.DefaultChannelPipeline : An exception was thrown by a user handler's exceptionCaught() method while handling the following exception:
java.lang.NoSuchMethodError: rx.Observable.collect(Lrx/functions/Func0;Lrx/functions/Action2;)Lrx/Observable;
at com.netflix.turbine.aggregator.StreamAggregator.lambda$null$36(StreamAggregator.java:89)
at rx.internal.operators.OnSubscribeMulticastSelector.call(OnSubscribeMulticastSelector.java:60)
at rx.internal.operators.OnSubscribeMulticastSelector.call(OnSubscribeMulticastSelector.java:40)
at rx.Observable.unsafeSubscribe(Observable.java:8591)
at rx.internal.operators.OperatorMerge$MergeSubscriber.handleNewSource(OperatorMerge.java:190)
at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext(OperatorMerge.java:160)
at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext(OperatorMerge.java:96)
at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:54)
at rx.internal.operators.OperatorGroupBy$GroupBySubscriber.onNext(OperatorGroupBy.java:173)
at rx.subjects.SubjectSubscriptionManager$SubjectObserver.onNext(SubjectSubscriptionManager.java:224)
at rx.subjects.PublishSubject.onNext(PublishSubject.java:101)
at org.springframework.cloud.netflix.turbine.amqp.Aggregator.handle(Aggregator.java:53)
at sun.reflect.GeneratedMethodAccessor63.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:112)
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:102)
at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:49)
at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:342)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88)
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:131)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:330)
at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:164)
at org.springframework.integration.util.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:276)
at org.springframework.integration.util.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:142)
at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:75)
at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:71)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:99)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:277)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:239)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:95)
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:248)
at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:171)
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:119)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:105)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:277)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:239)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:95)
at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:101)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter.access$400(AmqpInboundChannelAdapter.java:45)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$1.onMessage(AmqpInboundChannelAdapter.java:93)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:756)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:679)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$001(SimpleMessageListenerContainer.java:82)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$1.invokeListener(SimpleMessageListenerContainer.java:167)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:1241)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:660)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1005)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:989)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$700(SimpleMessageListenerContainer.java:82)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1103)
at java.lang.Thread.run(Thread.java:745)
Caused by: rx.exceptions.OnErrorThrowable$OnNextValue: OnError while emitting onNext value: GroupedObservable.class
at rx.exceptions.OnErrorThrowable.addValueAsLastCause(OnErrorThrowable.java:98)
at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:56)
... 58 common frames omitted
My dependencies for turbine-amqp are as follows:
dependencies {
compile('org.springframework.cloud:spring-cloud-starter-turbine-amqp:1.0.3.RELEASE')
compile 'org.springframework.boot:spring-boot-starter-web:1.2.5.RELEASE'
compile 'org.springframework.boot:spring-boot-starter-actuator:1.2.5.RELEASE'
testCompile("org.springframework.boot:spring-boot-starter-test")
}
dependencyManagement {
imports {
mavenBom 'org.springframework.cloud:spring-cloud-starter-parent:1.0.2.RELEASE'
}
}
It is so hard to find a solution.
Using Spring cloud 2.1.4.RELEASE I faced with similar problem.
The main cause is the incompatibility [exchanges] name in rabbitMQ between:
spring-cloud-netflix-hystrix-stream and spring-cloud-starter-netflix-turbine-stream.
So solve it:
See the name created exchange name when you start the service componente {the same that declare hystrix-stream}
on the componente that declare {turbine-stream}
update the property
turbine.stream.destination=
in my case
turbine.stream.destination=hystrixStreamOutput
I faced with similar problem and I find a solution.
My Spring Cloud version is 2.1.0.RELEASE
The solution:
add property
spring.cloud.stream.bindings.turbineStreamInput.destination: hystrixStreamOutput
turbine.stream.enabled: false
add auto configuration
#EnableBinding(TurbineStreamClient.class)
public class TurbineStreamAutoConfiguration {
#Autowired
private BindingServiceProperties bindings;
#Autowired
private TurbineStreamProperties properties;
#PostConstruct
public void init() {
BindingProperties inputBinding = this.bindings.getBindings()
.get(TurbineStreamClient.INPUT);
if (inputBinding == null) {
this.bindings.getBindings().put(TurbineStreamClient.INPUT,
new BindingProperties());
}
BindingProperties input = this.bindings.getBindings()
.get(TurbineStreamClient.INPUT);
if (input.getDestination() == null) {
input.setDestination(this.properties.getDestination());
}
if (input.getContentType() == null) {
input.setContentType(this.properties.getContentType());
}
}
#Bean
public HystrixStreamAggregator hystrixStreamAggregator(ObjectMapper mapper,
PublishSubject<Map<String, Object>> publisher) {
return new HystrixStreamAggregator(mapper, publisher);
}
}