在Feign 接口中定义了依赖服务的接口,当Feign调用依赖服务的接口失败时怎么办?
我们也可以在Feign中利用Hystrix的功能,当Feign 调用依赖服务的接口失败时,通过Hystrix调用指定的方法,Spring Cloud默认为Feign整合了Hystrix,但在Spring Cloud 基于Spring boot 2.x的版本中,默认是Feign是关闭Hystrix的。
那么Feign与Hystrix怎么配合使用呢?
1、创建项目futurecloud-feign-hystrix
注意:不需要添加依赖spring-cloud-starter-netflix-hystrix,Spring Cloud默认已为Feign整合了Hystrix。spring boot 主函数也不需要添加注解@EnableCircuitBreaker 来开启Hystrix。主函数类如下:
package com.futurecloud.feignhystrix;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableEurekaClient //声明为eureka 客户端
@EnableFeignClients //启动Feign
public class FuturecloudFeignHystrixApplication
{
@Bean //相当于xml中的bean标签,主要是用于调用当前方法获取到指定对象
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
public static void main( String[] args )
{
SpringApplication.run(FuturecloudFeignHystrixApplication.class,args);
}
}
开启Hystrix在application.yml中配置
#开启hystrix配置
feign:
hystrix:
enabled: true
2、Feign 使用fallback 方式进行Hystrix的回退
在定义Feign接口时,我们可以指定Feign接口中的方法调用失败后的一个回调类,这个类实现此Feign接口,
Feign接口代码如下:
package com.futurecloud.feignhystrix.feign;
import com.futurecloud.feignhystrix.bean.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(name = "futurecloud-user",fallback = FeignHystrixFallback.class) //指定依赖服务Hystrixd的回调类
public interface FeignInterface {
@GetMapping("/user/{id}")
User getUser(@PathVariable("id") Long id);
@GetMapping("/getObject")
User getObject(User user);
@GetMapping("/find//user/{id}")
User findUser(@PathVariable("id") Long id);
}
FeignHystrixFallback 代码如下:
package com.futurecloud.feignhystrix.feign;
import com.futurecloud.feignhystrix.bean.User;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class FeignHystrixFallback implements FeignInterface{
@Override
public User getUser(Long id) {
User user = new User();
user.setId(-401L);
user.setUsername("01-feignHystrixFallback");
user.setMail("[email protected]");
user.setPhone("13838389438");
user.setCreateDate(new Date());
return user;
}
@Override
public User getObject(User user) {
user = new User();
user.setId(-402L);
user.setUsername("02-feignHystrixFallback");
user.setMail("[email protected]");
user.setPhone("13838389438");
user.setCreateDate(new Date());
return user;
}
@Override
public User findUser(Long id) {
User user = new User();
user.setId(-403L);
user.setUsername("03-feignHystrixFallback");
user.setMail("[email protected]");
user.setPhone("13838389438");
user.setCreateDate(new Date());
return user;
}
}
注意:要添加注解@Component,否则Spring boot 找不到这个bean
启动eureka 服务futurecloud-service,
启动服务提供者服务futurecloud-user,
启动此服务futurecloud-feign-hystrix
访问http://localhost:8907/order/20 ,成功访问
将服务futurecloud-user关掉,再一次访问http://localhost:8907/order/20,调用了fallback指定的FeignHystrixFallback中的方法。
3、Feign 使用fallbackFactory方式进行Hystrix的回退
在Feign接口中指定使用fallbackFactory工厂类,其实就是实现Feign接口的匿名类
Feign接口定义如下:
package com.futurecloud.feignhystrix.feign;
import com.futurecloud.feignhystrix.bean.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(name = "futurecloud-user",fallbackFactory = FeignHystrixFallbackFactory.class)
public interface FeignInterface {
@GetMapping("/user/{id}")
User getUser(@PathVariable("id") Long id);
@GetMapping("/getObject")
User getObject(User user);
@GetMapping("/find//user/{id}")
User findUser(@PathVariable("id") Long id);
}
FeignHystrixFallbackFactory代码如下:
package com.futurecloud.feignhystrix.feign;
import com.futurecloud.feignhystrix.bean.User;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class FeignHystrixFallbackFactory implements FallbackFactory{
@Override
public FeignInterface create(Throwable throwable) {
return new FeignInterface() {
@Override
public User getUser(Long id) {
User user = new User();
user.setId(-404L);
user.setUsername("01-feignHystrixFallbackFactory");
user.setMail("[email protected]");
user.setPhone("13838389438");
user.setCreateDate(new Date());
return user;
}
@Override
public User getObject(User user) {
user = new User();
user.setId(-405L);
user.setUsername("02-feignHystrixFallbackFactory");
user.setMail("[email protected]");
user.setPhone("13838389438");
user.setCreateDate(new Date());
return user;
}
@Override
public User findUser(Long id) {
User user = new User();
user.setId(-406L);
user.setUsername("03-feignHystrixFallbackFactory");
user.setMail("[email protected]");
user.setPhone("13838389438");
user.setCreateDate(new Date());
return user;
}
};
}
}
其余配置与fallback一致。
启动eureka 服务futurecloud-service,
启动服务提供者服务futurecloud-user,
启动此服务futurecloud-feign-hystrix
访问http://localhost:8907/order/20 ,成功访问
将服务futurecloud-user关掉,再一次访问http://localhost:8907/order/20,调用了fallbackFactory指定的FeignHystrixFallbackFactory中的方法。