微服务之同步远程调用(Feign)(微服务远程调用方式)

  本篇文章为你整理了微服务之同步远程调用(Feign)(微服务远程调用方式)的详细内容,包含有微服务同步异步 微服务远程调用方式 微服务之间调用feign 微服务数据同步 微服务之同步远程调用(Feign),希望能帮助你了解 微服务之同步远程调用(Feign)。

  微服务的服务提供者和服务消费者解耦合之后,我们可以借助restTemplate这样的HTTP客户端,向微服务的服务提供者发起远程调用;

  但是这样的代码有2大缺陷:

  
Order order = orderMapper.selectById(orderId);

   //2.调用user-service服务查询当前订单的用户信息

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

   //使用RestTemplate发起远程调用

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

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

   //3.user封装到order对象

   order.setUser(user);

   // 4.返回

   return order;

   }

 

 

  

  一、SpringCloud项目搭建

  鉴于微服务架构中职责单一性原则,2个微服务使用单独的数据库;

  如果用户微服务需要查询订单微服务的数据,就需要使用Feign发起远程调用;

  在远程调用过程中user-service是消费者order-service是生产者;

  1.搭建流程图

  2.搭建父项目

  2.1.父项目依赖版本锁定

  

 ?xml version="1.0" encoding="UTF-8"? 

 

   project xmlns="http://maven.apache.org/POM/4.0.0"

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"

   modelVersion 4.0.0 /modelVersion

   groupId com.zhanggen /groupId

   artifactId spring-cloud-demo /artifactId

   version 1.0-SNAPSHOT /version

   !--在打包的时候被打成jar,会被作为管理模块去编译--

   packaging pom /packaging

   父项目中引入spring-boot-starter-parent继承Spring-boot的核心包

   子项目的spring-starter才可以被启动

   parent

   groupId org.springframework.boot /groupId

   artifactId spring-boot-starter-parent /artifactId

   version 2.3.9.RELEASE /version

   relativePath/

   /parent

   !--dependencyManagement进行版本锁定,不会真正引入依赖包--

   dependencyManagement

   dependencies

   !-- 给spring-cloud提供的Feign、Gateway、Eureka等提供版本锁定 --

   dependency

   groupId org.springframework.cloud /groupId

   artifactId spring-cloud-dependencies /artifactId

   version Hoxton.SR10 /version

   type pom /type

   scope import /scope

   /dependency

   !-- 给spring-cloud-alibaba提供的Nacos、Sentinel、Dubbo等提供版本锁定 --

   dependency

   groupId com.alibaba.cloud /groupId

   artifactId spring-cloud-alibaba-dependencies /artifactId

   version 2.2.6.RELEASE /version

   type pom /type

   scope import /scope

   /dependency

   /dependencies

   /dependencyManagement

   modules

   module user-service /module

   module order-service /module

   /modules

  
3.1.子项目依赖导入

  

 ?xml version="1.0" encoding="UTF-8"? 

 

   project xmlns="http://maven.apache.org/POM/4.0.0"

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"

   parent

   artifactId spring-cloud-demo /artifactId

   groupId com.zhanggen /groupId

   version 1.0-SNAPSHOT /version

   /parent

   modelVersion 4.0.0 /modelVersion

   artifactId order-service /artifactId

   dependencies

   !--在子项中引入spring-boot-starter-web依赖--

   dependency

   groupId org.springframework.boot /groupId

   artifactId spring-boot-starter-web /artifactId

   /dependency

   !--在子项中引入nacos依赖--

   dependency

   groupId com.alibaba.cloud /groupId

   artifactId spring-cloud-starter-alibaba-nacos-discovery /artifactId

   /dependency

   !--在子项中引入feign基本依赖--

   dependency

   groupId org.springframework.cloud /groupId

   artifactId spring-cloud-starter-openfeign /artifactId

   /dependency

   !--在子项中引入httpclient依赖,添加后feign支持连接池--

   dependency

   groupId io.github.openfeign /groupId

   artifactId feign-httpclient /artifactId

   /dependency

   /dependencies

  
3.2.application配置文件

  

server:

 

   port: 9090

  spring:

   application:

   name: order-service

   cloud:

   nacos:

   discovery:

   server-addr: 127.0.0.1:8848

 

  application.yml

  

  二、Feign介绍

  Feign是1个声明式的HTTP客户端,通过HTTP协议使得调用远程服务就像调用本地服务一样简单,只需要创建一个接口并添加一个注解即可。

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

  而且Feign默认集成了Ribbon,所以使用Feign默认就实现了客户端负载均衡的效果。

  

  三、Feign使用

  1.引入依赖

  

 !--feign的依赖-- 

 

   dependency

   groupId org.springframework.cloud /groupId

   artifactId spring-cloud-starter-openfeign /artifactId

   /dependency

 

  

  2.添加@EnableFeignClients注解

  该注解配置在调用者的启动类上,以至于可以调用被调用这;

  在order-service的启动类添加注解开启Feign的功能;

  

@MapperScan("com.zhanggen.order.mapper")

 

  @SpringBootApplication

  @EnableDiscoveryClient

  @EnableFeignClients //开启Feign

  public class OrderApplication {

   public static void main(String[] args) {

   SpringApplication.run(OrderApplication.class, args);

   }
 

   @Bean

   @LoadBalanced

   public RestTemplate restTemplate() {

   return new RestTemplate();

  }

 

  

  3.编写Feign的客户端

  服务提供者提供接口以至于服务调用者可以调用;

  在order-service项目中com.zhanggen.order.mapper包下新建一个接口,内容如下:

  

//FeignClient必须和@EnableFeignClients标注的类在同一个包下

 

  //该接口用于向user-service微服务发起远程调用

  //Feign底层默认使用HTTP协议发起远程调用

  //@FeignClient("user-service")+@GetMapping("/user/{id}")确定服务提供者的URL(http://user-service/user/{id})

  @FeignClient("user-service")

  public interface UserClient {

   //根据userId查询用户信息

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

   User findById(@PathVariable Long id);

  }

 

  这样,Feign就可以帮助我们发送http请求,无需自己使用RestTemplate来发送了。

  

  4.修改OrderService类

  是不是看起来优雅多了。

  

//使用Feign发起远程调用

 

   @Autowired

   private UserClient userClient;

   public Order findById(Long orderId) {

   // 1.查询订单

   Order order = orderMapper.selectById(orderId);

   //2.调用user-service服务查询当前订单的用户信息

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

   //使用RestTemplate发起远程调用

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

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

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

   //3.user封装到order对象

   order.setUser(user);

   // 4.返回

   return order;

   }

 

  

  四、Feign配置

  Feign可以支持很多的自定义配置,如下表所示:

  
修改日志级别

  包含四种不同的级别:NONE(默认)、BASIC、HEADERS、FULL NONE,不记录。默认选项 BASIC,仅记录请求方法和URL以及响应状态代码和执行时间。 HEADERS,记录基本信息以及请求和响应标头。 FULL,记录请求和响应的标题,正文和元数据。

  
请求参数编码

  将请求参数编码,便于通过http请求发送,例如POST请求,将请求参数编码到请求体中

  
失败重试机制

  请求失败的重试机制,默认是没有,不过会使用Ribbon的重试,例如A服务无法访问,会尝试访问集群中的B服务

  
一般情况下,Feign的默认配置就能满足我们使用,如果要自定义配置时,只需要创建自定义的@Bean覆盖默认Bean即可。

  下面以日志为例来演示如何自定义配置,修改Feign日志有 2 种方式: 配置文件方式、Java代码方式

  1.配置文件方式(推荐)

  基于配置文件修改feign的日志级别可以针对单个服务:

  

feign: 

 

   client:

   config:

   user-service: # 针对某个微服务的配置,也可以针对所有服务,这个位置换成default

   loggerLevel: FULL # 日志级别

 

  2.Java代码方式

  也可以基于Java代码来修改日志级别,在com.zhanggen.order.config包下创建类,然后声明一个Logger.Level的对象:

  

package com.zhanggen.order.config;

 

  import feign.Logger;

  import org.springframework.context.annotation.Bean;

  public class FeignDefaultConfiguration {

   @Bean

   public Logger.Level feignLogLevel(){

   return Logger.Level.FULL; // 日志级别为FULL

  }

 

  2.1.配置局部

  如果我想让以上日志配置在调用某1个服务提供者时生效,在FeigClien接口中修改如下;

  

@FeignClient(value = "user-service",configuration = FeignDefaultConfiguration.class)

 

  public interface UserClient {

   //根据userId查询用户信息

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

   User findById(@PathVariable Long id);

  }

 

  2.2.配置全局

  如果我想让以上日志配置在调用任意服务提供者时生效,在启动类上修改如下;

  

@EnableFeignClients(defaultConfiguration = FeignDefaultConfiguration.class)

 

  public class OrderApplication {

   public static void main(String[] args) {

   SpringApplication.run(OrderApplication.class, args);

   }

 

  

  五、Feign连接池

  Feign底层发起http请求,依赖于其它的框架。其底层客户端实现包括:

  
2.application.yml配置

  max-connections-per-route:再调用某1个服务提供者时,最多从连接池中拿出50个连接发起远程调用,避免服务雪崩;

  

feign:

 

   httpclient:

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

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

   max-connections-per-route: 50 # 并行接收一个服务的请求数量

  

 

  

  六、Feign公共模块

  在微服务架构中肯定会存在多个服务消费者,这些服务消费者都需要借助Feign发起远程调用;

  在实际的分布式架构开发中我们一般把Feign抽取出来作为1个公共模块,以便于其他微服务模块使用;

  

  1.创建feign-api公共模块

  把之前在order-service中编写的UserClient、User、FeignDefaultConfiguration剪切到feign-api项目中

  在fein-api模块中添加spring-cloud-starter-openfeign依赖

  

 dependencies 

 

   !--openfeign依赖--

   dependency

   groupId org.springframework.cloud /groupId

   artifactId spring-cloud-starter-openfeign /artifactId

   /dependency

   !--mybatis-plus 实体类注解要用到--

   dependency

   groupId com.baomidou /groupId

   artifactId mybatis-plus-core /artifactId

   version 3.4.0 /version

   /dependency

   !--httpclient基于连接池的调用--

   dependency

   groupId io.github.openfeign /groupId

   artifactId feign-httpclient /artifactId

   /dependency

   /dependencies

 

  

  2.服务消费者(调用方)

  2.1.引入公共模块

  服务消费者pom文件引入feign-api公共模块的依赖;

  

 dependency 

 

   groupId com.zhanggen /groupId

   artifactId fein-api /artifactId

   version 1.0-SNAPSHOT /version

   /dependency

 

  2.2.启动类

  服务消费者启动类设置@EnableFeignClients注解一定要设置Feign公共模块中的配置类和Feign公共模块的包;

  

@EnableFeignClients(defaultConfiguration = FeignDefaultConfiguration.class,

 

   basePackages = "com.zhanggen.feign")

  public class OrderApplication {

   public static void main(String[] args) {

   SpringApplication.run(OrderApplication.class, args);

  }

 

  服务消费者配置文件

  如果遇到调用超时问题,可以在服务消费者的配置文件中设置一下超时时间

  

feign:

 

   client:

   config:

   default:

   #不设置connectTimeout会导致readTimeout设置不生效

   connectTimeout: 3000

   readTimeout: 6000

 

  2.3.Feign常见报错

  Did you forget to include spring-cloud-starter-netflix-ribbon?

  

 dependency 

 

   groupId com.alibaba.cloud /groupId

   artifactId spring-cloud-starter-alibaba-nacos-discovery /artifactId

   /dependency

 

  

  3.服务提供者(被调用方)

  创建1个client包专门对内面向Feign远程调用,而controller包专门对外面向前端调用;

  

  

  参考

  以上就是微服务之同步远程调用(Feign)(微服务远程调用方式)的详细内容,想要了解更多 微服务之同步远程调用(Feign)的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: