0
点赞
收藏
分享

微信扫一扫

Day17_15_SpringCloud教程之Feign开发实战教程


Feign开发实战教程

一. Feign简介

1. Feign的概念

Feign 的英文表意为“假装,伪装,变形”,它是一个声明式的伪Http客户端,它是一个对http请求调用的轻量级框架.Feign使得写Http客户端变得更简单,我们只需要创建一个接口并注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,这种请求相对而言比较直观.Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果.

2. Feign的特点

  • 1️⃣. Feign 采用的是基于接口的注解;
  • 2️⃣. Feign 整合了ribbon,具有负载均衡的能力;
  • 3️⃣. 整合了Hystrix,具有熔断的能力.

3. Feign解决了什么问题?

封装了Http调用流程,更适合面向接口的编程习惯.

在服务调用的场景中,我们经常调用基于Http协议的服务,而我们经常使用到的框架可能有HttpURLConnection、Apache HttpComponnets、OkHttp3 、Netty等,这些框架都有自身的特性,但是从角色划分上来看,他们的职能是一致的,都是用来提供Http调用服务的.具体流程如下:


Day17_15_SpringCloud教程之Feign开发实战教程_动态代理

4. Feign的工作原理

FeignClient 会在底层根据我们的注解,与我们指定的服务建立连接、构造请求、发起请求、获取响应、解析响应,等,这一系列的工作,Feign 全帮我们实现了.

那么Feign 是如何做到这些的呢?
Feign 的一个关键机制就是使用了动态代理.

  • 首先,如果我们对某个接口定义了 @FeignClient注解,Feign就会针对这个接口创建一个动态代理;
  • 然后我们要是调用了那个接口,本质就是调用 Feign 创建的动态代理,这是核心中的核心;
  • Feign的动态代理会根据我们在接口上使用的 @RequestMapping 等注解,来动态构造出我们要请求的服务的地址;
  • 最后针对这个地址,发起请求、解析响应.

二. Feign的架构设计


Day17_15_SpringCloud教程之Feign开发实战教程_负载均衡_02

三. Feign 的性能

Feign 整体框架非常小巧,在处理请求转换和消息解析的过程中,基本上没什么时间消耗.真正影响性能的,是处理Http请求的环节.

如上所述,由于默认情况下,Feign采用的是JDK的HttpURLConnection,所以整体性能并不高.

四. Feign代码实战

在前一篇博客的基础之上,创建出一个基于Feign组件的eureka client模块-->service_feign_consumer.

1. 添加依赖包

<dependencies>
<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>
</dependencies>

2. 创建配置文件

server:
port: 8765
spring:
application:
name: eureka-feign
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/

3. 创建调用远程服务的service接口

定义一个feign接口,通过@ FeignClient(“要调用的服务名”),来指定调用哪个服务.比如在代码中调用了eureka-provider服务的“/hello”接口.

package com.syc.cloud.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(value = "eureka-provider")
public interface FeignHelloService {

@RequestMapping(value = "/hello", method = RequestMethod.GET)
String sayHello(@RequestParam(value = "name") String name);
}

3.1 @FeignClient标签的常用属性如下:

name: 指定FeignClient的名称,如果项目使用了Ribbon,name属性会作为微服务的名称,用于服务发现;

url: url一般用于调试,可以手动指定@FeignClient调用的地址;

decode404: 当发生http 404错误时,如果该字段为true,会调用decoder进行解码,否则抛出FeignException;

configuration: Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract;

fallback: 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口;

fallbackFactory: 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码;

path: 定义当前FeignClient的统一前缀.

4. 创建web层实现

Web层对外暴露一个"/hello"的API接口,通过上面定义的Feign客户端FeignHelloService 来消费服务.

package com.syc.cloud.web;

import com.syc.cloud.service.FeignHelloService;
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;

@RestController
public class HelloController {

//编译器报错,无视即可,因为这个Bean是在程序启动的时候注入的,编译器感知不到,所以报错.
@Autowired
private FeignHelloService helloService;

@GetMapping(value = "/hello")
public String sayHi(@RequestParam String name) {

return helloService.sayHello(name);
}
}

5. 创建入口类

在程序的启动类ServiceFeignApplication,加上@EnableFeignClients注解开启Feign的功能.

package com.syc.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableFeignClients
public class FeignApplication {

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

}

注意:

入口类上必须添加@EnableDiscoveryClient
@EnableFeignClients注解.

6. 目录结构


Day17_15_SpringCloud教程之Feign开发实战教程_动态代理_03

7. 启动项目

Day17_15_SpringCloud教程之Feign开发实战教程_动态代理_04

8. 结果测试


Day17_15_SpringCloud教程之Feign开发实战教程_动态代理_05



实现了远程调用,并且实现了负载均衡.

 

举报

相关推荐

0 条评论