03.Spring Cloud 之 Feign

1. 概述

1.1 Feign 是什么
  • Feign 是一个声明式 WebService 客户端。使用 Feign 能让编写 Web Service 客户端更加简单,它的使用方法是定义一个接口,然后在上面添加注解,同时也支持 JAX-RS 标准的注解。Feign 也支持可插拔式的编码器和解码器。SpringCloud 对 Feign 进行了封装,使其支持了 Spring MVC 标准注解和 HttpMessageConverters。Feign 可以与 Eureka 和 Ribbon 组合使用以支持负载均衡。
1.2 Feign 能干什么
  • Feign 旨在使编写 Java Http 客户端变得更容易

  • 前面在使用 Ribbon + RestTemplate 时,利用 RestTemplate 对 http 请求的封装处理,形成了一套模板化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,Feign 在此基础上做了进一步封装,由它来帮助我们定义和实现依赖服务接口的定义。在 Feign 的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是 Dao 接口上面标注 Mapper 注解,现在是一个微服务接口上面标注一个 Feign 注解即可),即可完成对服务提供方的接口绑定,简化了使用 Spring Cloud Ribbon 时,自动封装服务调用客户端的开发量。

3. Feign 集成了 Ribbon
  • 利用 Ribbon 维护了 microservicecloud-Dept 的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与 Ribbon 不同的是,通过 feign 只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用

2. Feign 使用

  • 项目已上传至 https://github.com/masteryourself/study-spring-cloud.git
2.1 配置文件
1. pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- eureka 已经集成了 ribbon,这里不需要再单独引入-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2. application.properties
# 此实例注册到eureka服务端的 name
spring.application.name=masteryourself-user
# 端口号
server.port=5001

# 与 eureka server 交互的地址
eureka.client.service-url.defaultZone=http://masteryourself-eureka-7001.com:7001/eureka
# 此实例注册到 eureka 服务端的唯一的实例 ID
eureka.instance.instance-id=masteryourself-user-5001
# 是否显示 IP 地址
eureka.instance.prefer-ip-address=true
# eureka 客户需要多长时间发送心跳给 eureka 服务器,表明它仍然活着,默认为 30 秒
eureka.instance.lease-renewal-interval-in-seconds=10
# eureka 服务器在接收到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除,默认为 90 秒
eureka.instance.lease-expiration-duration-in-seconds=30

# 请求连接的超时时间,默认的时间为 1000 ms
ribbon.ConnectTimeout=3000
# 请求处理的超时时间
ribbon.ReadTimeout=3000
2.2 代码
1. OrderService
@FeignClient(value = "MASTERYOURSELF-ORDER")
public interface OrderService {

    @RequestMapping(value = "doOrder")
    Map<String, String> doOrder();

}
2. WalletService
@FeignClient("MASTERYOURSELF-WALLET")
public interface WalletService {

    @RequestMapping(value = "doDeduct")
    Map<String, String> doDeduct();

}
3. UserControllerWithFeign
@RestController
public class UserControllerWithFeign {

    @Autowired
    private OrderService orderService;

    @Autowired
    private WalletService walletService;

    @RequestMapping(value = "buyByFeign")
    public Map buyByFeign() {
        Map orderMap = orderService.doOrder();
        Map deductMap = walletService.doDeduct();
        Map<Object, Object> result = new HashMap<>(10);
        result.put("order-msg", orderMap);
        result.put("deduct-msg", deductMap);
        return result;
    }

}
4. UserApplication5001
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class UserApplication5001 {

    public static void main(String [] args){
        SpringApplication.run(UserApplication5001.class, args);
    }

}
2.3 效果展示
  • 多次请求 http://192.168.20.1:5001/buyByFeign ,可以看到每次的返回值都是不同的服务器返回,同 Ribbon

3. Feign 使用自定义负载均衡

  • 项目已上传至 https://github.com/masteryourself/study-spring-cloud.git
3.1 代码
1. CustomRule
public class CustomRule extends AbstractLoadBalancerRule {

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }

    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        }
        System.out.println("自定义生效了");
        return lb.getAllServers().get(0);
    }

    @Override
    public Server choose(Object key) {
        return choose(getLoadBalancer(), key);
    }

}
2. OrderRuleConfig
  • 注意:此类不能被 Spring 的 ComponentScan 扫描到,否则会被当成全局的负载均衡策略使用
@Configuration
public class OrderRuleConfig {

    @Bean
    public IRule rule() {
        return new RandomRule();
    }

}
3. WalletRuleConfig
  • 注意:此类不能被 Spring 的 ComponentScan 扫描到,否则会被当成全局的负载均衡策略使用
@Configuration
public class WalletRuleConfig {

    @Bean
    public IRule rule() {
        return new CustomRule();
    }

}
4. UserApplication5001
  • 每个微服务可以使用自己的负载均衡策略
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@RibbonClients({
        @RibbonClient(name = "MASTERYOURSELF-ORDER", configuration = OrderRuleConfig.class),
        @RibbonClient(name = "MASTERYOURSELF-WALLET", configuration = WalletRuleConfig.class)
})
public class UserApplication5001 {

    public static void main(String [] args){
        SpringApplication.run(UserApplication5001.class, args);
    }

}
3.2 效果展示
  • 多次请求 http://192.168.20.1:5001/buyByFeign,wallet 微服务的结果总是返回第一台,而 order 微服务的结果是随机的

在这里插入图片描述
在这里插入图片描述

发布了37 篇原创文章 · 获赞 3 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/masteryourself/article/details/103101762