声明式服务调用Feign

目录

一、Feign介绍

1、什么Feign

2、Feign的启动器

二、Feign入门案例

1.创建服务提供者feign_provider

2.创建feign_interface模块

3.创建服务消费者feign_consumer

4.案例测试

 三、Feign原理

1.将Feign接口代理类注入到Spring容器中

2、为接口的方法创建RequestTemplate

3、发出请求

四、Feign优化

1、开启feign日志  

 2、feign超时

        1、方式一

         2、方式二

3、http连接池

 4、gzip压缩


一、Feign介绍

1、什么Feign

Feign是Spring Cloud提供的声明式、模板化的HTTP客户端, 它使得调用远程服务就像调用本地

服务一样简单,只需要创建一个接口并添加一个注解即可。

Spring Cloud集成Feign并对其进行了增强,使Feign支持了Spring MVC注解;Feign默认集成了

Ribbon,所以Fegin默认就实现了负载均衡的效果。【(ribbon+restTemplate)+优化=feign】

2、Feign的启动器

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

在FeignConsumerApp启动器类上添加 @EnableFeignClients 注解,开启feign注解的扫描

@SpringBootApplication
@EnableDiscoveryClient//向注册中心注册该服务,并可以获取其他服务的调用地址
@EnableFeignClients//开启feign注解的扫描
public class FeignConsumerApp {
    public static void main(String[] args) {
        SpringApplication.run(FeignConsumerApp.class);
    }
}

二、Feign入门案例

1.创建服务提供者feign_provider

注:feign_provider模块是拷贝的ribbo_provider_1模块,在下面内容中所使用到的代码案例均来自前面几篇内容中的代码案例。

 application.xml文件

server:
  port: 9090
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.238.132:8848 #nacos服务的地址
  application:
    name: feign-provider #向注册中心注册的名字

controller层

@RestController
@RequestMapping("/provider")
public class ProviderController {
    @Autowired
    private UserService userService;

    @RequestMapping("/getUserById/{id}")
    public User getUserById(@PathVariable Integer id){
        return userService.getUserById(id);
    }

    @RequestMapping("/deleteUserById")
    public User deleteUserById(Integer id){
        return userService.deleteUserById(id);
    }

    @RequestMapping("/addUser")
    public User addUser(@RequestBody User user){
        return userService.addUser(user);
    }
}

service包中改动内容

@Service
public class UserServiceImpl implements UserService {

    @Override
    public User getUserById(Integer id) {
        return new User(id,"王小",18);
    }

    @Override
    public User deleteUserById(Integer id) {
        return new User(id,"删除了王小",18);
    }
    @Override
    public User addUser(User user) {
        user.setName("新增王小");
        return user;
    }
}

2.创建feign_interface模块

pom.xml

<dependencies>
    <!--Spring Cloud OpenFeign Starter -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <dependency>
        <groupId>com.wrs</groupId>
        <artifactId>springcloud_common</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

UserFeign接口: 分别使用了三种不同的请求发送的方式

@FeignClient("feign-provider")
@RequestMapping("/provider")
public interface UserFeign {
    @RequestMapping("/getUserById/{id}")//拼接url
    public User getUserById(@PathVariable("id") Integer id);//restful形式拼接参数
    @RequestMapping("/deleteUserById")//拼接url
    User deleteUserById(@RequestParam("id") Integer id);//?形式拼接参数
    @RequestMapping("/addUser")
    User addUser(@RequestBody User user);//pojo--->json
}

3.创建服务消费者feign_consumer

pom.xml

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.wrs</groupId>
            <artifactId>springcloud_common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--nacos客户端-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--feign接口-->
        <dependency>
            <groupId>com.wrs</groupId>
            <artifactId>feign_interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

application.yml

server:
  port: 80
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.238.132:8848
  application:
    name: feign-consumer

Controller

@RestController
@RequestMapping("/consumer")
public class ConsumerController {
  @Autowired
  private UserFeign userFeign;//代理类

    @RequestMapping("/getUserById/{id}")
    public User getUserById(@PathVariable Integer id){
        System.out.println(userFeign.getClass());
        return userFeign.getUserById(id);
    }

    @RequestMapping("/deleteUserById")
    public User deleteUserById(Integer id){
        System.out.println(userFeign.getClass());
        return userFeign.deleteUserById(id);
    }

    @RequestMapping("/addUser")
    public User addUser(User user){
        System.out.println(userFeign.getClass());
        return userFeign.addUser(user);
    }
}

feign_consumer的启动器在上方内容已经给出为FeignConsumerApp,请参考上方内容;

4.案例测试

分别对三个请求方法进行了测试,根据注解的不同输入的请求路径也不相同,由此可知:

在UserFeign接口中

1、@RequestMapping   表示拼接请求路径  localhost/consumer/getUserById/2

        是restful传参

2、@PathVariable("id")  表示 ? 形式拼接参数     localhost/consumer/deleteUserById?2
        ?传参

3、@RequestBody 表示“对象”转“JSON”传参  localhost/consumer/addUser?id=2&name=wx&age=18

        pojo---->json转换传参

 三、Feign原理

1.将Feign接口代理类注入到Spring容器中

@EnableFeignClients注解开启Feign扫描,先调用FeignClientsRegistrar.registerFeignClients()方法扫描被@FeignClient注解标识的接口生成代理类,再将这些接口和代理类注入到Spring IOC容器中,方便后续被调用。

2、为接口的方法创建RequestTemplate

当consumer调用feign代理类时,代理类会调用SynchronousMethodHandler.invoke()创建RequestTemplate(url,参数)

3、发出请求

代理类会通过RequestTemplate创建Request,然后client(URLConnetct、HttpClient、OkHttp)使用Request发送请求

四、Feign优化

1、开启feign日志  

浏览器发起的请求可以通过F12查看请求和响应信息。如果想看微服务中的每个接口,我们可以使用日志配置方式进行详细信息的查看。

Feign虽然提供了日志增强功能,但是默认是不显示任何日志的,不过开发者在调试阶段可以自己配置日志的级别。

Feigin的日志级别如下:

  • NONE:默认的,不显示任何日志;
  • BASIC:仅记录请求方法、URL、响应状态码及执行时间;
  • HEADERS:除了BASIC中定义的信息之外,还是请求和响应的头信息;
  • FULL:除了HEADERS定义的信息之外,还有请求和响应的正文及元数据。

在application.yml中设置开启日志,并设置日志级别:

feign:
  client:
    config:
      default:
        loggerLevel: full
logging:
  level:
    com.wrs.feign: debug

日志开启效果:

 2、feign超时

在service实现层的任意一个方法中添加一个睡眠时间,来模拟连接超时

 启动案例,在浏览器中访问这个请求方法,此时在idea控制台,它会报出“连接超时”的错误。

 通过下面两种方式来解决连接超时的问题

        1、方式一

在配置文件中添加下面属性,设置请求连接的超时时间:

    ribbon:
               ConnectTimeout: 5000 #请求连接的超时时间
               ReadTimeout: 5000 #请求处理的超时时间

        2、方式二

feign:
  client:
    config:
      feign-provider:
  ConnectTimeout: 5000 #请求连接的超时时间
  ReadTimeout: 5000 #请求处理的超时时间

通过上边在两种方式在配置文件中分别添加不同的属性,来解决“连接超时”的问题:

3、http连接池

两台服务器建立HTTP连接的过程涉及到多个数据包的交换,很消耗时间。采用HTTP连接池可以节约大量的时间提示吞吐量。

Feign的http客户端支持3中框架:HttpURLConnection、HttpClient、OkHttp。

Feign默认是采用java.net.HttpURLConnection的,每次请求都会建立、关闭连接。

添加依赖:

 <dependency>
           <groupId>io.github.openfeign</groupId>
           <artifactId>feign-httpclient</artifactId>
  </dependency>

http连接池在配置文件中是默认开启的,所以无需在配置文件中添加开启属性,只需添加jar依赖才就能实现真正的开启。 

在feign.SynchronousMethodHandler()这个方法中debug调试,运行案例就会看到http连接池开启的标志

 http连接池关闭:将依赖去除

4、gzip压缩

gzip 介绍:gzip 是一种数据格式,采用用 deflate 算法压缩 data;gzip 是一种流行的文件压缩算法,应用十分广泛,尤其是在 Linux 平台。
gzip 能力:当 Gzip 压缩到一个纯文本文件时,效果是非常明显的,大约可以减少 70%以上的文件大小。
gzip 作用:网络数据经过压缩后实际上降低了网络传输的字节数,最明显的好处就是可以加快网页加载的速度。网页加载速度加快的好处不言而喻,除了节省流量,改善用户的浏览体验外,另一个潜在的好处是 Gzip 与搜索引擎的抓取工具有着更好的关系。例如 Google就可以通过直接读取 gzip 文件来比普通手工抓取 更快地检索网页。

feign开启gzip步骤:在项目中的yml文件中添加以下内容开启gzip压缩

 server:
          compression:
              enabled: true #开启gzip压缩

  开启gzip压缩后的,发送一个请求,查看请求的响应标头,显示出下边这个标志,表示设置成功:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值