SpringCLoud——Feign的远程调用

这篇具有很好参考价值的文章主要介绍了SpringCLoud——Feign的远程调用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于Feign的远程调用

RestTemplate方式调用存在的问题

来看一下之前我们使用RestTemplate调用时编写的Contrriller代码:

//        2.利用RestTemplate发起HTTP请求

//        2.1 url地址

        String url = "http://userserver/user/" + order.getUserId();

//        2.2 发送http请求,实现远程调用

        User user = restTemplate.getForObject(url, User.class);

//        封装user到Order

存在下面的问题:

  1. 代码可读性差,变成体验不统一
  2. 复杂参数URL难以维护

Feign的介绍

Feign是一个声明式的http客户端,官方地址:春云开假 (spring.io)

起作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题。

声明式,这个概念在之前我们学习Spring中的事务管理的时候,曾说过有一个叫做声明式事务的东西,它的作用就是简化我们应用事务的过程。在使用声明式事务之前,我们开启事务需要手动的管理事务,也就是手动进行事务的开启,回滚等一系列操作,但是声明式事务我们只需要指定需要应用事务的地方,剩下的关于事务的细节全部都交给Spring去管理即可,声明式就是这样的作用。

定义和使用Feign客户端

使用Feign的步骤如下:

  1. 首先引入依赖

<!--        Feign客户端-->

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-openfeign</artifactId>

        </dependency>

  1. 在order-service的启动类添加注解开启Feign功能:@EnableFeignClients

package cn.itcast.order;

import org.mybatis.spring.annotation.MapperScan;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;

import org.springframework.cloud.openfeign.EnableFeignClients;

import org.springframework.context.annotation.Bean;

import org.springframework.web.client.RestTemplate;

@MapperScan("cn.itcast.order.mapper")

@SpringBootApplication

@EnableFeignClients

public class OrderApplication {

    public static void main(String[] args) {

        SpringApplication.run(OrderApplication.class, args);

    }

    @Bean

    @LoadBalanced

    public RestTemplate restTemplate(){

        return new RestTemplate();

    }

}

然后就是使用Feign,首先我们需要编写Feign的客户端:

package cn.itcast.order.Feign;

import cn.itcast.order.pojo.User;

import org.springframework.cloud.openfeign.FeignClient;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

@FeignClient("userserver")

public interface UserClient {

    @GetMapping("/user/{id}")

    User FindById(@PathVariable Long id);

}

为了减少学习成本,其实是为了迎合SpringBoot用户的使用习惯,在Feign的客户端中,默认使用SpringMVC的编码习惯,比如:

  1. 服务名称:userserver
  2. 请求方式:GET
  3. 请求路径:/user/{id}
  4. 请求参数:Long id
  5. 返回值类型:User

使用这种方式,维护参数列表就是维护方法中的参数,比之前的编码要简单一些。

然后我们再看一下使用Feign调用之后的service代码:

package cn.itcast.order.service;

import cn.itcast.order.Feign.UserClient;

import cn.itcast.order.mapper.OrderMapper;

import cn.itcast.order.pojo.Order;

import cn.itcast.order.pojo.User;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.cloud.openfeign.FeignClient;

import org.springframework.stereotype.Service;

import org.springframework.web.client.RestTemplate;

@Service

public class OrderService {

    @Autowired

    private OrderMapper orderMapper;

    @Autowired

    private UserClient userClient;

    public Order queryOrderById(Long orderId) {

        // 1.查询订单

        Order order = orderMapper.findById(orderId);

//        使用Feign进行远程调用

        User user = userClient.FindById(order.getUserId());

//        封装user到Order

        order.setUser(user);

        // 4.返回

        return order;

//

    }

}

看着比之前就简单了很多,并且远程调用就像是方法的调用一样。

然后我们去浏览器访问Controller:

SpringCLoud——Feign的远程调用,SpringCloud,springcloud,中间件

可以看到是能正常的访问的,并且我们可以多访问几次,然后看一下控制台的日志,查看一下两台服务器的访问情况:

SpringCLoud——Feign的远程调用,SpringCloud,springcloud,中间件

SpringCLoud——Feign的远程调用,SpringCloud,springcloud,中间件

可以看到两台服务器都被访问过,这就说明,Feign除了做了远程调用,还做了负载均衡。原因就是在Feign的内部,集成了ribbon的依赖,我们可以打开Feign的依赖看一下:

SpringCLoud——Feign的远程调用,SpringCloud,springcloud,中间件

这里存在一个ribbon的依赖。

总结

Feign的使用步骤

  1. 引入依赖
  2. 添加@EnableFeignClients注解
  3. 编写FeignClinet接口
  4. 使用FeignClient中定义的方法代理RestTemplate

自定义Feign的配置

Feign运行自定义配置来覆盖默认配置,可以修改的配置如下:

SpringCLoud——Feign的远程调用,SpringCloud,springcloud,中间件

一般我们需要配置的就是日志级别。

配置Feign的配置有两种方式:

  1. 方式一:配置文件方式
    1. 全局生效:即访问所有的服务都以此日志级别生效

feign:

  client:

    config:

      default: # 这里的defaule就是全局配置,如果这里写的是服务名称,则是针对某个微服务的配置

        logger-level: FULL

    1. 局部生效:即仅访问配置的服务时候以此日志级别生效

feign:

  client:

    config:

      userserver: # 这里的defaule就是全局配置,如果这里写的是服务名称,则是针对某个微服务的配置

        logger-level: FULL

先来看一下默认的日志显示:

SpringCLoud——Feign的远程调用,SpringCloud,springcloud,中间件

就只有一个SQL语句的日志,然后我们修改配置,重启服务器之后,再来访问一下浏览器,看这次的日志输出内容是什么:

SpringCLoud——Feign的远程调用,SpringCloud,springcloud,中间件

这次的日志就非常的多了,除了上面的SQL语句日志之外,这里还有很大一堆的日志都是Feign的。

  1. 方式二:Java代码方式,需要先声明一个Bean,这是一个类,我们要新建一个类:

package cn.itcast.order.Feign;

import feign.Logger;

import org.springframework.context.annotation.Bean;

public class FeignConfig {

    @Bean

    public Logger.Level feignLogLevel(){

        return Logger.Level.BASIC;

    }

}

    1. 而后如果是全局配置,则把他放到@EnableFeignClient这个注解中,这个注解在启动类上:

@EnableFeignClients(defaultConfiguration = FeignConfig.class)

    1. 如果是局部配置,则把他放到@FeiguClient这个注解中,这个注解在启动类上:

@FeignClient(value = "userserver",configuration = FeignConfig.class)

然后我们重启服务器,再次在浏览器中访问接口,这次我们再来看日志:

SpringCLoud——Feign的远程调用,SpringCloud,springcloud,中间件

现在就清爽多了,也就两条日志,这就是BASIC日志级别。

总结

  1. 方式一是配置文件,feign.client.config.xxx.loggerLevel
    1. 如果xxx是default则代表全局
    2. 如果xxx是服务名称,例如userserver则代表某服务
  2. 方式二是Java代码配置Logger.Level这个Bean
    1. 如果在@EnableFeignClients注解声明则表示全局
    2. 如果在@FeignClient注解中声明则代表某服务

Feign的性能优化

Feign底层的客户端实现

  1. URLConnection:默认实现,不支持连接池
  2. Apache HttpClient:支持连接池
  3. OKHttp:支持连接池

因此优化Feign的性能主要包括:

  1. 使用连接池代替默认的URLConnection
  2. 日志级别,组好用Basic或None

Feign添加HttpClient的支持

引入依赖:

<!--        Feign的Apache Http依赖-->

        <dependency>

            <groupId>io.github.openfeign</groupId>

            <artifactId>feign-httpclient</artifactId>

        </dependency>

配置连接池:

feign:

  client:

    config:

      default: # defaule全局的配置

        logger-level: BASIC # 日志级别,BASIC就是基本的请求和相应信息

  httpclient:

    enabled: true # 开启Feign对HttpClient的支持

    max-connections: 200 # 最大的连接数

    max-connections-per-route: 50 # 每个路径最大的连接数,这个连接数并不是固定的,而是根据实际业务进行压力测试得来的最优解

Feign的最佳实践

方式一(继承):给消费者的FeignClient和提供者的controller定义统一的父接口作为标准。

首先我们来看一下我们之前写的使用Feign做的远程调用代码,和被调用的方法:

SpringCLoud——Feign的远程调用,SpringCloud,springcloud,中间件

SpringCLoud——Feign的远程调用,SpringCloud,springcloud,中间件

这么一对比,是不是一模一样,至于为什么一样就不用多说了吧,因为一个暴露接口,一个请求接口,那么这些基本的参数,比如请求方式,请求参数,请求路径必须都一样才能请求到啊,这就是为什么这两个方法一模一样的原因。那么方法既然一模一样,那么能不能抽取出来,作为一个共同的标准去引用他。作为同一个方法,当我要编写一个向外暴露的接口的时候,就不用自己写了,去继承这个标准就可以了,同样的,当我要访问一个接口的时候,具体的逻辑我也不用写了,去继承这个标准就可以了,因为被请求的那边也是继承这个标准,自然是一样的。这就是继承的基本逻辑,用一个共同的标准,统一请求方和被请求方两者的代码。

但是这种方式有一定的缺点:

  1. 服务紧耦合
  2. 父接口参数列表中的映射不会被继承

SpringCLoud——Feign的远程调用,SpringCloud,springcloud,中间件

方式二(抽取):将FeignClient抽取为的独立模块,并且把接口有关的POJO,默认的Feign配置都放到这个模块中,提供给消费者使用:

在一开始的时候,我们有一个服务的提供者和服务的消费者,当我的消费者要调用提供者的接口的时候,我要自己写一个方法去调用,就要做配置,写代码,调用。当我的消费者数量多了之后,每一个消费者要调用这个提供者的时候,都要自己写一套代码做调用,非常的麻烦。

这时候,我们就可以将这些重复的操作,比如做配置,写代码,这些过程抽取出来,作为一个feign-api组件,除了配置,代码,还有接收代码的实体类,以及所有有关的配置,方法,类都放在这个feign-api里面,当我们有某个服务要用的时候,直接引入这个feign-api组件,直接调用组件中的方法就可以了,这也是一种方式。

SpringCLoud——Feign的远程调用,SpringCloud,springcloud,中间件

方式二:抽取FeignClient

实现最佳实践方式二的步骤如下:

  1. 1.首先创建一个module,命名为feign-api,然后引入feign的starter依赖
  2. 2.将order-server中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中
  3. 3.在order-server中引入feign-api的依赖
  4. 4.修改order-server中所有与上述三个组件有关的import部分,改成导入feign-api中的包
  5. 5.重启测试

当我们都做完之后,会出现一个问题,就是在启动的时候,有时候在编译期间就已经会报错了,就是找不到我们对应的UserClient的实例对象:

SpringCLoud——Feign的远程调用,SpringCloud,springcloud,中间件

这是因为,在之前我们能自动注入,是因为我们在UserClient上写的@FeignClient在被SpringBoot扫描到之后,会自动的将对应的接口实例化成一个对象,然后注入到容器中,在我们要用的时候自动注入,但是此时我们的SpringBoot的启动类与我们的UserClient并不在一个类里面,所以无法扫描到这个注解,也就无法自动注入,这时候,我们需要在启动类的@EnableFeignClients上加上一个属性:basePackageClasses,他指向我们的UserClient的Class文件:

@EnableFeignClients(defaultConfiguration = FeignConfig.class,basePackageClasses = UserClient.class)

然后再回去看刚才报错的地方:

SpringCLoud——Feign的远程调用,SpringCloud,springcloud,中间件

此时报错就没有了。

然后我们正常启动项目,在浏览器访问之前的接口,如果能正常访问,则表示我们的Feign已经正常运行了。文章来源地址https://www.toymoban.com/news/detail-733276.html

到了这里,关于SpringCLoud——Feign的远程调用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringCloud 核心组件Feign【远程调用&自定义配置】

    目录 1,Feign远程调用 1.1:Feign概述 1.2:Feign替代RestTemplate         1):引入依赖         2):添加注解         3):编写Feign的消费服务,提供服务         4):测试         5):总结 1.3:自定义配置 1.3.1:配置文件方式 1.3.2:Java代码方式 Feign是一款Java语言编写的

    2023年04月08日
    浏览(77)
  • 39.SpringCloud—配置管理nacos、远程调用Feign、服务网关Gateway

    目录 一、SpringCloud。 (1)Nacos配置管理。 (1.1)nacos中添加配置文件、微服务引入依赖,并配置bootstrap.yml文件。 (1.2)获取配置文件信息,实现热更新。 (1.3)多环境配置共享。 (1.4)多服务共享配置。 (2)http客户端Feign。 (2.1)RestTemplate方式调用存在的问题。 (2.2)

    2024年02月10日
    浏览(70)
  • SpringCloud实用篇2——Nacos配置管理 Feign远程调用 Gateway服务网关

    Nacos除了可以做注册中心,同样可以做配置管理来使用。 当微服务部署的实例越来越多,达到数十、数百时,逐个修改微服务配置就会让人抓狂,而且很容易出错。我们需要一种统一配置管理方案,可以集中管理所有实例的配置。 Nacos一方面可以将配置集中管理,另一方可以

    2024年02月13日
    浏览(49)
  • SpringCloud Alibaba(一)微服务简介+Nacos的安装部署与使用+Nacos集成springboot实现服务注册+Feign实现服务之间的远程调用+负载均衡+领域划分

    目录 一.认识微服务 1.0.学习目标 1.1.单体架构 单体架构的优缺点如下: 1.2.分布式架构 分布式架构的优缺点: 1.3.微服务 微服务的架构特征: 1.4.SpringCloud 1.5Nacos注册中心 1.6.总结 二、Nacos基本使用安装部署+服务注册 (一)linux安装包方式单节点安装部署 1. jdk安装配置 2. na

    2024年02月09日
    浏览(45)
  • SpringCloud微服务环境中,使用Feign跨服务调用Api

    在微服务中,很多时候都需要调用其他小组的服务接口,这里记录一下使用Feign调用其他服务的过程。 第一步,导入依赖:  第二步,被调用服务编写接口:  第三步,调用服务端启动类上添加@EnableFeignClients  第四步,编写调用API接口,接口上添加@FeignClient注解,注解的na

    2024年02月10日
    浏览(37)
  • 【SpringCloud Alibaba】(四)使用 Feign 实现服务调用的负载均衡

    在上一文中,我们实现了服务的自动注册与发现功能。但是还存在一个很明显的问题:如果用户微服务和商品微服务在服务器上部署多份的话,之前的程序无法实现服务调用的负载均衡功能。 本文就带着大家一起实现服务调用的负载均衡功能 负载均衡:将原本由一台服务器

    2024年02月15日
    浏览(39)
  • SpringCloud框架 服务拆分和远程调用

    数据库隔离避免耦合度过高,不同模块将自己的业务暴露为接口,供其他微服务调用 微服务远程调用技术Rest 在后端实现发送http请求  1.在启动类/配置类里注册RestTemplate启动对象 2.注入Bean对象使用

    2024年04月25日
    浏览(45)
  • springcloud五大组件:Eureka:注册中心、Zuul:服务网关、Ribbon:负载均衡、Feign:服务调用、Hystix:熔断器

    Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。 SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。 Eureka包含两个组件:Eureka Server和Eure

    2024年04月10日
    浏览(43)
  • SpringCloud --- 认识微服务、服务拆分和远程调用

    随着互联网行业的发展,对服务的要求也越来越高,服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢?   单体架构 :将业务的所有功能集中在一个项目中开发,打成一个包部署。 单体架构的优缺点如下: 优点: 架构简单 部署成本低

    2024年02月01日
    浏览(40)
  • 【微服务 SpringCloud】实用篇 · 服务拆分和远程调用

    微服务(2) 本文将正式进入微服务框架SpringCloud和SpringCloudAlibaba的学习了,他们的工作就是微服务治理 任何分布式架构都离不开服务的拆分,微服务也是一样 服务拆分就是单个模块拆成多个模块,不过模块必须具有一定的独立性,这里我总结了微服务拆分时的几个原则:

    2024年02月08日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包