javanica中的Hystrix异步方法没有在spring-boot java应用程序中运行

时间:2014-10-14 23:52:58

标签: java spring-cloud hystrix

我正在使用spring-cloud-starter(即具有所有微服务功能的spring boot)。当我在使用javanica @HystrixCommand注释的组件中创建hystrix方法时,请按照javanica github网站(https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica)上的说明使该方法运行异步,无论我是否使用他们的'Future<>'或反应执行'Observable<>',没有任何运行/执行,我得到了 java.lang.ClassCastException: springbootdemo.EricComponent$1 cannot be cast to springbootdemo.Eric每当我尝试提取结果时(在Future<>的情况下)或获得回调(在Reactive Execution的情况下......并且println不会触发,所以它确实没有运行)。

public class Application { ...
}
@RestController
@RequestMapping(value = "/makebunchofcalls/{num}")
class EricController { ..

    @RequestMapping(method={RequestMethod.POST})
    ArrayList<Eric> doCalls(@PathVariable Integer num) throws IOException {
        ArrayList<Eric> ale = new ArrayList<Eric>(num);
        for (int i =0; i<num; i++) {
            rx.Observable<Eric> oe = this.ericComponent.doRestTemplateCallAsync(i);
            oe.subscribe(new Action1<Eric>() {
                @Override
                public void call(Eric e) {  // AT RUNTIME, ClassCastException
                    ale.add(e);
                }
            });
        }

        return ale;
    }

@Component
class EricComponent { ...

    // async version =========== using reactive execution via rx library from netflix ==============

    @HystrixCommand(fallbackMethod = "defaultRestTemplateCallAsync", commandKey = "dogeAsync")
    public rx.Observable<Eric> doRestTemplateCallAsync(int callNum) {
        return new ObservableResult<Eric>() {
            @Override
            public Eric invoke() {  // NEVER CALLED
                try {
                    ResponseEntity<String> result = restTemplate.getForEntity("http://doges/doges/24232/photos", String.class);  // actually make a call
                    System.out.println("*************** call successfull: " + new Integer(callNum).toString() + " *************");
                } catch (Exception ex) {
                    System.out.println("=============== call " + new Integer(callNum).toString() + " not successfull: " + ex.getMessage() + " =============");
                }
                return new Eric(new Integer(callNum).toString(), "ok");
            }
        };
    }

    public rx.Observable<Eric> defaultRestTemplateCallAsync(int callNum) {
        return new ObservableResult<Eric>() {
            @Override
            public Eric invoke() {
                System.out.println("!!!!!!!!!!!!! call bombed " + new Integer(callNum).toString() + "!!!!!!!!!!!!!");
                return new Eric(new Integer(callNum).toString(), "bomb");
            }
        };
    }
}

为什么我要取回EricComponent$1而不是Eric?顺便说一句,Eric只是一个带有2个字符串的简单类......它被省略了。

我认为我必须明确执行,但这包括我,因为:1)使用Future&lt;&gt;进行操作queue()方法不可用,因为文档声明和2)使用Observable&lt;&gt;我真的没有办法执行它。

1 个答案:

答案 0 :(得分:4)

您的应用程序类是否有@EnableHystrix注释?

subscribe方法是异步的,您尝试在同步控制器方法中填充列表,因此可能存在问题。您是否可以将subscribe更改为toBlockingObservable().forEach()并查看是否有帮助?

更新#1 我能够复制。您的默认方法不应返回Observable<Eric>,只需返回Eric

public Eric defaultRestTemplateCallAsync(final int callNum) {
    System.out.println("!!!!!!!!!!!!! call bombed " + new Integer(callNum) + "!!!!!!!!!!!!!");
    return new Eric(new Integer(callNum).toString(), "bomb");
}

更新#2 请在此处查看我的代码https://github.com/spencergibb/communityanswers/tree/so26372319

更新#3 当我注释掉fallbackMethod属性时,它抱怨它无法为AOP找到EricComponent的公开版本。我制作了EricComponent public static并且它有效。它自己的文件中的顶级类可以工作。上面链接的我的代码有效(假设restTemplate调用有效)并返回n OK