Feign在RestTemplate的基础上对其封装,由它来帮助我们定义和实现依赖服务接口的定义。Spring Cloud Feign 基于Netflix Feign 实现的,整合了Spring Cloud Ribbon 与 Spring Cloud Hystrix,并且实现了声明式的Web服务客户端定义方式。
我的理解是Feign是一个接口,是发起rest请求的工具,它集成了ribbon负载均衡和hystrix的错误熔断机制,通过rest的方式得到类似rpc远程调用的服务,也就是根据用户(客户)的url路径参数要求,去申请其他微服务的资源(多个服务可以负载均衡比如轮询),如果某个微服务宕机,可以通过hystric熔断(躲开),并返回回退函数的值给客户。
1. 创建微服务spring start project项目,命名为microservice-Feign-Hystrix-8804
2.pom.xml 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
3.application.properties
server.port: 8804
spring.application.name=MicroserviceFeignHystrix8804
spring.cloud.discovery.enabled=true
eureka.client.serviceUrl.defaultZone=http://admin:123@centos7:8101/eureka/,http://admin:123@microservice1:8102/eureka/
feign.hystrix.enabled=true
4. 启动类增加注解
@EnableDiscoveryClient
@EnableFeignClients
@EnableEurekaClient
@EnableCircuitBreaker
@SpringBootApplication
5. 声明@FeignClient接口
-
-
// 作为消费者轮询eureka中名字为MicroserviceServerA8801的微服务,如果超时,回退执行HelloClientFallback.class
-
@FeignClient(name = "MicroserviceServerA8801", fallback = HelloClientFallback.class)
-
public
interface HelloClient {
-
-
//定义声明接口
-
@RequestMapping(method = RequestMethod.GET, value = "/hello")
-
public String hello();
-
-
@RequestMapping(method = RequestMethod.GET, value = "/toHello")
-
public String toHello();
-
-
@RequestMapping(method = RequestMethod.GET, value = "/listusers")
-
public String listusers();
-
}
6. 定义回退类HelloClientFallback
-
@Component
-
public
class HelloClientFallback implements HelloClient {
-
//这是回退类,超时就执行这个得到返回值
-
-
public String hello() {
-
return
"fallback hello";
-
}
-
-
public String toHello() {
-
return
"fallback timeout hello";
-
}
-
-
public String listusers() {
-
return
"fallback listusers";
-
}
-
-
}
7. 定义控制类FeignController 对接口声明的实现
-
@RestController
-
public
class FeignController {
-
-
@Autowired
-
private HelloClient helloClient;
-
-
//对声明接口方法的具体实现
-
@RequestMapping(method = RequestMethod.GET, value = "/hello")
-
public String hello() {
-
return helloClient.hello();
-
}
-
-
@RequestMapping(method = RequestMethod.GET, value = "/listusers")
-
public String listusers() {
-
return helloClient.listusers();
-
// helloclient 是一个restemplate的请求,就是去发起连接请求获取返回,不能获取就执行回退程序
-
}
-
-
@RequestMapping(method = RequestMethod.GET, value = "/toHello")
-
public String toHello() throws InterruptedException {
-
Thread.sleep(
500);
-
String result = helloClient.toHello();
-
HystrixCircuitBreaker breaker = HystrixCircuitBreaker.Factory
-
.getInstance(HystrixCommandKey.Factory
-
.asKey(
"HelloClient#toHello()"));
-
System.
out.println(
"断路器状态:" + breaker.isOpen());
-
return result;
-
}
-
}
8,测试,先启动eureka服务,再启动微服务生产者MicroserviceServerA8801 我这启动两次,分别在8801,8802端口提供相同服务,最后启动本测试微服务在端口8804
可见访问同一网址多次,会负载均衡轮询多个MicroserviceServerA8801同名服务(8801,8802端口),当轮询的服务中断时,返回回退信息“fallback listusers”。