【问题标题】:Spring Cloud - HystrixCommand - How to properly enable with shared librariesSpring Cloud - HystrixCommand - 如何正确启用共享库
【发布时间】:2018-07-30 03:09:00
【问题描述】:

使用 Springboot 1.5.x、Spring Cloud 和 JAX-RS:

我可以使用第二双眼睛,因为我不清楚 Spring 配置是否适用于所有用例,Javanica HystrixCommand 是否适用于所有用例,或者我的代码是否可能有错误。下面是我正在做的一个近似值,下面的代码实际上不会编译。

从下面开始,WebService 位于一个库中,主应用程序具有单独的包路径。同时 MyWebService 存在于与 Springboot 应用程序在同一上下文路径中的应用程序中。 MyWebService 也可以正常工作,那里没有问题。这只是与 HystrixCommand 注释在基于 Springboot 的配置方面的可见性有关。

在运行时,我注意到当像下面这样的代码运行时,我在响应中看到“commandKey=A”。这是我没想到的,因为它在获取数据时仍在运行。由于我们记录了 HystrixRequestLog,因此我还在日志中看到了这个命令键。

但所有其他命令键根本不可见,无论我将它们放在文件中的什么位置。如果我删除 CommandKey-A 则没有任何命令可见。

想法?

// Example WebService that we use as a shared component for performing a backend call that is the same across different resources


@RequiredArgsConstructor
@Accessors(fluent = true)
@Setter
public abstract class WebService {

    private final @Nonnull Supplier<X> backendFactory;
    
    @Setter(AccessLevel.PACKAGE)
    private @Nonnull Supplier<BackendComponent> backendComponentSupplier = () -> new BackendComponent();
    
    
    @GET
    @Produces("application/json")
    @HystrixCommand(commandKey="A")
    public Response mainCall() {

        Object obj = new Object();
        
        try {
            otherCommandMethod();
        } catch (Exception commandException) {
            // do nothing (for this example)
        }
        
        // get the hystrix request information so that we can determine what was executed
        
        Optional<Collection<HystrixInvokableInfo<?>>> executedCommands = hystrixExecutedCommands();

        // set the hystrix data, viewable in the response
        obj.setData("hystrix", executedCommands.orElse(Collections.emptyList()));

        if(hasError(obj)) {
            return Response.serverError()
                        .entity(obj)
                        .build();
        }
        return Response.ok()
                .entity(healthObject)
                .build();
        
    }

    @HystrixCommand(commandKey="B")
    private void otherCommandMethod() {
        backendComponentSupplier
                .get()
                .observe()
                .toBlocking()
                .subscribe();
    }

    Optional<Collection<HystrixInvokableInfo<?>>> hystrixExecutedCommands() {
        Optional<HystrixRequestLog> hystrixRequest = Optional
                .ofNullable(HystrixRequestLog.getCurrentRequest());

        // get the hystrix executed commands
        Optional<Collection<HystrixInvokableInfo<?>>> executedCommands = Optional.empty();
        if (hystrixRequest.isPresent()) {
            executedCommands = Optional.of(hystrixRequest.get()
                    .getAllExecutedCommands());
        }
        return executedCommands;
    }
    
    
    @Setter
    @RequiredArgsConstructor
    public class BackendComponent implements ObservableCommand<Void> {
    
        @Override
        @HystrixCommand(commandKey="Y")
        public Observable<Void> observe() {
             // make some backend call
            return backendFactory.get()
                    .observe();
        }
        
    }

}


// then later this component gets configured in the specific applications with sample configuraiton that looks like this:

@SuppressWarnings({ "unchecked", "rawtypes" })
@Path("resource/somepath")
@Component
public class MyWebService extends WebService {

    @Inject
    public MyWebService(Supplier<X> backendSupplier) {
        super((Supplier)backendSupplier);
    }

}

【问题讨论】:

    标签: spring-boot jax-rs spring-cloud hystrix


    【解决方案1】:

    mainCall() 调用 otherCommandMethod() 存在问题。不能在同一个类中调用带有 @HystrixCommand 的方法。

    正如this 问题的答案中所讨论的,这是 Spring 的 AOP 的一个限制。

    【讨论】:

      猜你喜欢
      • 2016-10-19
      • 1970-01-01
      • 2014-01-09
      • 2018-05-30
      • 2019-07-31
      • 2015-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多