Feign 简介和使用

一、简介

Feign是Netflix公司开发的一个声明式的REST调用客户端
Ribbon负载均衡、Hystrix服务熔断是我们Spring Cloud开发中非常基础的组件,在使用过程中他们一般是同时出现的,配置也非常相似,每次开发都有许多相同的代码。因此,Spring Cloud基于Netflix Feign整合了Ribbon和Hystrix两个组件,让我们的开发变的更加简单。
Spring Cloud Feign :对Ribbon负载均衡、Hystrix服务熔断进行了简化,在其基础上进行了进一步的封装,不仅在配置上大大简化了开发工作,同时还提供了一种声明式的Web服务客户端定义方式。

二、使用Feign实现服务消费者

  1. 创建SpringBoot工程
  2. 添加依赖
    spring-cloud-starter-netflix-eureka-client
    spring-cloud-starter-openfeign
    spring-cloud-starter-netflix-hystrix
  3. 在入口函数上激活功能
    @EnableEurekaClient
    @EnableFeignClients
  4. 配置文件
# 服务端口号
server.port=80
#指定该服务的名字,该名称将在服务被调用时使用
spring.application.name=feign-eureka-client-consumer
#Eureka配置:服务注册到哪里
eureka.client.service-url.defaultZone=http://eureka7001:7001/eureka
  1. service接口
/**
 * 用于标记当前借口是一个Feign声明式服务接口。Spring会为这个接口生成动态代理对象
 * 属性name:指定注册中心某个服务的名字
 */
@FeignClient(name="feign-eureka-client-provider")
public interface TestService {
    /**
     * 定义抽象方法
     * RequestMapping标记这个方法用于访问服务提供者,参数对应服务提供者提供的方法
     * @return 服务提供者返回的具体内容
     */
    @RequestMapping("/test")
    String test();

    /**
     * @RequestParam 指定基本数据类型参数
     */
    @RequestMapping("/testParam01")
    String testParam01(@RequestParam String name, @RequestParam Integer age);
    /**
     * @RequestBody 指定对象类型参数
     */
    @RequestMapping("/testParam02")
    String testParam02(@RequestBody User user);
    /**
     * 如果服务提供者返回的Json数据符合Json对象格式
     * 那么我们可以使用一个实体类或Map集合来接收响应数据
     */
    @RequestMapping("/testReturnUser")
    User testReturnUser();
    /**
     * 如果服务提供者返回的Json数据符合Json对象数组格式
     * 那么我们可以使用一个List集合来接收响应数据
     */
    @RequestMapping("/testReturnList")
    List<User> testReturnList();
}

  1. controller调用远程服务
/**
 * 作为服务消费者,可以不使用 RestController 返回json数据,这里为了方便而使用。
 */
@RestController
public class TestController {
    @Resource
    private TestService testService;

    @RequestMapping("/test")
    public String test(){
        String result = testService.test();
        return "使用了Feign的服务消费者..."+result;
    }
    @RequestMapping("/testParam01")
    public String testParam01(){
        String result = testService.testParam01("lily",24);
        return "使用了Feign的服务消费者..."+result;
    }
    @RequestMapping("/testParam02")
    public String testParam02(){
        User user = new User("xiaoming",23);
        String result = testService.testParam02(user);
        return "使用了Feign的服务消费者..."+result;
    }

    @RequestMapping("/testReturnUser")
    public String testReturnUser(){
        User user = testService.testReturnUser();
        return "使用了Feign的服务消费者..."+user.toString();
    }

    @RequestMapping("/testReturnList")
    public String testReturnList(){
        List<User> list = testService.testReturnList();
        return "使用了Feign的服务消费者..."+list.toString();
    }
}

三、实现普通的服务提供者

  1. 创建SpringBoot工程
  2. 添加依赖
    spring-cloud-starter-netflix-eureka-client
  3. 在入口函数上激活功能
    @EnableEurekaClient
  4. 配置文件
server.port=8001

#指定该服务的名字,该名称将在服务被调用时使用
spring.application.name=feign-eureka-client-provider

#Eureka配置:服务注册到哪里
eureka.client.service-url.defaultZone=http://eureka7001:7001/eureka
  1. controller提供服务
/**
 * 作为服务提供者,要是用 RestController 返回json数据
 */
@RestController
public class TestController {
    @GetMapping("/test")
    public String test(){
        return "【服务提供者返回内容】";
    }

    @GetMapping("/testParam01")
    public String testParam01(String name,Integer age){
        return "【服务提供者返回内容 name:"+name+"  age:"+age+"】";
    }

    @RequestMapping("/testParam02")
    public String testParam02(@RequestBody User user){
        return "【服务提供者返回内容 name:"+user.getName()+"  age:"+user.getAge()+"】";
    }

    @RequestMapping("/testReturnUser")
    public Object testReturnUser(){
        User user = new User("小黄",23);
        return user;
    }

    @RequestMapping("/testReturnList")
    public Object testReturnList(){
        List<User> list = new ArrayList<>();
        User user1 = new User("小黄",23);
        User user2 = new User("小李",24);
        User user3 = new User("小明",25);
        list.add(user1);
        list.add(user2);
        list.add(user3);
        return list;
    }
}

四、Feign服务调用测试

  1. 访问:http://localhost/test
    在这里插入图片描述
  2. http://localhost/testParam01
    在这里插入图片描述
  3. 访问:http://localhost/testParam02
    在这里插入图片描述
  4. 访问:http://localhost/testReturnUser
    在这里插入图片描述
  5. 访问:http://localhost/testReturnList
    在这里插入图片描述

五、Feign消费者测试

负载均衡

Spring Cloud提供了Ribbon来实现负载均衡,使用Ribbon直接注入一个RestTemplate对象即可,RestTemplate已经做好了负载均衡的配置;在Spring Cloud下,使用Feign也是直接实现负载均衡的,定义一个有@FeignClient注解的接口,然后使用@RequestMapping注解到方法上映射远程的REST服务,此方法也是做好负载均衡配置的。

服务熔断
  1. 在application.properties文件开启feign对hystrix功能支持(支持熔断)
feign.hystrix.enabled=true
  1. 指定熔断回调逻辑
/**
 * @FeignClient:标记当前接口是一个Feign声明式服务接口,Spring会为这个接口生成动态代理对象
 * 属性name:指定注册中心某个服务的名字
 * 属性fallback:指定一个自定义异常熔断器类
 * 属性fallbackFactory:指定一个自定义异常熔断器类,可以获得异常信息
 */
//方式一
@FeignClient(name="feign-eureka-client-provider",fallback = MyFallback.class)
//方式二
@FeignClient(name="feign-eureka-client-provider",fallbackFactory = MyFallbackFactory.class)
public interface TestService {...}
  1. 自定义异常熔断器
//方式一

/**
 * 自定义异常熔断器类,并实现自定义声明式Feign的接口
 * 为这个接口中的所有抽象方法提供熔断处理
 */
@Component
public class MyFallback implements TestService {
    @Override
    public String test() {
        return "test请求熔断";
    }

    @Override
    public String testParam01(String name, Integer age) {
        return "testParam01请求熔断";
    }

    @Override
    public String testParam02(User user) {
        return "testParam02请求熔断";
    }

    @Override
    public User testReturnUser() {
        return null;
    }

    @Override
    public List<User> testReturnList() {
        return null;
    }
}
//方式二

/**
 * 自定义异常熔断器类,并实现Hystrix的降级回调的父接口
 * 注意:泛型决定当前类要为哪个声明式接口提供异常熔断处理
 */
@Component
public class MyFallbackFactory implements FallbackFactory<TestService> {
    /**
     * @param throwable
     * @return 返回一个接口中泛型的对象:当这个泛型对象出现异常后将用create返回的这个对象进行降级
     */
    @Override
    public TestService create(Throwable throwable) {
        //使用匿名内部类来创建TestService声明式服务接口的熔断对象
        return new TestService() {
            @Override
            public String test() {
                System.out.println(throwable.getClass());
                System.out.println(throwable.getMessage());
                return "test请求熔断";
            }

            @Override
            public String testParam01(String name, Integer age) {
                return "testParam01请求熔断";
            }

            @Override
            public String testParam02(User user) {
                return "testParam02请求熔断";
            }

            @Override
            public User testReturnUser() {
                return null;
            }

            @Override
            public List<User> testReturnList() {
                return null;
            }
        };
    }
}
  1. 服务异常
    @GetMapping("/test")
    public String test(){
        System.out.println(1/0);
        return "【服务提供者返回内容】";
    }
  1. 调用服务进行熔断测试 http://localhost/test
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值