spring cloud 里的 超时问题

hystrix默认超时时间是1000,单位:ms

服务提供方:

package cc.sion.web;

import cc.sion.biz.ISayBiz;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;

import java.util.concurrent.TimeUnit;

@RestController
public class SayController {
    @RequestMapping(value = "/sayWaiting/{name}" ,method = RequestMethod.GET)
    public String sayWaiting(@PathVariable String name) {
        try {
            //等5秒
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return "I hate waiting in line.";
    }

}

服务消费者:

@Service
public class RemoteService {

    @Autowired
    RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "sayFallback")
    public String sayWaiting(String name) {
        return restTemplate.getForObject(hello_url+"/sayWaiting/"+name, String.class);
    }

    public String sayFallback(String name,Throwable e)
    {

        System.out.println("=======================");
        if(e!=null)
            e.printStackTrace();

        return ":(";
    }
}

运行时提示:

=======================
com.netflix.hystrix.exception.HystrixTimeoutException
	at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$1.run(AbstractCommand.java:1121)
	at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:41)
	at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:37)
	at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable.run(HystrixContextRunnable.java:57)
	at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$2.tick(AbstractCommand.java:1138)
	at com.netflix.hystrix.util.HystrixTimer$1.run(HystrixTimer.java:99)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

解决办法如下:

一,修复消费者代码,添加个配置

    @HystrixCommand(fallbackMethod = "sayFallback",
            commandProperties = {
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "6000")
            }
    )
    public String sayWaiting(String name) {
        return restTemplate.getForObject(hello_url+"/sayWaiting/"+name, String.class);
    }

二,在application.yml下改hystrix配置

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds:  6000

或者直接禁用掉超时设置:

hystrix:
  command:
    default:
      execution:
        timeout:
          enabled:  false

还一个就是restTemplate的超时,比如这个:

org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://ooxx/addNumber": Read timed out; nested exception is java.net.SocketTimeoutException: Read timed out
        at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:633) ~[spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
        at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:580) ~[spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
        at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:380) ~[spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
        at org.springframework.web.client.RestTemplate$$FastClassBySpringCGLIB$$aa4e9ed0.invoke(<generated>) ~[

直接换个restTemplate的构造方式:

    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        //By default RestTemplate uses SimpleClientHttpRequestFactory which depends on default configuration of HttpURLConnection.
        //If you want to use HttpComponentsClientHttpRequestFactory - it has a connection pooling configuration which SimpleClientHttpRequestFactory does not have.

//毫秒
//        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
//        requestFactory.setConnectTimeout(60000);
//        requestFactory.setReadTimeout(10000);

        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setConnectionRequestTimeout(5000);
        requestFactory.setConnectTimeout(5000);
        requestFactory.setReadTimeout(60000);

        return new RestTemplate(requestFactory);
    }

猜你喜欢

转载自my.oschina.net/u/2357969/blog/874571