SpringCloud-OpenFeign组件的使用

  • 思考: 使用RestTemplate+ribbon已经可以完成服务间的调用,为什么还要使用feign?
String restTemplateForObject = restTemplate.getForObject("http://服务名/url?参数" + name, String.class);

存在问题:

  • 1.每次调用服务都需要写这些代码,存在大量的代码冗余
  • 2.服务地址如果修改,维护成本增高
  • 3.使用时不够灵活

说明

  • https://cloud.spring.io/spring-cloud-openfeign/reference/html/
  • Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性(可以使用springmvc的注解),可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,默认实现了负载均衡的效果并且springcloud为feign添加了springmvc注解的支持。

1.openFeign 服务调用

还是在上一个项目的基础之上,在users项目中

1.服务调用方法引入依赖OpenFeign依赖

<!--Open Feign依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2.入口类加入注解开启OpenFeign支持

@SpringBootApplication
@EnableFeignClients   //开启openfeign支持
public class Users9999Application {
    public static void main(String[] args) {
        SpringApplication.run(Users9999Application.class, args);
    }
}

3.创建一个客户端调用接口

// 此时的product项目中的方法
@RestController
@Slf4j
public class ProductController {

    @Value("${server.port}")
    private int port;

    @GetMapping("/product/findAll")
    public Map<String, Object> findAll(){
        log.info("商品服务调用成功,当前的服务端口:[{}]",port);
        HashMap<String, Object> map = new HashMap<>();
        map.put("msg","服务调用成功,服务提供的端口为:"+port);
        map.put("status",true);
        return map;
    }
}

//--------------------------------------------------------------------
package com.md.clients;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * @author md
 * @Desc 调用商品服务的组件
 * @date 2020/12/9 15:30
 */

// 指定当前的接口是openfeign组件,value是调用的服务名
@FeignClient("products")
public interface ProductClient {

    @GetMapping("/product/findAll")
    String findAll();
}

4.使用feignClient客户端对象调用服务

@RestController
@Slf4j
public class UserController {

//注入客户端对象
@Autowired
private ProductClient productClient;

@GetMapping("/user/findAllFeignClient")
public String findAllFeignClient(){
  log.info("通过使用OpenFeign组件调用商品服务...");
  String msg = productClient.findAll();
  return msg;
}
}

5.访问并测试服务

2.调用服务并传参

  • 服务和服务之间通信,不仅仅是调用,往往在调用过程中还伴随着参数传递,接下来重点来看看OpenFeign在调用服务时如何传递参数

3.GET方式调用服务传递参数

  • 在商品服务中加入需要传递参数的服务方法来进行测试
  • 在用户服务中进行调用商品服务中需要传递参数的服务方法进行测试

1.商品服务中添加如下方法

 @GetMapping("/product/findOne")
public Map<String,Object> findOne(String productId){
  log.info("商品服务查询商品信息调用成功,当前服务端口:[{}]",port);
  log.info("当前接收商品信息的id:[{}]",productId);
  Map<String, Object> map = new HashMap<String,Object>();
  map.put("msg","商品服务查询商品信息调用成功,当前服务端口: "+port);
  map.put("status",true);
  map.put("productId",productId);
  return map;
}

2.用户服务中在product客户端中声明方法

//
@FeignClient("products")
public interface ProductClient {
@GetMapping("/product/findOne")
  Map<String, Object> findOne(@RequestParam("productId") String productId);
}

注意:使用openfeign的get方式传递参数,参数变量必须通过@RequestParam注解进行修饰

3.用户服务中调用并传递参数

//
//注入客户端对象
@RestController
@Slf4j
public class UserController {

    @Autowired
    private ProductClient productClient;

      @GetMapping("/user/findOne")
      public Map<String, Object> findOne(String productId){
          log.info("用来测试Openfiegn的GET方式参数传递");
          Map<String, Object> msg = productClient.findOne(productId);
          log.info("调用返回信息:[{}]",msg);
          return msg;
      }
}

4.测试访问

4.post方式调用服务传递参数

  • 在商品服务中加入需要传递参数的服务方法来进行测试
  • 在用户服务中进行调用商品服务中需要传递参数的服务方法进行测试

1.商品服务加入post方式请求并接受name

@PostMapping("/product/save")
public Map<String,Object> save(String name){
  log.info("商品服务保存商品调用成功,当前服务端口:[{}]",port);
  log.info("当前接收商品名称:[{}]",name);
  Map<String, Object> map = new HashMap<String,Object>();
  map.put("msg","商品查询服务完成当前服务端口: "+port);
  map.put("status",true);
  map.put("name",name);
  return map;
}

2.用户服务中在product客户端中声明方法

//value属性用来指定:调用服务名称
@FeignClient("products")
public interface ProductClient {
    @PostMapping("/product/save")
    String save(@RequestParam("name") String name);
}

3.用户服务中调用并传递参数

@Autowired
private ProductClient productClient;

@PostMapping("/user/save")
public Map<String, Object> save(String productName){
  log.info("接收到的商品信息名称:[{}]",productName);
  Map<String, Object> map = productClient.save(productName);
  log.info("调用成功返回结果: "+map);
  return map;
}

4.测试访问

5.传递对象类型参数

  • 商品服务定义对象
  • 商品服务定义对象接收方法
  • 用户服务调用商品服务定义对象参数方法进行参数传递
//1.商品服务定义对象
@Data
public class Product {
    private Integer id;
    private String name;
    private Date bir;
}
//2.商品服务定义接收对象的方法
@PostMapping("/product/saveProduct")
public Map<String,Object> saveProduct(@RequestBody Product product){
  log.info("商品服务保存商品信息调用成功,当前服务端口:[{}]",port);
  log.info("当前接收商品名称:[{}]",product);
  Map<String, Object> map = new HashMap<String,Object>();
  map.put("msg","商品服务查询商品信息调用成功,当前服务端口: "+port);
  map.put("status",true);
  map.put("product",product);
  return map;
}

//3.将商品对象复制到用户服务中
// 先阶段先这样用着

//4.用户服务中在product客户端中声明方法
@FeignClient("products")
public interface ProductClient {
  @PostMapping("/product/saveProduct")
  String saveProduct(@RequestBody Product product);
}
//注意:服务提供方和调用方一定要加入@RequestBody注解

注意:服务提供方和调用方一定要加入@RequestBody注解

// 5.在用户服务中调用保存商品信息服务
//注入客户端对象
@Autowired
private ProductClient productClient;

@PostMapping("/user/saveProduct")
    public Map<String, Object> saveProduct(Product product){
        log.info("接收到的商品信息:[{}]",product);
        Map<String, Object> map = productClient.saveProduct(product);
        log.info("调用成功返回结果: "+map);
        return map;
    }

测试

5.OpenFeign超时设置

1.超时说明

  • 默认情况下,openFiegn在进行服务调用时,要求服务提供方处理业务逻辑时间必须在1S内返回,如果超过1S没有返回则OpenFeign会直接报错,不会等待服务执行,但是往往在处理复杂业务逻辑是可能会超过1S,因此需要修改OpenFeign的默认服务调用超时时间。

2.模拟超时

  • 服务提供方加入线程等待阻塞

3.进行客户端调用

4.修改OpenFeign默认超时时间

# 这里的PRODUCTS使用的是大写的方法
feign.client.config.PRODUCTS.connectTimeout=5000  #配置指定服务连接超时
feign.client.config.PRODUCTS.readTimeout=5000  #配置指定服务等待超时
#feign.client.config.default.connectTimeout=5000  #配置所有服务连接超时
#feign.client.config.default.readTimeout=5000#配置所有服务等待超时

6.OpenFeign调用详细日志展示

0.说明

  • 往往在服务调用时我们需要详细展示feign的日志,默认feign在调用是并不是最详细日志输出,因此在调试程序时应该开启feign的详细日志展示。feign对日志的处理非常灵活可为每个feign客户端指定日志记录策略,每个客户端都会创建一个logger默认情况下logger的名称是feign的全限定名需要注意的是,feign日志的打印只会DEBUG级别做出响应。
  • 我们可以为feign客户端配置各自的logger.level对象,告诉feign记录那些日志logger.lever有以下的几种值
    NONE 不记录任何日志 BASIC 仅仅记录请求方法,url,响应状态代码及执行时间
    HEADERS 记录Basic级别的基础上,记录请求和响应的header FULL 记录请求和响应的header,body和元数据

1.开启日志展示

# 这里的PRODUCTS使用的是大写的方法
feign.client.config.PRODUCTS.loggerLevel=full  #开启指定服务日志展示
#feign.client.config.default.loggerLevel=full  #全局开启服务日志展示
logging.level.com.baizhi.feignclients=debug    #指定feign调用客户端对象所在包,必须是debug级别

2.测试服务调用查看日志

(0)

相关推荐

  • Spring Boot 2.0 的配置绑定类Bindable居然如此强大

    Spring Boot 2.0 的配置绑定类Bindable居然如此强大

  • jackson学习之八:常用方法注解

    https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS等: 系列文章汇总 jac ...

  • 填坑系列之OpenFeign(一)

    前提 使用OpenFeign构建微服务消费端,发送带参请求时,控制台报错: Servlet.service() for servlet [dispatcherServlet] in context w ...

  • Spring Cloud OpenFeign 动态Url

    版权声明:本文为CSDN博主「markix」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明. 原文链接: https://blog.csdn.net/qq_31772 ...

  • spring 框架常用注解

    spring 框架常用注解

  • 再见,HttpClient!再见,Okhttp!

    作者:元人部落 来源:www.cnblogs.com/bryan31/p/13359376.html 1.背景 因为业务关系,要和许多不同第三方公司进行对接.这些服务商都提供基于http的api.但是 ...

  • springboot~feign模拟multipart/form-data

    openfeign介绍 在微服务设计里,服务之间的调用是很正常的,通常我们使用httpClient来实现对远程资源的调用,而这种方法需要知识服务的地址,业务接口地址等,而且需要等他开发完成后你才可以去 ...

  • SpringCloud-Hystrix组件使用

    https://github.com/Netflix/Hystrix 在分布式环境中,许多服务依赖项不可避免地会失败.Hystrix是一个库,它通过添加延迟容忍和容错逻辑来帮助您控制这些分布式服务之间 ...

  • 反射之Type类

    原文链接http://zhhll.icu/2020/08/17/java%E5%9F%BA%E7%A1%80/%E5%8F%8D%E5%B0%84/%E5%8F%8D%E5%B0%84%E4%B9%8 ...

  • springcloud组件技术分享(推荐)

    目录 1. 项目初始化配置 2. Eureka 3. Ribbon 4. Feign学习 5. hystrix学习 6. springboot的健康监控actuator 7. feign配合Hystr ...

  • springcloud组件技术分享

    目录1. 项目初始化配置2. Eureka3. Ribbon4. Feign学习5. hystrix学习6. springboot的健康监控actuator7. feign配合Hystrix使用8. ...

  • 光伏产业研究-组件环节

           前两篇推文我们总结了硅料.硅片以及电池片环节,本篇就是组件环节啦! 由于单片太阳电池片输出电压较低,未封装的电池片由于环境的影响电极容易脱落,因此必须将一定数量的单片电池采用串.并联的方 ...

  • 组件企业业绩简析

    本文将对隆基.晶澳.天合三家公司20年业绩和2021年一季度业绩进行简要分析. 对于这三家组件龙头企业,按理说应该花很长的篇幅去阐述.去细致的分析其业绩,并给出相关的论据.论点.但在我们将年报.季报看 ...

  • 【特医食品】浦索—特殊医学用途蛋白质组件配方粉

    按照2016版的中国居民膳食指南和营养学家推荐,成人每天需要1g/kg体重的蛋白质才能满足身体需求,对于运动量大的人群来说,因为蛋白质需求更大,需要1.5-1.8g/kg体重去摄入. 目前我们年轻一代 ...

  • UG英制转公制简单方法及UG装配:该组件与显示部件的单位不同,因此不能作为工作部件

    英制部件 导出部件 新建部件注意为毫米单位 导入刚才的部件,会出现此对话框,按确定 测量后发现部件尺寸大,实际是把英寸放大了,让后缩放体就行了 缩放体比例因子 缩放后测量尺寸正常

  • SpringCloud SpringBoot OAuth2 Spring Security Redi...

    来自:CSDN,作者:myCat 链接:https://blog.csdn.net/WYA1993/article/details/85050120 开发环境: Windows10 Intellij ...

  • 中间件:ElasticSearch组件RestHighLevelClient用法详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.基础API简介 1.RestHighLevelClient RestHighLevelClient的API作为ElasticSearch备 ...

  • go好用的类型转换第三方组件

    Cast介绍 开源地址 https://github.com/spf13/cast Cast是什么? Cast是一个库,以一致和简单的方式在不同的go类型之间转换. Cast提供了简单的函数,可以轻松 ...

  • 360安全浏览器服务组件是什么?怎么彻底删除?

    最近有用户反馈系统中总是有360安全浏览器服务组件在运行,开机就有,显而易见360安全浏览器服务组件是360浏览器的一个组件,那么这个360安全浏览器服务组件是什么,干什么用的呢?也有用户问如何才能彻 ...