ribbon组件的ConnectTimeOut和ReadTimeOut功能失效
最近在学习springcloud微服务,在使用openfeign时,需要使用ribbon组件的ConnectTimeOut和ReadTimeOut功能
本次项目是由消费者和提供者组成,提供者故意延时3s模拟复杂业务,而消费者的对用户提供的服务采用了服务降级
提供者服务,由控制层调用
package com.sgy.springcloud.service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.sgy.springcloud.dao.PaymentDao;
import com.sgy.springcloud.entities.Payment;
import com.sgy.springcloud.services.BaseDaoServiceImpl;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/**
* Created by AaronShen on 2020/6/1
*/
@Service
public class PaymentServiceImpl extends BaseDaoServiceImpl<Payment,String, PaymentDao>
implements PaymentService {
/**
* 模拟复杂业务
* 3000表示当前线程超过3s后调用fallbackMethod中指定的方法
* @param id
*/
@HystrixCommand(fallbackMethod = "paymentInfoTimeOutHandle",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")
})
@Override
public String paymentInfoTimeOut(Integer id) {
// int i = 10 / 0 ;
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
String result = "当前线程:" + Thread.currentThread().getName() +
"\t" + "paymentInfoTimeOut(id)" + "\t" + id +
"\t" + "耗时(秒):5";
return result;
}
private String paymentInfoTimeOutHandle(Integer id) {
String result = "当前线程:" + Thread.currentThread().getName() +
"\t" + "8090系统繁忙或者运行报错,请稍后再试试!!!" +
"\t" + "服务降级";
return result;
}
}
消费者
控制层
package com.sgy.springcloud.controller;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.sgy.springcloud.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* Created by AaronShen on 2020/6/1
*/
@RestController
@Slf4j
@DefaultProperties(defaultFallback = "paymentGlobalFallback")
public class OrderController {
@Resource
OrderService orderService;
@GetMapping("/hystrix/ok/{id}")
public String orderInfoOk(@PathVariable(value="id") Integer id) {
String result = orderService.paymentInfoOk(id);
return result;
}
@GetMapping("/hystrix/timeout/{id}")
// @HystrixCommand(fallbackMethod = "paymentInfoTimeOutHandle",commandProperties = {
// @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")
// })
@HystrixCommand
public String orderInfoTimeOut(@PathVariable(value="id") Integer id) {
String result = orderService.paymentInfoTimeOut(id);
return result;
}
private String paymentInfoTimeOutHandle(Integer id) {
String result = "当前线程:" + Thread.currentThread().getName() +
"\t" + "我是消费者80,对方支付系统繁忙请10秒后再试试或者自己运行出错请检查自己!!!" +
"\t" + "服务降级";
return result;
}
// 下面是全局的fallback
public String paymentGlobalFallback() {
return "消费者Global Fallback异常";
}
}
服务接口
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVER",fallback = OrderFallbackService.class)
public interface OrderService {
@GetMapping("/hystrix/ok/{id}")
String paymentInfoOk(@PathVariable(value="id") Integer id);
@GetMapping("/hystrix/timeout/{id}")
String paymentInfoTimeOut(@PathVariable(value="id") Integer id);
}
/**
* Created by AaronShen on 2020/7/9
*/
@Service
public class OrderFallbackService implements OrderService{
@Override
public String paymentInfoOk(Integer id) {
return "fallback--paymentInfoOk,支付服务宕机了";
}
@Override
public String paymentInfoTimeOut(Integer id) {
return "fallback--paymentInfoTimeOut,支付服务宕机了";
}
}
出现的问题
我在消费者的控制层中的orderInfoTimeOut方法中直接标注@HystrixCommand
,则调用全局的服务降级,但是呢?服务提供者故意延时3s,模拟复杂业务,结果消费者,每回访问都在调用服务降级。
原因分析
Hystrix默认超时时间是1秒,我们可以通过hystrix源码看到,
找到 hystrix-core.jar com.netflix.hystrix包下的HystrixCommandProperties类
default_executionTimeoutInMilliseconds属性局势默认的超时时间
解决问题
引入的依赖,千万别引入错了
<!--引入Hystrix依赖:-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
application.yml配置文件加上
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
接着探索
当我们经过以上的步骤之后,服务降级的超时时间是生效了,但是我使用了feign,feign底层使用的是ribbon,对远程服务进行调用
依旧出现服务降级问题分析
这回出现服务降级的原因就是,ribbon访问超时了,但是我明明配置了超时时间啊
# 设置feign客户端超时时间(OpenFeign默认支持Ribbon)
ribbon:
ReadTimeOut: 10000 # 建立连接所用时间,适用于网络状况正常的情况下,两端连接所用的时间
ConnectTimeOut: 10000 # 建立连接后,从服务器读取到的可用资源所用的时间
问题解决
使用中发现ribbon组件的ConnectTimeOut和ReadTimeOut功能并没有生效,报错代码示下:
查找maven导的依赖发现ribbon包冲突了,所以我选用feign里面的ribbon:
feign:
hystrix:
enabled: true
client:
config:
default:
# 设置feign客户端超时时间(OpenFeign默认支持Ribbon)
#简历连接所用的时间,适用于网络状况正常的情况下,两端连接所需要的时间
ConnectTimeout: 5000
#指建立连接后从服务端读取到可用资源所用的时间
ReadTimeout: 10000