一、前言
在上篇博客中,小编带大家接触了断路器Hystrix,是不是很好玩。分布式服务之间有了Hystrix,可以很好的提高容错性能。
但是在实际开发中,项目中会有很多的服务间的调用,对于服务的调用不可能是一处。所以我们针对各个服务自行封装一些客户端类来包装这些依赖服务的调用。
SpringCloud Feign就在这个基础上做了封装,他可以帮助我们定义接口。开发时候只需要定义接口并添加相应的注解,大大的简化了使用ribbon的开发量。
二、准备
2.1 准备
根据上一篇博客搭建好的框架,我们在这个基础上进行修改,您可以在这里得到代码。
https://github.com/AresKingCarry/SpringCloudDemo
2.2 建立feign项目
创建springboot项目。
2.3 添加Feign的依赖
在pom文件中添加feign的依赖spring-cloud-starter-feign
和spring-cloud-starter-eureka
。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
2.4 启动类添加启动feign
在启动类添加@EnableFeignClients来开启对Spring Cloud Feign的支持:
package com.wl.feign;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
public class FeignApplication {
public static void main(String[] args) {
SpringApplication.run(FeignApplication.class, args);
}
}
3.5 service
定义ClientService 接口,通过@FeignClient(value = "xxxxxxx")
指定服务名来绑定服务,然后通过springmvc注解来绑定具体提供服务的rest接口。
这里注意的是,绑定的服务名,不区分大小写。所以client1和CLIENT1都是可以的。
package com.wl.feign.service;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* Created by Ares on 2018/4/23.
*/
@FeignClient(value = "client1")
public interface ClientService {
@GetMapping("/user/findById")
String findById(@RequestParam("id")String id);
}
2.6 Controller
package com.wl.feign.controller;
import com.wl.feign.service.ClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by Ares on 2018/4/23.
*/
@RestController
public class ClientController {
@Autowired
ClientService clientService;
@GetMapping("/user/findById")
public String findById(@RequestParam("id")String id){
return clientService.findById(id);
}
}
2.7 配置文件
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 7001
spring:
application:
name: feign-service
2.8 测试验证
因为feign是对ribbon的封装,所以默认的负载均衡策略依旧为轮询。依次启动Eureka、两个服务提供者、feign。
访问http://ares-pc:7001//user/findById?id=wl
三、添加断路器
在上篇博客中,我们在Ribbon中使用了Hystrix断路器,同样,我们也可以在Feign中使用断路器。
3.1 开启断路器
因为Feign是对springcloud Ribbon和springcloud Hystrix的封装,所以Feign是带短路器 的,需要我们在配置文件中,开启短路器。
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 7001
spring:
application:
name: feign-service
feign:
hystrix:
enabled: true
3.2 建立Service接口的实现类
定义ClientFallback 实现类,并注入spring容器。
package com.wl.feign.exception;
import com.wl.feign.service.ClientService;
import org.springframework.stereotype.Component;
/**
* Created by Ares on 2018/4/23.
*/
@Component
public class ClientFallback implements ClientService {
@Override
public String findById(String id) {
return "调用Client1服务超时,调用方法findById(id)-根据id查询所有记录"+id;
}
}
3.3 修改service
添加fallback,指明如果出错后要调用的类。
package com.wl.feign.service;
import com.wl.feign.exception.ClientFallback;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* Created by Ares on 2018/4/23.
*/
@FeignClient(value = "client1",fallback = ClientFallback.class)
public interface ClientService {
@GetMapping("/user/findById")
String findById(@RequestParam("id")String id);
}
3.4 测试
依次启动eureka、两个提供者、feign,正常启动的情况下:
当关闭一个提供者后,情况如下:
四、小结
通过feign,是不是感觉有点面向对象的感觉,把一些乱的调用,整理了一下。很好的操作。