Spring Cloud - HystrixCommand - 如何正确启用共享库

Spring Cloud - HystrixCommand - How to properly enable with shared libraries

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

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

从下面看,WebService 位于一个库中,该库具有指向主应用程序的独立包路径。同时 MyWebService 位于与 Springboot 应用程序相同的上下文路径中的应用程序中。 MyWebService 也可以正常运行,没有问题。这仅与 HystrixCommand 注释在 Spring 基于引导的配置方面的可见性有关。

在运行时,我注意到当像下面这样的代码运行时,我确实在响应中看到 "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);
    }

}

mainCall() 调用 otherCommandMethod() 时出现问题。不能从同一个 class 中调用带有 @HystrixCommand 的方法。

问题的答案中所述,这是 Spring 的 AOP 的限制。