RestTemplate遇上Hystrix

作者: 铁汤 | 来源:发表于2016-09-11 23:21 被阅读443次

    RestTemplate集成Hystrix和Robbin

    查看RestTemplate源代码,可以看到RestTemplate继承了InterceptingHttpAccessor类,InterceptingHttpAccessor类通过ClientHttpRequestInterceptor接口提供了扩展功能。

    实现intercept方法,在该方法中封装HystrixCommand和Ribbon逻辑即可。

    下面的代码是集成了HystrixCommand的例子:

    @Override
        public ClientHttpResponse intercept(
                final HttpRequest request, final byte[] body,
                final ClientHttpRequestExecution execution) throws IOException {
            final URI originalUri = request.getURI();
            String serviceName = mapCommandKey(originalUri);
    
            log.info("{} :{} {} ", serviceName, request.getMethod().name(), originalUri.toString());
            return new RestTemplateHystrixCommnad(serviceName, () -> {
                return execution.execute(request, body);
            }, hystrixFallback).execute();
    
        }
    

    下面是集成了HystrixCommand和Ribbon的例子

    @Override
        public ClientHttpResponse intercept(
                final HttpRequest request, final byte[] body,
                final ClientHttpRequestExecution execution) throws IOException {
            final URI originalUri = request.getURI();
            String serviceName = mapCommandKey(originalUri);
    
            log.info("{} :{} {} ", serviceName, request.getMethod().name(), originalUri.toString());
            return new RestTemplateHystrixCommnad(serviceName, () -> {
                return this.loadBalancer.execute(serviceName, instance -> {
                    HttpRequest serviceRequest = new HystrixLoadBalancerInterceptor.ServiceRequestWrapper(
                            request,
                            instance);
                    return execution.execute(serviceRequest, body);
    
                });
            }, hystrixFallback).execute();
        }
    

    2)RestTemplate支持Hystrix异步特性

    Hystrix的执行在线程隔离模型下是支持异步的,因此也扩展一个RestTemplate异步执行。如下代码所示,通过调用queue()方法返回一个Future。

    Future<String> fs = new CommandHelloWorld("World").queue();
    String s = fs.get(); 
    

    这样可以修改RestOperations接口方法为异步方法:

    从:

    <T>  T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException;
    

    到:

    <T> Future<T> getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException;
    

    然后在原生的RestTemplate做一层代理,在代理层集成Hystrix和Ribbon,无论是JDK动态代理还是硬编码实现代理都变得容易,然后就可以这样来调用了:

    HystrixAsyncRestOperations asyncRestTemplate =null;
    //先依次调用
    Future<String> future1 = asyncRestTemplate.getForObject("http://tietang.wang/", String.class);
    Future<String> future2 = asyncRestTemplate.getForObject("http://tietang.wang/2016/03/17/hystrix/%E6%80%8E%E6%A0%B7%E4%BD%BF%E7%94%A8Hystrix/", String.class);
    //再依次获取调用结果
    String html1 = future1.get();
    String html2 = future2.get(100, TimeUnit.MILLISECONDS);//异步超时,建议
    

    相关文章

      网友评论

      • 董运琪邦利德网络科技:RestTemplateHystrixCommnad,这个是自定义的类吗?
        铁汤:@董运琪邦利德网络科技 是的
      • 6dd8f0a35472:非常期待您的回复
      • 6dd8f0a35472:如果我想封装自定义的通信协议,而不用http协议,但是想要集成hystrix和ribbon应该怎么做?
        铁汤:@吸烟两包半
        https://github.com/netflix/ribbon
        https://github.com/Netflix/Hystrix/wiki/How-To-Use
        参考:
        IRule rule = new AvailabilityFilteringRule();
        ServerList<DiscoveryEnabledServer> list = new DiscoveryEnabledNIWSServerList("MyVIP:7001");
        ServerListFilter<DiscoveryEnabledServer> filter = new ZoneAffinityServerListFilter<DiscoveryEnabledServer>();
        ZoneAwareLoadBalancer<DiscoveryEnabledServer> lb = LoadBalancerBuilder.<DiscoveryEnabledServer>newBuilder()
        .withDynamicServerList(list)
        .withRule(rule)
        .withServerListFilter(filter)
        .buildDynamicServerListLoadBalancer();
        DiscoveryEnabledServer server = lb.chooseServer();

      本文标题:RestTemplate遇上Hystrix

      本文链接:https://www.haomeiwen.com/subject/ksfpettx.html