Java 反应堆代码中的奇怪拒绝执行异常

Java 反应堆代码中的奇怪拒绝执行异常,java,spring,reactive-programming,project-reactor,Java,Spring,Reactive Programming,Project Reactor,我有一个关于这个奇怪的例外的问题 return reactionRepository .getPage(context, scanQuery) .buffer(100) .concatMap(Flux::fromIterable) .flatMapSequential(likeSn -> findOne(context, parentId, likeSn) .transform(Reactive

我有一个关于这个奇怪的例外的问题

return reactionRepository
        .getPage(context, scanQuery)
        .buffer(100)
        .concatMap(Flux::fromIterable)
        .flatMapSequential(likeSn -> findOne(context, parentId, likeSn)
                .transform(ReactiveHelpers.defaultIfNotFoundOrError(Optional.empty())))
        .filter(Optional::isPresent)
        .map(Optional::get)
        .doOnError(e -> log.error("Failed to find likes", e));
ExecutorTrackedRunnable r = new ExecutorTrackedRunnable(task, this, true);
        if (!tasks.add(r)) {
            throw Exceptions.failWithRejected();
        }
我在生产中收到了一些被拒绝的ExecutionException(大约每天200个)。 Reactor使用scheduler.fromExecutorService()在自定义计划程序上运行

因此,我首先检查了队列大小或
ExcutorService
的任何内容,但一切正常。没有满队。没有关机

这是引发异常的代码

return reactionRepository
        .getPage(context, scanQuery)
        .buffer(100)
        .concatMap(Flux::fromIterable)
        .flatMapSequential(likeSn -> findOne(context, parentId, likeSn)
                .transform(ReactiveHelpers.defaultIfNotFoundOrError(Optional.empty())))
        .filter(Optional::isPresent)
        .map(Optional::get)
        .doOnError(e -> log.error("Failed to find likes", e));
ExecutorTrackedRunnable r = new ExecutorTrackedRunnable(task, this, true);
        if (!tasks.add(r)) {
            throw Exceptions.failWithRejected();
        }
getPage()返回Flux对象。以下代码是从Redis集群读取信息的主要代码

...
return bucketList.publishOn(redisScheduler)
                   .filter(val -> val.getScore() >= 0)
                   .map(Value::getValue)
这是我在日志文件中得到的异常日志。此错误日志是在上面的
.doError(e->log.error(“未能找到喜欢的对象”,e))中编写的

reactor.core.Exceptions$ReactorRejectedExecutionException: Scheduler unavailable
    at reactor.core.Exceptions.failWithRejected(Exceptions.java:249)
    at reactor.core.publisher.Operators.onRejectedExecution(Operators.java:412)
    at reactor.core.publisher.FluxPublishOn$PublishOnSubscriber.trySchedule(FluxPublishOn.java:293)
    at reactor.core.publisher.FluxPublishOn$PublishOnSubscriber.request(FluxPublishOn.java:261)
    at reactor.core.publisher.FluxBuffer$BufferExactSubscriber.request(FluxBuffer.java:111)
    at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onSubscribe(FluxConcatMap.java:227)
    at reactor.core.publisher.FluxBuffer$BufferExactSubscriber.onSubscribe(FluxBuffer.java:125)
    at reactor.core.publisher.FluxPublishOn$PublishOnSubscriber.onSubscribe(FluxPublishOn.java:209)
    at reactor.core.publisher.FluxConcatArray.subscribe(FluxConcatArray.java:78)
    at reactor.core.publisher.FluxPublishOn.subscribe(FluxPublishOn.java:108)
    at reactor.core.publisher.FluxBuffer.subscribe(FluxBuffer.java:72)
    at reactor.core.publisher.FluxConcatMap.subscribe(FluxConcatMap.java:121)
    at reactor.core.publisher.Flux.subscribe(Flux.java:6877)
    at reactor.core.publisher.FluxMergeSequential.subscribe(FluxMergeSequential.java:99)
    at reactor.core.publisher.FluxFilter.subscribe(FluxFilter.java:52)
    at reactor.core.publisher.FluxMap.subscribe(FluxMap.java:62)
    at reactor.core.publisher.FluxPeek.subscribe(FluxPeek.java:83)
    at reactor.core.publisher.MonoCollectList.subscribe(MonoCollectList.java:59)
    at reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:59)
    at reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)
    at reactor.core.publisher.Mono.subscribe(Mono.java:3080)
    at reactor.core.publisher.MonoZip.subscribe(MonoZip.java:128)
    at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60)
    at reactor.core.publisher.Mono.subscribe(Mono.java:3080)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.onNext(FluxFlatMap.java:372)
    at reactor.core.publisher.FluxGroupBy$UnicastGroupedFlux.drainRegular(FluxGroupBy.java:554)
    at reactor.core.publisher.FluxGroupBy$UnicastGroupedFlux.drain(FluxGroupBy.java:630)
    at reactor.core.publisher.FluxGroupBy$UnicastGroupedFlux.subscribe(FluxGroupBy.java:696)
    at reactor.core.publisher.FluxFlatMap.subscribe(FluxFlatMap.java:97)
    at reactor.core.publisher.Flux.subscribe(Flux.java:6877)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.onNext(FluxFlatMap.java:372)
    at reactor.core.publisher.FluxGroupBy$GroupByMain.drainLoop(FluxGroupBy.java:380)
    at reactor.core.publisher.FluxGroupBy$GroupByMain.drain(FluxGroupBy.java:316)
    at reactor.core.publisher.FluxGroupBy$GroupByMain.onNext(FluxGroupBy.java:201)
    at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:244)
    at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:202)
    at reactor.core.publisher.FluxGroupBy$GroupByMain.onSubscribe(FluxGroupBy.java:165)
    at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:140)
    at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:64)
    at reactor.core.publisher.FluxGroupBy.subscribe(FluxGroupBy.java:82)
    at reactor.core.publisher.FluxFlatMap.subscribe(FluxFlatMap.java:97)
    at reactor.core.publisher.MonoCollect.subscribe(MonoCollect.java:66)
    at reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:59)
    at reactor.core.publisher.MonoOnAssembly.subscribe(MonoOnAssembly.java:76)
    at reactor.core.publisher.Mono.subscribe(Mono.java:3080)
    at reactor.core.publisher.MonoSubscribeOn$SubscribeOnSubscriber.run(MonoSubscribeOn.java:123)
    at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:84)
    at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:37)
    at io.micrometer.core.instrument.AbstractTimer.recordCallable(AbstractTimer.java:143)
    at io.micrometer.core.instrument.Timer.lambda$wrap$1(Timer.java:137)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.util.concurrent.RejectedExecutionException: Scheduler unavailable
    at reactor.core.Exceptions.<clinit>(Exceptions.java:502)
    at reactor.core.publisher.Operators.onOperatorError(Operators.java:345)
    at reactor.core.publisher.Operators.onOperatorError(Operators.java:323)
    at reactor.core.publisher.Operators.onOperatorError(Operators.java:305)
    at reactor.core.publisher.MonoError.subscribe(MonoError.java:53)
    at reactor.core.publisher.Mono.subscribe(Mono.java:3080)
    at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:75)
    at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:78)
    at reactor.core.publisher.Operators.complete(Operators.java:128)
    at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:45)
    at reactor.core.publisher.Mono.subscribe(Mono.java:3080)
这是我现在才知道的线索

有人知道这个问题吗?任何建议都可以帮助我

编辑1。添加提到的代码。这是处理自定义异常的帮助程序代码

public static <T> Function<Mono<T>, Publisher<T>> defaultIfNotFoundOrError(T defaultValue) {
    return source -> source.onErrorResume(ReactionStorageException.class,
                                          e -> {
                                              if (e.getErrorCode() == ReactionStorageErrorCode.NOT_FOUND) {
                                                   return Mono.just(defaultValue);
                                              } else {
                                                   return Mono.error(e);
                                              }
                                          });
}
公共静态函数defaultIfNotFoundOrError(T defaultValue){
返回source->source.onErrorResume(ReactionStorageException.class,
e->{
如果(如getErrorCode()==未找到反应存储错误代码){
返回Mono.just(defaultValue);
}否则{
返回单声道错误(e);
}
});
}
和芬顿()

public Mono findOne(最终请求者上下文),
最后一个字符串parentId,
最终int序列号,
最终布尔型手柄(有故障){
前提条件.checkArgument(!Strings.isNullOrEmpty(parentId),
“parentId不能为空值”);
前提条件.checkArgument(sn>=StorageConstants.BASE\u sn,
“序列号必须大于基本值”);
最后一个字符串,如INFOKEY=RedisKeys.reactionInfo(reactionType,parentId,sn);
return cmds.hgetall(像info键)
.publishOn(重新调度)
.flatMap(m->Mono.justOrEmpty(如从(m))中删除映射器)
.switchIfEmpty(反应帮助程序).MaporeEmpty(手动故障,
requestFaultedLike(上下文、父ID、序号)))
.switchIfEmpty(例外直到生成(未找到ReactionStorageErrorCode,
“找不到Like(%s,%d)”,
parentId,sn))
.map(可选::of nullable)
.doon错误(e->log.trace(“未能找到类似的”,e));
}

更新2。深入调试后,由于源已取消,引发了异常。此取消是由Mono.zip(A、B、C…)引起的。上面的源是B。如果A是空源,则应取消B。但偶尔B请求在收到取消信号后正在处理。

您能指定
反应堆的确切版本吗?这有助于通过堆栈跟踪搜索源。@OlegKurbatov我使用3.1.8版本,因此
返回Mono.error(e)。调试此位置以了解发生了哪些异常,或者按照我的建议重写整个过程,以便一次处理所有异常。此逻辑在大多数情况下运行良好,包括我的单元测试中的异常情况。在dev环境中,我找不到任何类似上述的异常。若错误能以优雅的方式解决,你们的建议并没有问题。但是我想知道
拒绝执行异常的真正原因。我偶尔会遇到异常,参数几乎相同。我很好奇为什么会出现这种异常。在丢弃之前,您总是可以记录它。