客户端远程调用Feign
客户端远程调用
Feign
什么是Feign?
Feign是 Netflix 公司开源的声明式HTTP客户端
Github : Feign 源码
为什么需要Feign?
- 原代码可读性不高
- 复杂的URL难以维护(
https://user-center/s?wd={userId}&rsv_spt=1&rsv_iqid=0x93bff3cd000cf3da&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_sug3=4&rsv_sug1=4&rsv_sug7=100&rsv_t=10c2risCimsUZC0RBruMerdnQRN1gRxFI%2BywuD0L3LwGGNd2dR8XE6x%2FyFOjHnR0oEi0&rsv_sug2=0&inputT=1535&rsv_sug4=1535&rsv_sug=2) - 难以应对需求的快速变化
- 编码体验和我们写JAVA差异较大
举例重构代码
//替换前
ResponseEntity<UserDTO> userEntity = restTemplate.getForEntity(
"http://user-center/users/{userId}",
UserDTO.class, userId
);
UserDTO userDTO = new UserDTO();
if (null != userEntity) {
userDTO = userEntity.getBody();
log.info("ShareService#findById userDTO: {}", userDTO);
}
- 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 启动类添加注解
@EnableFeignClients - 添加配置
- 实现对应微服务的client
/**
* IUserCenterFeignClient for 定义 user-center feign client
*
* @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
* @since 2019/7/15
*/
@FeignClient(name = "user-center")
public interface IUserCenterFeignClient {
/**
* Feign client 会将请求转换为
* http://user-center/users/{userId}
*
* @param userId 用户id
* @return 返回用户对象
*/
@GetMapping(path = "/users/{userId}")
public UserDTO findById(@PathVariable Long userId);
}
- 替换后代码
//使用 FeignClient 来替换掉RestTemplate调用
UserDTO userDTO = this.userCenterFeignClient.findById(userId);
Feign的组成

Feign的配置方式
Java Code
支持的配置项

自定义Feign日志级别
- 级别内容

Demo
**Tip **: 有可能出现父子上下文重叠问题
- 在client添加配置
/**
* IUserCenterFeignClient for 定义 user-center feign client
*
* @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
* @since 2019/7/15
*/
@FeignClient(name = "user-center",configuration = UserCenterFeignConfiguration.class)
public interface IUserCenterFeignClient {
...
}
- 编写java配置文件
/**
* UserCenterFeignConfiguration for 自定义user-center服务请求中,feign的配置信息
* {@link @Configuration} 不能添加该注解,否则会和ribbon一样,出现上下文重叠问题,造成配置全局共享
* 如要添加该注解,需要将该类放在主程序启动扫描不到的包下
*
* @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
* @since 2019/7/15
*/
public class UserCenterFeignConfiguration {
@Bean
public Logger.Level level() {
// 配置feign 日志级别,记录请求和响应的header、body以及元数据
return Logger.Level.FULL;
}
}
一定要在配置文件中添加该client 全路径
logging:
level:
#com.sxzhongf: debug
com.sxzhongf.sharedcenter.feignclients.IUserCenterFeignClient: debug
打印信息
2019-07-15 15:06:11.650 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient : [IUserCenterFeignClient#findById] <--- HTTP/1.1 200 (402ms)
2019-07-15 15:06:11.651 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient : [IUserCenterFeignClient#findById] content-type: application/json;charset=UTF-8
2019-07-15 15:06:11.651 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient : [IUserCenterFeignClient#findById] date: Mon, 15 Jul 2019 07:06:11 GMT
2019-07-15 15:06:11.651 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient : [IUserCenterFeignClient#findById] transfer-encoding: chunked
2019-07-15 15:06:11.652 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient : [IUserCenterFeignClient#findById]
2019-07-15 15:06:11.652 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient : [IUserCenterFeignClient#findById] {"id":1,"wxId":"","wxNickname":"IsaacZhang","roles":"","avatarUrl":"aaa","createTime":"2019-07-11T06:08:18.000+0000","updateTime":"2019-07-11T06:08:18.000+0000","bonus":100}
2019-07-15 15:06:11.652 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient : [IUserCenterFeignClient#findById] <--- END HTTP (173-byte body)
Configuration
支持的配置项

demo
使用配置文件来定义log level
#logging:
#level:
#com.sxzhongf: debug
#com.sxzhongf.sharedcenter.feignclients.IUserCenterFeignClient: debug
feign:
client:
config:
user-center: #单服务配置
loggerLevel: full
---
feign:
client:
config:
default: #全局配置日志级别
loggerLevel: full
Feign的继承性
- 官方不建议使用
- 大多数公司使用?
架构师需要根据自身业务情况来决定,是否需要将不同的微服务进行业务耦合,还是使用冗余代码的方式来解放业务耦合性。
Feign多参请求
Get
- 使用
@SpringQueryMap
@FeignClient(name = "user-center")
public interface ITestUserCenterFeignClient {
@GetMapping("/users/q")
public UserDTO query(@SpringQueryMap UserDTO userDTO);
}
- 使用
@RequestParam
@FeignClient(name = "user-center")
public interface ITestUserCenterFeignClient {
@RequestMapping(value = "/users/q",method = RequestMethod.GET)
public UserDTO query(@RequestParam("id") Long id,@RequestParam("name") String name);
}
- 使用
Map构建,(不推荐)
@FeignClient(name = "user-center")
public interface ITestUserCenterFeignClient {
@RequestMapping(value = "/users/q",method = RequestMethod.GET)
public UserDTO query(@RequestParam Map<String,Object> conditions);
}
注意:这种方式不建议使用。主要是因为可读性不好,而且如果参数为空的时候会有一些问题,例如
map.put("username", null);会导致user-center服务接收到的username是"",而不是null。
Post
服务提供者方法
@PostMapping("/create")
public User createUser(@RequestBody User user){
return null;
}
服务调用者
@FeignClient(name = "user-center")
public interface ITestUserCenterFeignClient {
@RequestMapping(value = "/users/q",method = RequestMethod.POST)
public UserDTO query(@RequestBody UserDTO user);
}
Feign脱离服务注册/Ribbon调用
@FeignClient(name = "xxxxx",url = "http://www.baidu.com")
public interface ITestBaiduFeignClient {
@GetMapping("")
public String getBaidu();
}
Feign 性能优化
使用连接池
httpClient
- 加依赖
<!--Feign 性能优化,需要使用连接池,引入依赖-->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
- 加注解(不需要)
- 改配置
httpclient:
# 为feign启用 apache httpclient 做请求,而不使用默认的urlconection
enabled: true
# feign 最大连接数
max-connections: 200
# feign 单个路径请求的最大连接数
max-connections-per-route: 50
okHttp
- 加依赖
<!--Feign 性能优化,需要使用连接池,引入依赖-->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
- 加注解(不需要)
- 改配置
httpclient:
# 为feign启用 apache httpclient 做请求,而不使用默认的urlconection
#enabled: true
# feign 最大连接数
max-connections: 200
# feign 单个路径请求的最大连接数
max-connections-per-route: 50
okhttp:
enabled: true
合理使用Feign日志
生产环境使用
Logger.Level.BASIC
RestTemplate
RestTemplate VS. Feign

客户端远程调用Feign的更多相关文章
- 阶段5 3.微服务项目【学成在线】_day09 课程预览 Eureka Feign_07-Feign远程调用-Feign测试
2.2.1 Feign介绍 Feign是Netflix公司开源的轻量级rest客户端,使用Feign可以非常方便的实现Http 客户端.Spring Cloud引入 Feign并且集成了Ribbon实 ...
- Hessian怎样实现远程调用
1.Spring中除了提供HTTP调用器方式的远程调用,还对第三方的远程调用实现提供了支持,其中提供了对Hessian的支持. Hessian是由Caocho公司发布的一个轻量级的二进制协议远程调用实 ...
- Python中实现远程调用(RPC、RMI)简单例子
说白了,远程调用就是将对象名.函数名.参数等传递给远程服务器,服务器将处理结果返回给客户端 远程调用使得调用远程服务器的对象.方法的方式就和调用本地对象.方法的方式差不多,因为我们通过网络编程把这 ...
- 【微服务】之五:轻松搞定SpringCloud微服务-调用远程组件Feign
上一篇文章讲到了负载均衡在Spring Cloud体系中的体现,其实Spring Cloud是提供了多种客户端调用的组件,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使 ...
- springcloud系列五 feign远程调用服务
一:Feign简介 Feign 是一种声明式.模板化的 HTTP 客户端,在 Spring Cloud 中使用 Feign,可以做到使用 HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完 ...
- 2019.12.4 Hystix熔断&Feign进行远程调用&Zuul
0.学习目标 会配置Hystix熔断 会使用Feign进行远程调用 能独立搭建Zuul网关 能编写Zuul的过滤器 1.Hystrix 1.1.简介 Hystrix,英文意思是豪猪,全身是刺,看起来就 ...
- 阶段5 3.微服务项目【学成在线】_day09 课程预览 Eureka Feign_05-Feign远程调用-客户端负载均衡介绍
2 Feign远程调用 在前后端分离架构中,服务层被拆分成了很多的微服务,服务与服务之间难免发生交互,比如:课程发布需要调用 CMS服务生成课程静态化页面,本节研究微服务远程调用所使用的技术. 下图是 ...
- Feign远程调用
有关微服务中,服务与服务如何通信,我已经给大家介绍了Ribbon远程调用的相关知识,不知道大家有没有发现Ribbon的问题呢? Ribbon的问题 在Ribbon中,如果我们想要发起一个调用,是这样的 ...
- SpringCloud(二) - Eureka注册中心,feign远程调用,hystrix降级和熔断
1.项目模块介绍 2. 父项目 主要依赖 spring-cloud 的 版本控制 <properties> <!-- springCloud 版本 --> <scd.ve ...
随机推荐
- ReportViewer,RDLC 报表开发之个性化样式
原文:ReportViewer,RDLC 报表开发之个性化样式 报表开发中,客户对样式提出了要求: 1.工具栏上显示每页条数 2.只导出Excel,不需要下拉菜单. 3.报表上显示的图表,分页时,每页 ...
- 微信小程序把玩(三十五)Video API
原文:微信小程序把玩(三十五)Video API 电脑端不能测试拍摄功能只能测试选择视频功能,好像只支持mp4格式,值得注意的是成功之后返回的临时文件路径是个列表tempFilePaths而不是tem ...
- UWP入门(六)-- ResourceDictionary 和 XAML 资源引用
原文:UWP入门(六)-- ResourceDictionary 和 XAML 资源引用 你最希望声明为 XAML 资源的 XAML 元素包括 Style.ControlTemplate.动画组件和 ...
- 让Qt在MIPS Linux上运行 good
下载 首先下载Qt everywhere,当前的版本是4.7.2,可以从nokia的网站上下载,也可以从git服务器上下载.考虑到文件有200M 以上的大小,下载速率低于25kBPS的,需要考虑从什么 ...
- C#每天进步一点--事件
事件:如果类型定义了事件成员,那么类型就可以通知其他对象发生了特定的事情.例如,Button类提供了一个名为Click的事件.应用程序中的一个或者多个对象可能想接收关于这个事件的通知,以便在Butto ...
- 案例解析:springboot自动配置未生效问题定位(条件断点)
Spring Boot在为开发人员提供更高层次的封装,进而提高开发效率的同时,也为出现问题时如何进行定位带来了一定复杂性与难度.但Spring Boot同时又提供了一些诊断工具来辅助开发与分析,如sp ...
- Java集合 LinkedList的原理及使用
Java集合 LinkedList的原理及使用 LinkedList和ArrayList一样是集合List的实现类,虽然较之ArrayList,其使用场景并不多,但同样有用到的时候,那么接下来,我们来 ...
- Java虚拟机详解(一)------简介
本系列博客我们将以当前默认的主流虚拟机HotSpot 为例,详细介绍 Java虚拟机.以 JDK1.7 为主,同时介绍与 JDK1.8 的不同之处,通过Oracle官网以及各种文献进行整理,并加以验证 ...
- 解决kali linux 2016.2实体机安装后root用户没有声音
Kali Linux系统默认状态下,root用户是无法使用声卡的,也就没有声音.启用的方法如下:(1)在终端执行命令:systemctl --user enable pulseaudio (2)在/e ...
- Ruby字符串(2):String方法详细整理
String方法整理 官方手册 类方法 new new(str="") → new_str new(str="", encoding: enc) → new_s ...