【发布时间】:2018-04-26 10:05:44
【问题描述】:
我们在服务中为我们的客户使用 Feign。最近其中一项服务开始随机抛出一些异常,这是由以下原因引起的:
Caused by: java.lang.NullPointerException: null
at org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:63)
at org.springframework.cloud.sleuth.instrument.web.client.feign.TraceLoadBalancerFeignClient.execute(TraceLoadBalancerFeignClient.java:41)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:97)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)
at feign.hystrix.HystrixInvocationHandler$1.run(HystrixInvocationHandler.java:108)
at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:301)
at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:297)
at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46)
at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:51)
at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)
at com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction$1.call(HystrixContexSchedulerAction.java:56)
at com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction$1.call(HystrixContexSchedulerAction.java:47)
at our.code.hystrix.AuthContextAwareHystrixConcurrencyStrategy$AuthorizationContextAwareCallable.call(AuthContextAwareHystrixConcurrencyStrategy.java:57)
at org.springframework.cloud.sleuth.instrument.hystrix.SleuthHystrixConcurrencyStrategy$HystrixTraceCallable.call(SleuthHystrixConcurrencyStrategy.java:154)
at com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction.call(HystrixContexSchedulerAction.java:69)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
我查看了 spring-cloud-netflix-core (v1.2.2.RELEASE) 代码及其依赖项,但无法弄清楚 NPE 发生的原因。
在堆栈跟踪中,它指向LoadBalancerFeignClient 中的第 63 行,即:
private CachingSpringLoadBalancerFactory lbClientFactory;
@Override
public Response execute(Request request, Request.Options options) throws IOException {
try {
URI asUri = URI.create(request.url());
String clientName = asUri.getHost();
URI uriWithoutHost = cleanUrl(request.url(), clientName);
FeignLoadBalancer.RibbonRequest ribbonRequest = new FeignLoadBalancer.RibbonRequest(
this.delegate, request, uriWithoutHost);
IClientConfig requestConfig = getClientConfig(options, clientName);
return lbClient(clientName).executeWithLoadBalancer(ribbonRequest, // Line 63
requestConfig).toResponse();
}
catch (ClientException e) {
IOException io = findIOException(e);
if (io != null) {
throw io;
}
throw new RuntimeException(e);
}
}
private FeignLoadBalancer lbClient(String clientName) {
return this.lbClientFactory.create(clientName);
}
这意味着只有lbClient(clientName) 是返回null 的唯一可能位置。查看CachingSpringLoadBalancerFactory 类及其实现,我在ConcurrentReferenceHashMap 的文档中发现了这一点:
注意:引用的使用意味着不能保证放置到地图中的项目随后将可用。垃圾收集器可能随时丢弃引用,因此可能会出现未知线程正在默默地删除条目。
现在我的问题是它为什么会发生以及如何解决它。谢谢。
【问题讨论】:
-
1.2.2.RELEASE 已经快一年了。我会要求您尝试使用来自 Dalston.SR4 的 1.3.5
-
这是未来的计划,但现在我需要修复它:)
-
1.2.2 不受支持,Camden 列车中的最新版本是 SR7,即 1.2.7.RELEASE。让我知道你什么时候可以尝试更新的东西。
标签: spring spring-cloud spring-cloud-netflix spring-cloud-feign