三、SpringCloud-Netflix-Openfeign

1.Feign介绍

1.1.什么是Feign

Feign是一个声明式的http客户端,使用Feign可以实现声明式REST调用,让WEB调用更加简单;
Feign整合了Ribbon和SpringMvc注解,这让Feign的客户端看起来像一个Controller;
Feign提供了HTTP请求模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息;
Feign会完全代理HTTP请求,我们只需要调用方法就可以完成服务请求及相关处理;
Feign整合了Hystrix,可以很容易的实现服务熔断和降级。

1.2.为什么要使用Feign

上篇文章我们说到使用Ribbon作为客户端使用负载均衡完成服务之间的通信;
我们使用RestTemplate调用其他服务时,需要的参数要在URL中进行拼接,如果参数过多,就会很麻烦;
Feign对Ribbon进行了封装,把一些url和参数处理细节屏蔽了起来,使用更方便。

2.使用

搭建Pay服务,注册到eureka

2.1.导入依赖

导入Feign的依赖jar包
<!--2.导入Feign的包-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2.2.编写配置类

主要是使用@EnableFeignClients注解
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
public class PayApp {
    public static void main(String[] args) {
        SpringApplication.run(PayApp.class,args);
    }

}

2.3.yaml配置

#注册到EurekaServer
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:1010/eureka/
  instance:
    instance-id: pay-server
spring:
  application:
    name: pay-server
server:
  port: 1040

2.4.编写Feign客户端接口

创建一个客户端接口,加上@Feign注解,value值是服务名:
	Feign可以根据服务名在注册中心找到目标服务的通信地址;
请求方式、路径、参数和返回值类型需要和被调用的接口一致。
@FeignClient(value = "user-server")
public interface UserClientFeign {
    @GetMapping("/user/{id}")
    User getUser(@PathVariable Long id);
}

2.5.编写Controller使用Feign接口

直接通过Feign接口调用方法
@RestController
@RequestMapping("/pay")
public class PayController {
    @Autowired
    private UserClientFeign userClientFeign;

    @GetMapping("/{id}")
    public User getPay(@PathVariable("id") Long id) {
        User user = userClientFeign.getUser(id);
        return user;
    }
}
启动类上使用了@EnableFeignClient注解,会去扫描指定路径下的所有子包下使用了@FeignClient注解的类;
使用动态代理,生成代理类并将对象注入到IOC容器;
在代理方法中使用Http工具(RequestTemplate)生成request请求,交给Http客户端;
Http客户端会交给LoadBalanceClient,使用Ribbon的负载均衡发起调用。

3.Feign的参数配置

3.1.负载均衡配置

Feign已经集成了Ribbon,所以配置Ribbon的负载均衡即可;

通过@Bean方式或者xml方式:

@Bean
    public RandomRule getRandomRule() {
        return new RandomRule();
    }
user-server:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

3.2.Feign的超时配置

在服务调用时出现"feign.RetryableException : Read timed out...”错误日志;
说明Ribbon处理超时,我们可以配置Ribbon的超时时间。
ribbon:
	ConnectTimeout: 3000
    ReadTimeout: 6000

4.Feign开启日志调试

NONE,不记录(DEFAULT)。
BASIC,仅记录请求方法和URL以及响应状态代码和执行时间。
HEADERS,记录基本信息以及请求和响应标头。
FULL,记录请求和响应的标题,正文和元数据。

向IOC容器注入Level对象

@Bean
Logger.Level feignLoggerLevel() {
     return Logger.Level.FULL;	//打印Feign的所有日志
 }

上面配置的打印Feign的内容,下面是配置日志框架打印日志的级别。

logging:
  level:
    cn.liupeng: trace

5.Feign开启HZIP

开启Feign的数据压缩传输,这样可以节省网络开销;
但是压缩数据会增加CPU开销,所以太小的数据没必要压缩;
通过压缩大小阈值来控制,如下:
feign:
  compression:
    request:
      enabled: true
      min-request-size: 1024 #最小阈值,小于这个不压缩
      mime-types: text/xml,application/xml,application/json #压缩哪些类型的数据
    response:
      enabled: true

开启之后在控制台就能看到以下结果:
在这里插入图片描述

6.了解Hystrix熔断器

6.1.雪崩效应

微服务中服务的调用非常复杂,一个请求往往需要很多的微服务共同完成,可能形成很长的调用链;
在整个调用链中,如果某一个服务发生故障会导致调用它的服务一起发生异常;
然后整个调用链异常,导致整个微服务架构瘫痪。

6.2.Hystrix作用

防止单个服务异常导致整个微服务异常;
快速失败,如果服务器出现故障,服务的请求快速失败,线程不会等待;
服务降级,请求故障可以返回设定好的备用方案(兜底数据);
熔断机制,防止故障的扩散,导致整个服务瘫痪;
服务监控,提供了Hystrix Bashboard仪表盘,实时监控熔断器状态。

资源隔离

线程池隔离:
	使用一个线程池来存储当前请求,线程池对请求做处理,设置任务返回处理超时时间,堆积的请求先入线程池队列。
	新线程、异步、线程调度和切换开销、支持并发。
信号量隔离:
	使用一个原子计数器(或信号量)记录当前有多少个线程在运行,请求来先判断计数器的数值;
	若超过设置的最大线程个数则丢弃该类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。
	原线程、同步、无线程切换开销、支持并发。

6.3.OpenFeign使用Hystrix

6.3.1.导入依赖

OpenFeign上面已经导入过了

6.3.2.yaml配置

开启熔断支持
feign:
  hystrix:
    enabled: true #开启熔断支持

6.3.3.Feign接口熔断

指定托底数据有两种方式:
fallback和fallbackFactory
6.3.3.1.fallback方式
创建一个类实现Feign接口,重写接口方法,返回托底数据;(交给Spring管理)
6.3.3.2.fallbackFactory方式

Feign接口

@FeignClient(value = "user-server",fallbackFactory = UserClientFallBackFactory.class)
public interface UserClientFeign {
    @GetMapping("/user/{id}")
    User getUser(@PathVariable Long id);
}

Feign实现类

@Component
public class UserClientFallBackFactory implements FallbackFactory<UserClientFeign> {

    @Override
    public UserClientFeign create(Throwable throwable) {
        return new UserClientFeign() {
            @Override
            public User getUser(Long id) {
                throwable.printStackTrace();
                return new User(-1l,"出毛病啦!!",65536L);
            }
        };
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值