Feign概述
前面的可以发现当我们通过RestTemplate调用其它服务的API时,所需要的参数须在请求的URL中进行拼接,如果参数少的话或许我们还可以忍受,一旦有多个参数的话,这时拼接请求字符串就会效率低下,并且显得好傻。Feign是一个声明式的Web Service客户端,它的**目的就是让Web Service调用更加简单**。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。而Feign则会完全代理HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。Feign整合了Ribbon和Sentinel(关于Sentinel我们后面再讲),可以让我们不再需要显式地使用这两个组件
Feign具有如下特性:
- 可插拔的注解支持,包括Feign注解和JAX-RS注解;
- 支持可插拔的HTTP编码器和解码器;
- 支持Sentinel和它的Fallback;
- 支持Ribbon的负载均衡;
支持HTTP请求和响应的压缩;
这看起来有点像我们springmvc模式的Controller层的RequestMapping映射。这种模式是我们非常喜欢的。Feign是用@FeignClient来映射服务的。
Feign是以接口方式进行调用,而不是通过RestTemplate来调用,feign底层还是ribbon,它进行了封装,让我们调用起来更加happy.总结,就是feign通过一个本地对服务接口的代理,进行对注册到注册中心的服务调用,对于调用者来说,就像调用本地接口一样。
Feign的操作
导包
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>feign接口编写
@FeignClient(name = "接口对应需要调用的服务名") public interface UserFeignClient { @GetMapping("/getUser") public String getUserByNewsId(@RequestParam(required = false) Integer nid); @GetMapping("/test1") public String test1(@RequestParam("p1") String p1, @RequestParam("p2") Integer p2); @GetMapping("/query") public List<UserDto> query(@SpringQueryMap/*表单参数注解*/ UserDto user); @PostMapping("/queryJson") public UserDto queryJson(@RequestBody UserDto user); @GetMapping("/list") public List<UserDto> list(); @GetMapping("/getById/{id}") public UserDto getById(@PathVariable Integer id); }调用 ```java @Autowired private UserFeignClient userFeignClient;
UserDto user = userFeignClient.getById(1);
4.启动类
```java
@SpringBootApplication
@MapperScan("com.woniuxy.mapper")
@EnableFeignClients(basePackages = "com.woniuxy.client")
public class ProductServerApplication {
public static void main(String[] args) {
SpringApplication.run(ProductServerApplication.class, args);
}
}
Feign的配置
Java配置
编写配置类
@Configuration public class FeignConfig { //Feign的日志级别配置 @Bean public Level createLevel() { return Level.FULL; } }在主配置类指定
@FeignClient(configuration = FeignConfig.class) public class BaseConfig {}3、传递token
@Configuration public class FeignConfiguration implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String token = request.getHeader("token"); if (!StringUtils.isEmpty(token)) { // header添加token requestTemplate.header("token", token); } } }
属性配置
feign:
client:
config:
default: #这里可以换成服务名进行局部配置
logger-level: full
httpclient:
enabled: true #开启httpclient连接池配置
max-connections: 200 #最大连接数
max-connections-per-route: 50 #最大的路由数量
connection-timeout: 200000 #连接超时时间
logging: #配置spring的日志级别
level:
com.woniuxy.client: debug
Sentinel
雪崩效用
服务雪崩效应是一种因“服务提供者的不可用”(原因)导致“服务调用者不可用”(结果),并将不可用逐渐放大的现象。如下图所示:

服务容错
我们没办法预防雪崩效应的发生,只能尽可能的去做好容错。容错就是提供服务不可用的一种处理方式,避免雪崩。常见的服务容错的机制如下:
- 超时
超时模式,是一种最常见的容错模式,常见的有设置网络连接超时时间,一次RPC的响应超时时间等。在分布式服务调用的场景中,它主要解决了当依赖服务出现建立网络连接或响应延迟,不用无限等待的问题,调用方可以根据事先设计的超时时间中断调用,及时释放关键资源,如Web容器的连接数,数据库连接数等,避免整个系统资源耗尽出现拒绝对外提供服务这种情况。 - 限流
限流是指在一段时间内,定义某个客户或应用可以接收或处理多少个请求的技术。例如,通过限流,你可以过滤掉产生流量峰值的客户和微服务,或者可以确保你的应用程序在自动扩展(Auto Scaling)失效前都不会出现过载的情况。你还可以阻止较低优先级的流量,以便为关键事务提供足够的资源 - 断路器
当在短时间内多次发生指定类型的错误,断路器会开启。开启的断路器可以拒绝接下来更多的请求 – 就像防止真实的电子流动一样。断路器通常在一定时间后关闭,以便为底层服务提供足够的空间来恢复。
- 仓壁模式
在工业领域中,常使用舱壁将划分为几个部分,以便在有某部分船体发生破裂时,其他部分依然能密封安然无恙。舱壁的概念也可以在软件开发中用于隔离资源。通过使用舱壁模式,我们可以保护有限的资源不被用尽。例如,如果我们有两种类型的操作的话,它们都是和同一个数据库实例进行通信,并且数据据库限制连接数,这时我们可以使用两个连接池而不是使用一个共享的连接池。由于这种客户端和资源分离,超时或过度使用池的操作不会令所有其他操作失效。泰坦尼克号沉没的主要原因之一是其舱壁设计失败,水可以通过上面的甲板倒在舱壁的顶部,最后整个船淹没。
引入sentinel
Sentinel 是面向分布式服务架构的**轻量级**流量控制产品,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助您保护服务的稳定性。
导包
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>下载控制台
https://github.com/alibaba/Sentinel/releases
下载下来是一个jar包 直接通过 java命令启动- 配置跟控制台的通信
spring: cloud: sentinel: transport: dashboard: localhost:8080 #控制台地址 web-context-unify:false #支持链路追踪,默认为聚合,设置为非聚合
