zoukankan      html  css  js  c++  java
  • org.springframework.web.client.RestTemplate设置访问超时 || @HystrixCommand注解设置超时

     原文:https://www.cnblogs.com/shamo89/p/8177182.html

     

    (一)RestTemplate 客户端

    1、RestTemplate 是Spring的封装,需要spring的包 spring-web-3.0.7.RELEASE.jar

    2、客户端代码:

    复制代码
     1 /** 
     2  * RestTemplate 客户端访问 
     3  */  
     4 private void RestTemplateVisit() {  
     5     String returnXml = ""; // 核心返回结果报文字符串  
     6   
     7     try {  
     8   
     9         //复杂构造函数的使用  
    10         SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();  
    11         requestFactory.setConnectTimeout(1000);// 设置超时  
    12         requestFactory.setReadTimeout(1000);  
    13   
    14         //利用复杂构造器可以实现超时设置,内部实际实现为 HttpClient  
    15         RestTemplate restTemplate = new RestTemplate(requestFactory);  
    16   
    17         //设置HTTP请求头信息,实现编码等  
    18         HttpHeaders requestHeaders = new HttpHeaders();  
    19         // requestHeaders.set("Accept", "text/");  
    20         requestHeaders.set("Accept-Charset", "utf-8");  
    21         requestHeaders.set("Content-type", "text/xml; charset=utf-8");// 设置编码  
    22   
    23         //利用容器实现数据封装,发送  
    24         HttpEntity<String> entity = new HttpEntity<String>(mRequestXml, requestHeaders);  
    25         returnXml = restTemplate.postForObject(mUrl, entity, String.class);  
    26   
    27         // 转码原因:RestTemplate默认是使用org.springframework.http.converter.StringHttpMessageConverter来解析  
    28         // StringHttpMessageConverter 默认用的 ISO-8859-1来编码的  
    29         returnXml = new String(returnXml.getBytes("ISO-8859-1"), "utf-8");  
    30   
    31     } catch (UnsupportedEncodingException e) {  
    32         e.printStackTrace();  
    33     }  
    34   
    35     System.out.println("restTemplate客户端访问返回: 
    " + returnXml);  
    36 }  
    复制代码

    (二)RestTemplate 详解

    1、两个构造方法:第二个实现超时。

    复制代码
    public RestTemplate() {  
              /** 
                   ...初始化过程 
              */  
    }  
       
    //实现超时  
    public RestTemplate(ClientHttpRequestFactory requestFactory) {  
         this();  
         setRequestFactory(requestFactory);  
    }  
    复制代码

    其中,第二个构造方法中可以传入ClientHttpRequestFactory参数,第一个进行默认初始化,因为我们经常需要对请求超时进行设置并能够对超时进行后续处理,而第一个构造方法,我们无法控制超时时间,第二个构造中的ClientHttpRequestFactory接口的实现类中存在timeout属性,因此选用第二个构造方法。

    1 SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();  
    2 requestFactory.setConnectTimeout(1000);  
    3 requestFactory.setReadTimeout(1000);  
    4   
    5 RestTemplate restTemplate = new RestTemplate(requestFactory);  

    Hystrix 超时配置的N种玩法

     

    前阵子在我的知识星球中,有位朋友对我提了个问题,问我如何让Hystrix支持对接口级别的超时配置,今天给大家写篇文章,普及下Hystrix配置超时的几种方式。

    至于以后你是用阿里的Sentinel还是Netflix Hystrix我就不管了,但今天的主题还是Netflix Hystrix,至少目前还是有很多在使用的,所以今天这篇文章还是看看吧。

    @HystrixCommand

    如果我们使用的是@HystrixCommand注解,那么可以在注解中直接指定超时时间,如下:

    @HystrixCommand(fallbackMethod="fallback",
    	commandProperties = {
    	     @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000" )
    	}
    )
    
    

    当然也可以指定commandKey,然后在配置文件中配置超时时间,如下:

    @HystrixCommand(fallbackMethod="fallback",commandKey="userGetKey")
    

    配置文件给commandKey配置超时时间:

    hystrix.command.userGetKey.execution.isolation.thread.timeoutInMilliseconds = 13000
    

    全局配置

    如果只是想全局的配置,可以配置默认的超时时间:

    hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000
    

    接口级别配置

    假如我们的Feign Client定义如下:

    @FeignClient(value = "user-service", fallbackFactory = UserRemoteClientFallbackFactory.class)
    public interface UserRemoteClient {
    	
    	@GetMapping("/user/get")
    	public ResponseData<UserDto> getUser(@RequestParam("id") Long id);
    	
    }
    

    那么配置如下:

    hystrix.command.UserRemoteClient#getUser(Long).execution.isolation.thread.timeoutInMilliseconds = 300
    

    为什么要配置成上面的方式呢?

    其实就是对commandKey进行配置,只要我们知道commandKey的生成规则就可以对接口级别进行配置,接口级别的规则是 Client名称#方法名(参数类型)

    源码在feign.hystrix.SetterFactory.Default中:

    String commandKey = Feign.configKey(target.type(), method);
    

    服务级别配置

    1.在Zuul中针对服务级别的话,直接配置service-id,如下:
    hystrix.command.service-id.execution.isolation.thread.timeoutInMilliseconds=3000
    

    Zuul中之所以要配置service-id原因是commandKey就是用的service-id, 通过源码分析可以得到结论。

    首先进入的是RibbonRoutingFilter中的run方法,然后我们看核心的forward方法:

    ClientHttpResponse response = forward(commandContext);
    

    在forward中有下面的代码:

    RibbonCommand command = this.ribbonCommandFactory.create(context);
    

    通过create可以定位到具体的实现,这边就看你用的什么Http客户端,默认有三种实现,默认定位到org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactory.create(RibbonCommandContext)方法。

    重点在new HttpClientRibbonCommand这行代码,第一个参数就是serviceId,我们看下HttpClientRibbonCommand构造函数的完整参数:

    所以service-id就是commandKey。

    2.在Feign中针对服务级别的话,需要对commandKey进行定制,可以用service-id, 也可以用Feign Client Name,如下:
    @Bean
    @Scope("prototype")
    @ConditionalOnMissingBean
    @ConditionalOnProperty(name = "feign.hystrix.enabled")
    public Feign.Builder feignHystrixBuilder() {
    	return HystrixFeign.builder().setterFactory(new SetterFactory() {
    
    		@Override
    		public Setter create(Target<?> target, Method method) {
    			String groupKey = target.name();
    			String commandKey = Feign.configKey(target.type(), method);
    			return HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
    						//.andCommandKey(HystrixCommandKey.Factory.asKey(commandKey))
    						//.andCommandKey(HystrixCommandKey.Factory.asKey(groupKey))
    						.andCommandKey(HystrixCommandKey.Factory.asKey(target.type().getSimpleName()));
    			}
    	});
    }
    
    • .andCommandKey(HystrixCommandKey.Factory.asKey(commandKey))
      默认的接口方式

    • .andCommandKey(HystrixCommandKey.Factory.asKey(groupKey))
      service-id方式

    • .andCommandKey(HystrixCommandKey.Factory.asKey(target.type().getSimpleName()));
      Feign Client Name方式

    配置的话根据不同的配置填写不通的commandKey就可以了:

    hystrix.command.Feign Client Name.execution.isolation.thread.timeoutInMilliseconds=3000
    

    摘自: https://www.jianshu.com/p/3c98580759aa

  • 相关阅读:
    react native android9 axios network error
    .NET Core3.1升级.NET5 oracle连接报错
    asp.net mvc api swagger 配置
    ASP.NET Core3.1 中使用MongoDB基本操作
    基于.NET Core3.1的SQLiteHelper增删改帮助类
    linux离线安装gcc 和g++
    简单验证两次密码输入是否相同
    循环结构-回文数
    《暴走大事件》为80、90后正名
    循环结构-判断一个数是否为完全数(C语言)
  • 原文地址:https://www.cnblogs.com/hanwuxing/p/12889899.html
Copyright © 2011-2022 走看看