热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

十、SpringCloud实用篇_Feign远程调用

一、Feign远程调用Feign[feɪn]先来看我们以前利用RestTemplate发起远程调用的代码:存在下面的问题:代码可读性差,
一、Feign远程调用

Feign [feɪn]
先来看我们以前利用RestTemplate发起远程调用的代码:
在这里插入图片描述
存在下面的问题:

  • 代码可读性差,编码体验不统一
  • 参数复杂URL,难以维护

Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/feign
其作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题。
在这里插入图片描述

Feign is a Java to Http client binder inspired by Retrofit, JAXRS-2.0, and WebSocket. Feign’s first goal was reducing the complexity of binding Denominator uniformly to Http APIs regardless of ReSTfulness.
翻译:Feign是受Retrofit,JAXRS-2.0和WebSocket启发的Java到Http客户端绑定程序。 Feign的第一个目标是减少与ReSTfulness无关的将Denominator统一绑定到Http API的复杂性。
Feign是一个声明式的伪HTTP客户端,它使得写HTTP客户端变得更简单。使用Feign,只需要创建一个接口并注解。


1.1、Feign替代RestTemplate

Feign的使用步骤如下:

1.1.1、引入依赖

我们在order-service服务的pom文件中引入feign的依赖:

<dependency><groupId>org.springframework.cloudgroupId><artifactId>spring-cloud-starter-openfeignartifactId>
dependency>

在这里插入图片描述

1.1.2、添加注解

在order-service的启动类添加注解开启Feign的功能&#xff1a;
在这里插入图片描述

1.1.3、编写Feign的客户端

在order-service中新建一个接口&#xff0c;内容如下&#xff1a;

package com.xbmu.order.client;import com.xbmu.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;&#64;FeignClient("userservice")
public interface UserClient {&#64;GetMapping("/user/{id}")User findById(&#64;PathVariable("id") Long id);
}

这个客户端主要是基于SpringMVC的注解来声明远程调用的信息&#xff0c;比如&#xff1a;

  • 服务名称&#xff1a;userservice
  • 请求方式&#xff1a;GET
  • 请求路径&#xff1a;/user/{id}
  • 请求参数&#xff1a;Long id
  • 返回值类型&#xff1a;User

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

1.1.4、测试

修改order-service中的OrderService类中的queryOrderById方法&#xff0c;使用Feign客户端代替RestTemplate&#xff1a;
在这里插入图片描述
是不是看起来优雅多了。

多请求几次http://localhost:8080/order/101&#xff0c;发现UserApplication&#xff08;8082&#xff09;与UserApplication&#xff08;8081&#xff09;两个服务&#xff0c;都处理了请求。
在这里插入图片描述
由下图可见&#xff0c;Feign组件中已经引入了Ribbon实现负载均衡
在这里插入图片描述

1.1.5、总结

使用Feign的步骤:

  1. 引入依赖
  2. 添加&#64;EnableFeignClients注解
  3. 编写FeignClient接口
  4. 使用FeignClient中定义的方法代替RestTemplate

1.2、自定义配置

Feign可以支持很多的自定义配置&#xff0c;如下表所示&#xff1a;

类型作用说明
feign.Logger.Level修改日志级别包含四种不同的级别&#xff1a;NONE、BASIC、HEADERS、FULL
feign.codec.Decoder响应结果的解析器http远程调用的结果做解析&#xff0c;例如解析json字符串为java对象
feign.codec.Encoder请求参数编码将请求参数编码&#xff0c;便于通过http请求发送
feign. Contract支持的注解格式默认是SpringMVC的注解
feign. Retryer失败重试机制请求失败的重试机制&#xff0c;默认是没有&#xff0c;不过会使用Ribbon的重试

一般情况下&#xff0c;默认值就能满足我们使用&#xff0c;如果要自定义时&#xff0c;只需要创建自定义的&#64;Bean覆盖默认Bean即可。
下面以日志为例来演示如何自定义配置。

1.2.1、配置文件方式

基于配置文件修改Feign的日志级别可以针对单个服务&#xff1a;

feign:client:config: userservice: # 针对某个微服务的配置loggerLevel: FULL #日志级别

在这里插入图片描述
也可以针对所有服务&#xff1a;

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

在这里插入图片描述
测试&#xff0c;查看日志信息&#xff1a;
在这里插入图片描述
日志的级别分为四种&#xff1a;

  • NONE&#xff1a;不记录任何日志信息&#xff0c;这是默认值。
  • BASIC&#xff1a;仅记录请求的方法&#xff0c;URL以及响应状态码和执行时间
  • HEADERS&#xff1a;在BASIC的基础上&#xff0c;额外记录了请求和响应的头信息
  • FULL&#xff1a;记录所有请求和响应的明细&#xff0c;包括头信息、请求体、元数据。

1.2.2、Java代码方式

也可以基于Java代码来修改日志级别&#xff0c;先声明一个类&#xff0c;然后声明一个Logger.Level的对象&#xff1a;

package com.xbmu.order.config;import feign.Logger;
import org.springframework.context.annotation.Bean;public class DefaultFeignConfiguration {&#64;Beanpublic Logger.Level feignLogLevel(){return Logger.Level.BASIC; // 日志级别为BASIC}
}

在这里插入图片描述
如果要全局生效&#xff0c;将其放到启动类的&#64;EnableFeignClients这个注解中&#xff1a;

&#64;EnableFeignClients(defaultConfiguration &#61; DefaultFeignConfiguration.class)
在这里插入图片描述
如果要局部生效&#xff0c;则把它放到对应的&#64;FeignClient这个注解中&#xff1a;

&#64;FeignClient(value &#61; "userservice",configuration &#61; DefaultFeignConfiguration.class)
在这里插入图片描述

1.3、Feign使用优化

Feign底层发起http请求&#xff0c;依赖于其它的框架。其底层客户端实现包括&#xff1a;

  • URLConnection&#xff1a;默认实现&#xff0c;不支持连接池
  • Apache HttpClient&#xff1a;支持连接池
  • OKHttp&#xff1a;支持连接池

因此提高Feign的性能主要手段就是使用连接池代替默认的URLConnection
这里我们用Apache的HttpClient来演示。

1.3.1、引入依赖

在order-service的pom文件中引入Apache的HttpClient依赖&#xff1a;


<dependency><groupId>io.github.openfeigngroupId><artifactId>feign-httpclientartifactId>
dependency>

在这里插入图片描述

1.3.2、配置连接池

在order-service的application.yml中添加配置&#xff1a;

feign:client:config:default: # 这里用default就是全局配置&#xff0c;如果是写服务名称&#xff0c;则是针对某个微服务的配置loggerLevel: BASIC #日志级别&#xff0c;BASIC就是基本的请求和响应信息httpclient:enabled: true # 开启feign对HttpClient的支持max-connections: 200 # 最大的连接数max-connections-per-route: 50 # 每个路径的最大连接数

在这里插入图片描述
接下来&#xff0c;在FeignClientFactoryBean中的loadBalance方法中打断点&#xff1a;

Debug方式启动order-service服务&#xff0c;可以看到这里的client&#xff0c;底层就是Apache HttpClient&#xff1a;
在这里插入图片描述

1.3.3、总结

Feign的优化&#xff1a;

  1. 日志级别尽量用BASIC
  2. 使用HttpClient或OkHttp代替URLConnection
    引入feign-httpclient依赖
    配置文件开启httpclient功能&#xff0c;设置连接池 参数

1.4、最佳实践

所谓最佳实践&#xff0c;就是使用过程中总结的经验&#xff0c;最好的一种使用方式。
仔细观察可以发现&#xff0c;Feign的客户端于服务提供者的Controller代码非常相似&#xff1a;

Feign客户端&#xff1a;
在这里插入图片描述
UserController&#xff1a;
在这里插入图片描述
有没有一种办法简化这种重复的代码编写呢&#xff1f;

1.4.1、继承方式

一样的代码可以通过继承来共享&#xff1a;

  1. 定义一个API接口&#xff0c;利用定义方法&#xff0c;并基于SpringMVC注解做声明。
  2. Feign客户端和Controller都继承该接口。
    在这里插入图片描述

优点&#xff1a;

  • 简单
  • 实现了代码共享

缺点&#xff1a;

  • 服务提供方、服务消费方紧耦合

  • 参数列表中的注解映射并不会继承&#xff0c;因此Controller中必须再次声明方法、参数列表、注解


1.4.2、抽取方式

将Feign的Client抽取为独立模块&#xff0c;并且把接口有关的POJO、默认的Feign配置都放到这个模块中&#xff0c;提供给所有消费者使用。
例如&#xff0c;将UserClient、User、Feign的默认配置都抽取到一个feign-api包中&#xff0c;所有微服务引入该依赖包&#xff0c;即可直接使用。
在这里插入图片描述

1.4.3、实现基于抽取的最佳实践


1.4.3.1、抽取

首先创建一个module&#xff0c;命名为feign-api&#xff1a;
在这里插入图片描述
项目结构&#xff1a;
在这里插入图片描述
在feign-api中&#xff0c;引入feign的start依赖

<dependency><groupId>org.springframework.cloudgroupId><artifactId>spring-cloud-starter-openfeignartifactId>
dependency>

在这里插入图片描述
然后&#xff0c;order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中
在这里插入图片描述

1.4.3.2、在order-service中使用feign-api

首先&#xff0c;删除order-service中的UserClient、User、DefaultFeignConfiguration等类或接口。
在order-service的pom文件中引入feign-api的依赖&#xff1a;
在这里插入图片描述

1.4.3.3、重启测试

重启后&#xff0c;发现服务报错了&#xff1a;
在这里插入图片描述
这是因为UserClient现在在com.xbmu.feign.client包下&#xff0c;
而order-service的&#64;EnableFeignClients注解是在com.xbmu.order包下&#xff0c;不在同一个包&#xff0c;无法扫描到UserClient。

1.4.3.4、解决扫描包问题


  • 方式一&#xff1a;
    指定feign应用扫描的包&#xff1a;
    &#64;EnableFeignClients(basePackages &#61; "com.xbmu.feign.client")
    在这里插入图片描述
  • 方式二&#xff1a;
    指定需要加载的Client接口&#xff1a;
    &#64;EnableFeignClients(clients &#61; {UserClient.class})
    在这里插入图片描述
    重启&#xff0c;成功&#xff1a;
    在这里插入图片描述

推荐阅读
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • Android日历提醒软件开源项目分享及使用教程
    本文介绍了一款名为Android日历提醒软件的开源项目,作者分享了该项目的代码和使用教程,并提供了GitHub项目地址。文章详细介绍了该软件的主界面风格、日程信息的分类查看功能,以及添加日程提醒和查看详情的界面。同时,作者还提醒了读者在使用过程中可能遇到的Android6.0权限问题,并提供了解决方法。 ... [详细]
  • 本文介绍了贝叶斯垃圾邮件分类的机器学习代码,代码来源于https://www.cnblogs.com/huangyc/p/10327209.html,并对代码进行了简介。朴素贝叶斯分类器训练函数包括求p(Ci)和基于词汇表的p(w|Ci)。 ... [详细]
  • Sleuth+zipkin链路追踪SpringCloud微服务的解决方案
    在庞大的微服务群中,随着业务扩展,微服务个数增多,系统调用链路复杂化。Sleuth+zipkin是解决SpringCloud微服务定位和追踪的方案。通过TraceId将不同服务调用的日志串联起来,实现请求链路跟踪。通过Feign调用和Request传递TraceId,将整个调用链路的服务日志归组合并,提供定位和追踪的功能。 ... [详细]
  • 有意向可以发简历到邮箱内推.简历直达组内Leader.能做同事的话,内推奖励全给你. ... [详细]
  • 详解 Python 的二元算术运算,为什么说减法只是语法糖?[Python常见问题]
    原题|UnravellingbinaryarithmeticoperationsinPython作者|BrettCannon译者|豌豆花下猫(“Python猫 ... [详细]
  • zuul 路由不生效_Zuul网关到底有何牛逼之处?竟然这么多人在用~
    作者:kosamino来源:cnblogs.comjing99p11696192.html哈喽,各位新来的小伙伴们,大家好& ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • Firefox火狐浏览器关闭到http://detectportal.firefox.com的流量问题解决办法
    本文介绍了使用Firefox火狐浏览器时出现关闭到http://detectportal.firefox.com的流量问题,并提供了解决办法。问题的本质是因为火狐默认开启了Captive portal技术,当连接需要认证的WiFi时,火狐会跳出认证界面。通过修改about:config中的network.captive-portal-service.en的值为false,可以解决该问题。 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
author-avatar
yunzjyun
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有