我正在使用Spring Webflux通过Schedulers.elastic()从另一服务调用一项服务
Mono<Integer> anaNotificationCountObservable = wrapWithRetryForFlux(wrapWithTimeoutForFlux(
notificationServiceMediatorFlux.getANANotificationCountForUser(userId).subscribeOn(reactor.core.scheduler.Schedulers.elastic())
)).onErrorReturn(0);
在主线程中,我设置了一个InhertitableThreadLocal变量,在子线程中,我试图访问它,并且工作正常。
这是我用于存储threadlocal的类
@Component
public class RequestCorrelation {
public static final String CORRELATION_ID = "correlation-id";
private InheritableThreadLocal<String> id = new InheritableThreadLocal<>();
public String getId() {
return id.get();
}
public void setId(final String correlationId) {
id.set(correlationId);
}
public void removeCorrelationId() {
id.remove();
}
}
现在问题是第一次正常运行,这意味着我在threadlocal中设置的值将传递给其他服务。
但这也是第二次,它使用的是旧ID(在上次请求中生成)。
我尝试使用Schedulers.newSingle()而不是elastic(),但它可以正常工作。 因此,请考虑一下,因为elastic()正在重用线程,所以这就是为什么它无法清除/或正在重用的原因。
我应该如何解决问题。 我在过滤器中设置了本地线程,并在myfiler中清除了该线程
requestCorrelation.setId(UUID.randomUUID().toString());
chain.doFilter(req,res)
requestCorrelation.removeCorrelationId();
答案 0 :(得分:1)
在利用反应堆管道时,切勿将资源或信息绑定到特定线程。 Reactor本身与时间表无关;使用您的库的开发人员可以选择在另一个调度程序上调度工作-如果您决定强制执行调度模型,则可能会失去性能优势。
相反,您可以将数据存储在reactor context内。这是一种类似于地图的结构,与订户相关,并且与计划安排无关。
这是诸如spring security和micrometer之类的项目存储通常属于threadlocal的信息的方式。