【问题标题】:NullPointerException in LoadBalancerFeignClient (spring-cloud-netflix)LoadBalancerFeignClient (spring-cloud-netflix) 中的 NullPointerException
【发布时间】: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


【解决方案1】:

作为记录,这是 GitHub 上的问题: https://github.com/spring-cloud/spring-cloud-netflix/issues/2443 虽然在新版本中已修复。

【讨论】:

猜你喜欢
  • 2016-03-31
  • 2017-07-08
  • 2017-07-21
  • 2017-07-15
  • 1970-01-01
  • 2016-10-07
  • 2020-04-15
  • 2016-04-27
  • 2015-04-04
相关资源
最近更新 更多