微服务-Feign

文章目录

    • Feign介绍
    • Feign的基本使用
    • 自定义Feign的配置
    • Feign性能优化
    • Feign最佳实践

Feign介绍

RestTemplate远程调用存在的问题:代码可读性差,java代码中夹杂url;参数复杂很难维护

String url = "http://userservice/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);

Feign是一个声明式的http发送的客户端,用来替代RestTemplate;使用Feign可以通过直接写java接口发送http请求,而不需要定义url

在这里插入图片描述

Feign的基本使用

  1. 引入依赖
  2. 添加@EnableFeignClients注解
  3. 编写FeignClient接口
  1. 消费者(案例为order-service)中引入依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  1. 启动类中添加注解@EnableFeignClients
  2. 定义UserClient接口,该接口可以发送http请求,且写法与SpringMVC相似。接口添加@FeignClient注解,userservice表示该类使用的http请求是用来访问userservice服务的。
@FeignClient("userservice")
public interface UserClient {
    @GetMapping("user/{id}")
    User findById(@PathVariable("id")Long id);
}
  1. OrderService中使用UserClient接口发送http请求
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    //自动注入UserClient
    @Autowired
    UserClient userClient;

    public Order queryOrderById(Long orderId){
        Order order = orderMapper.findById(orderId);
        // 发送http请求,以order.getUserId()为参数
        User user = userClient.findById(order.getUserId());

        order.setUser(user);

        return order;
    }
}

以下是之前使用RestTemplate的OrderService

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    //获取restTemplate对象
    @Autowired
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        // 2.定义url
        // String url = "http://localhost:8081/user/"+order.getUserId();
        String url = "http://userservice/user/"+order.getUserId(); //修改为服务名
        // 3.发送http请求
        User user = restTemplate.getForObject(url, User.class);
        // 4.封装user
        order.setUser(user);
        // 5.返回
        return order;
    }
}
  1. 在浏览器中测试发送4次请求,http://localhost:8080/order/103。发现UserApplication和UserApplication2各自被访问两次。因此,Feign已经自动实现了负载均衡,在Feign的依赖中发现了Ribbon依赖。

在这里插入图片描述

自定义Feign的配置

在这里插入图片描述通常只需要配置日志级别

  1. 在application.yml中配置

配置日志级别有两种:1、全局配置,对所有访问的服务的http请求都有效;2、单个service配置,对某个服务进行配置

  • 全局配置
feign:
  client:
    config:
      default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
        loggerLevel: FULL # 日志级别

浏览器中测试,发现order-service访问userservice时控制台打印出来了很多http请求日志信息
在这里插入图片描述

  • 单个服务的配置
feign:
  client:
    config:
      userservice: # 针对userservice微服务的配置
        loggerLevel: FULL

测试发现,仍打印出了日志信息

  1. 使用java代码配置
    定义一个Feign配置类FeignClientConfiguration ,这里不用加@SpringBootConfiguration;
    然后声明一个Logger.Level的Bean
public class FeignClientConfiguration {

    @Bean
    public Logger.Level level(){
        return Logger.Level.BASIC; //只打印基础日志
    }
}

全局配置,直接在启动类中配置,注入添加的Feign配置类

@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)

局部配置,在对应的Client接口中配置,注入添加的Feign配置类
@FeignClient(value = “userservice”,configuration = FeignClientConfiguration.class)

@FeignClient(value = "userservice",configuration = FeignClientConfiguration.class)
public interface UserClient {
    @GetMapping("user/{id}")
    User findById(@PathVariable("id")Long id);
}

浏览器中测试,发现order-service访问userservice时控制台打印出来了基础的http请求日志信息
在这里插入图片描述

Feign性能优化

在这里插入图片描述

引入连接池的步骤

  1. 引入feign-httpclient依赖
<!--httpClient的依赖 -->
<dependency>    
	<groupId>io.github.openfeign</groupId>    
	<artifactId>feign-httpclient</artifactId>
</dependency>
  1. 在applicaiton.yml中配置httpclient或者okhttp,添加连接池参数
feign:
	httpclient:    # 使用的连接池
		enabled: true # 开启feign对HttpClient的支持    
		max-connections: 200 # 最大的连接数    
		max-connections-per-route: 50 # 每个路径的最大连接

Feign最佳实践

在这里插入图片描述
方式二:将FeignClient抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给所有消费者使用
在这里插入图片描述

  1. 首先创建一个module,命名为feign-api,然后引入feign的starter依赖
  2. 将order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中
  3. 在order-service中引入feign-api的依赖
  4. 修改order-service中的所有与上述三个组件有关的import部分,改成导入feign-api中的包
  5. 重启测试
  1. 创建module名叫feign-api,引入依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  1. 修改feign-api的包结构如下
    在这里插入图片描述

  2. 删除order-service中原有的UserClient,FeignClientConfiguration,User;修改后的order-service包结构如下
    在这里插入图片描述

  3. 在order-service的pom文件中引入feign-api依赖

<dependency>
    <groupId>cn.itcast.demo</groupId>
    <artifactId>feign-api</artifactId>
    <version>1.0</version>
</dependency>

在order-service重新导入UserClient,FeignClientConfiguration,User类,项目不再报红

在这里插入图片描述

  1. 启动,发现启动失败。OrdeApplication报错如下:UserClient的Bean不存在
Description:

Field userClient in cn.itcast.order.service.OrderService required a bean of type 'cn.itcast.feign.clients.UserClient' that could not be found.

The injection point has the following annotations:
	- @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'cn.itcast.feign.clients.UserClient' in your configuration.

前后的UserClient同样都加了@FeignClient注解,但现在没扫描到。原因是因为之前的UserClient在cn.itcast.order.clients包下面,而现在在cn.itcast.feign.clients包下面,但是spring创建对象时只能扫描到启动类所在包(cn.itcast.order)下面,因此并不会将UserClient创建对象放到spring容器中。

有以下解决方案

//方案一:在启动类的@EnableFeignClients注解后加入UserClient所在包basePackages = "cn.itcast.feign.clients"
@EnableFeignClients(basePackages = "cn.itcast.feign.clients")

//方案二(推荐):加入UserClient的字节码
@EnableFeignClients(clients = {UserClient.class})
  1. 修改OrderApplicaiton启动类后,测试。成功使用UserClient访问到userservice。
@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class,
                    clients = {UserClient.class}) //增加clients = {UserClient.class}
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/111737.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

纬创出售印度子公司给塔塔集团,结束iPhone代工业务 | 百能云芯

纬创&#xff08;Wistron&#xff09;董事会于10月27日通过决议&#xff0c;同意以1.25亿美元的价格出售其印度子公司Wistron InfoComm Manufacturing (India) Private Limited&#xff08;WMMI&#xff09;的100%股权给塔塔集团&#xff0c;交割将尽快完成。此举将意味着纬创退…

3ds Max2022安装教程(最新最详细)

目录 一.简介 二.安装步骤 网盘资源见文末 一.简介 3DS Max是由Autodesk公司开发的一款专业三维建模、动画和渲染软件&#xff0c;广泛应用于影视、游戏、建筑和工业设计等领域。 3DS Max的主要特点和功能包括&#xff1a; 三维建模&#xff1a;3DS Max提供了各种强大的建…

【Python 零基础入门】Numpy 常用函数

【Python 零基础入门】内容补充 3 Numpy 常用函数 概述Numpy 数组创建np.arangenp.linspace 数组操作reshapeflattenconcatenatesplitvstackhstack 数学运算add 相加subtract 相减multiply 相乘divide 相除 通用函数np.sqrt 平方根np.log 对数np.exp 指数np.sin 正弦 概述 Num…

如何有效使用蜂邮EDM和vba批量发送邮件?

蜂邮EDM和vba批量发送邮件的方法&#xff1f;怎么使用蜂邮EDM和vba代码群发电子邮件&#xff1f; 批量发送邮件已经成为一种不可或缺的沟通方式。蜂邮EDM和VBA是两个功能强大的工具&#xff0c;可以帮助您在邮件营销和业务通信中实现高效的批量发送邮件操作。接下来将介绍如何…

Java设置日期时间的毫秒数为0

背景 做一个发送短信的需求&#xff0c;采用RabbitMQ来实现定时发送。发送时需要验证发送短信任务的预计发送时间和生产者传过来的时间是否一致&#xff0c;一致才发送。 结果在调试的时候&#xff0c;却发现任务一直没法触发。一步步调试&#xff0c;发现是两个时间不相等。明…

理解springboot那些过滤器与调用链、包装或封装、设计模式相关等命名规范,就可以读懂80%的springboot源代码,和其他Java框架代码

紧接上面《 理解springboot那些注册与回调、监控与统计等命名规范,就可以读懂70%的springboot源代码》、《 理解springboot那些约定俗成的框架类名、全局context等命名规范,就可以读懂一半springboot的源代码》2篇文章,此片将汇总springboot那些过滤器与调用链、包装或封装…

【C++ 系列文章 -- 程序员考试 201811 下午场 C++ 专题 】

1.1 C 题目六 阅读下列说明和C代码&#xff0c;填写程序中的空&#xff08;1&#xff09; &#xff5e;&#xff08;5&#xff09;&#xff0c;将解答写入答题纸的对应栏内。 【说明】 以下C代码实现一个简单乐器系统&#xff0c;音乐类&#xff08;Music&#xff09;可以使用…

防雷接地测试方法完整方案

防雷接地是保障电力系统、电子设备和建筑物安全的重要措施&#xff0c;防雷接地测试是检验防雷接地装置是否合格的必要手段。本文介绍了防雷接地测试的原理、方法和注意事项&#xff0c;以及如何编写防雷接地测试报告。 地凯科技防雷接地测试的原理 防雷接地测试的基本原理是…

驱动开发11 编写iic驱动-读取温湿度数据

头文件 head.h #ifndef __HEAD_H__ #define __HEAD_H__ #define GET_HUM _IOR(m, 1, int) #define GET_TEM _IOR(m, 0, int) #endif 应用程序 si7006.c #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #inc…

高效学习工具之AnkiMobile新手入门指南(ios端,包括ipad、ihpone设备)————创建、使用、备份、设置参数、相关资料

文章目录 0 背景0.1 闭环学习0.2 什么是anki0.3 anki践行者经验分享 1 开始使用1.1 导入1.2 创建空白组1.3 创建卡片1.3.1 利用anki创建卡片的两种方法1.3.2 复习材料分类 1.4 筛选&#xff08;做减法&#xff0c;拆分学习&#xff08;做子卡牌集合&#xff09;&#xff09;&am…

4.1 继承

思维导图&#xff1a; 第4章 面向对象(下) 学习目标: 了解面向对象中的继承特性&#xff0c;掌握继承的概念与特点。掌握方法的重写&#xff0c;能够在子类中重写父类方法。掌握super关键字&#xff0c;明白如何在类中使用super访问父类成员。理解final关键字的作用&#xff0…

微信小程序如何使用地球半径计算两组经纬度点之间的距离(自身位置与接口返回位置)【上】

目录 1.配置位置权限 2.获取当前自身经纬度 3. 请求接口拿到返回经纬 4. 循环取每一项的经纬 5.如何判断是否打开了定位权限 6.进行距离计算操作 7.运行效果 8.完整代码 首先在使用小程序时&#xff0c;请求的接口一定要去配置合法域名&#xff0c;才能够进行接下来…

缓存击穿只会逻辑过期 OR 互斥锁?深入思考 == 鹤立鸡群

网上但凡看得见的文章&#xff0c;大部分在说缓存穿透时都是无脑分布式锁 / 逻辑过期&#xff0c;分布式锁一点问题都没有么&#xff1f;逻辑过期一点问题都没有么&#xff1f;还能不能再进一步优化&#xff1f; 在聊聊缓存击穿的双重判定锁之前&#xff0c;我们将按照循循渐进…

双十一首日捷报 | 德施曼率先破亿,再度蝉联智能锁品类第一

10月31日晚8:00&#xff0c;各大平台迎来了双十一第一波现货开售。其中&#xff0c;在智能锁类目中德施曼势头最为迅猛&#xff0c;此前&#xff0c;德施曼凭借“全民换锁季”主题活动&#xff0c;在预售期间就已经全面引爆消费者换锁热潮&#xff0c;随着此次现货开售&#xf…

cut 命令

cut [选项参数] filename #默认分隔符是制表符 选项参数&#xff1a; -d delimiter 分隔符 -f field 场地、领域&#xff08;第几列&#xff09; 命令使用&#xff1a; cut -d " " -f 1 cut.txt #空格为分隔符截取第1列cut -d " " -f 2,3 cut.txt #截…

百度上传自己个人简介攻略,个人介绍百度百科怎么做?

个人介绍要展示在百度百科上该怎么操作&#xff0c;我们都清楚百度百科词条是需要申请才能拥有的&#xff0c;但是没有百度上传自己个人简介的攻略&#xff0c;很多人是不知从何下手的。下面洛希爱做百科网带着大家一起来了解。 一、了解百度百科词条的创建规则 1. 词条名称规…

jdk官网下载(详细步骤)

jdk全部版本下载网址 Java Archive | Oraclehttps://www.oracle.com/java/technologies/downloads/archive/ 下载之前先建立oracle账号(免费创建)&#xff0c;不用特意去搜&#xff0c;你点击下载jdk的时候会自动弹出来&#xff0c;自己建立一个账号就能下载了 找到自己要下载…

【产品体验】OA办公系统

一、演示地址 http://admin.dianshixinxi.com:90/index 二、办公管理功能 1.我的待办&#xff1a;当前登录用户&#xff0c;办理任务 2.通知公告&#xff1a;通知与公告&#xff0c;已发布通知公告会显示在首页 3.自定义表单&#xff1a;自定义表单&#xff0c;托拉拽的形式…

iZotope RX 10(音频修复和增强工具)

iZotope RX 10是一款音频修复和增强软件&#xff0c;主要特点包括&#xff1a; 声音修复&#xff1a;iZotope RX 10可以去除不良噪音、杂音、吱吱声等&#xff0c;使音频变得更加清晰干净。音频增强&#xff1a;iZotope RX 10支持对音频进行音量调节、均衡器、压缩器、限制器等…

IDEA 使用技巧

文章目录 语言支持简化编写 有问题&#xff0c;可暂时跳过 个人常用快捷键插件主题插件功能插件 碰到过的问题 除了一些在Linux上用vim开发的大佬&#xff0c;idea算是很友好的集成开发工具了&#xff0c;功能全面&#xff0c;使用也很广泛。 记录一下我的 IDEA 使用技巧&#…