使用Feign实现远程HTTP调用

什么是Feign

实现
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
@MapperScan("com.itmuch.contentcenter.dao")
@SpringBootApplication
@EnableFeignClients// (defaultConfiguration = GlobalFeignConfiguration.class)
@EnableBinding({Source.class})
public class ContentCenterApplication {
@FeignClient(name = "user-center")
public interface UserCenterFeignClient {
/**
* http://user-center/users/{id}
*
* @param id
* @return
*/
@GetMapping("/users/{id}")
UserDTO findById(@PathVariable Integer id);
}
private final UserCenterFeignClient userCenterFeignClient;

// 1. 代码不可读
// 2. 复杂的url难以维护:https://user-center/s?ie={ie}&f={f}&rsv_bp=1&rsv_idx=1&tn=baidu&wd=a&rsv_pq=c86459bd002cfbaa&rsv_t=edb19hb%2BvO%2BTySu8dtmbl%2F9dCK%2FIgdyUX%2BxuFYuE0G08aHH5FkeP3n3BXxw&rqlang=cn&rsv_enter=1&rsv_sug3=1&rsv_sug2=0&inputT=611&rsv_sug4=611
// 3. 难以相应需求的变化,变化很没有幸福感
// 4. 编程体验不统一
UserDTO userDTO = this.userCenterFeignClient.findById(userId);

Feign的组成

细粒度配置自定义

  • Java代码方式
  • 配置属性方法

指定日志级别

Java代码方式

UserCenterFeignClient
@FeignClient(name = "user-center", configuration = GlobalFeignConfiguration.class)
public interface UserCenterFeignClient {
/**
* http://user-center/users/{id}
*
* @param id
* @return
*/
@GetMapping("/users/{id}")
UserDTO findById(@PathVariable Integer id);
}
GlobalFeignConfiguration
/**
* feign的配置类
* 这个类别加@Configuration注解了,否则必须挪到@ComponentScan能扫描的包以外
*/
public class GlobalFeignConfiguration {
@Bean
public Logger.Level level(){
// 让feign打印所有请求的细节
return Logger.Level.FULL;
}
}
application.yml
logging:
level:
com.itmuch.contentcenter.feignclient.UserCenterFeignClient: debug

配置属性方法

全局配置

  • Java代码方式
  • 配置属性方式

Java代码方式

ContentCenterApplication

EnableFeignClients

// 扫描mybatis哪些包里面的接口
@MapperScan("com.itmuch.contentcenter.dao")
@SpringBootApplication
@EnableFeignClients(defaultConfiguration = GlobalFeignConfiguration.class)
@EnableBinding({Source.class})
public class ContentCenterApplication {
/**
* feign的配置类
* 这个类别加@Configuration注解了,否则必须挪到@ComponentScan能扫描的包以外
*/
public class GlobalFeignConfiguration {
@Bean
public Logger.Level level(){
// 让feign打印所有请求的细节
return Logger.Level.FULL;
}
}

配置属性方式

// 扫描mybatis哪些包里面的接口
@MapperScan("com.itmuch.contentcenter.dao")
@SpringBootApplication
@EnableFeignClients// (defaultConfiguration = GlobalFeignConfiguration.class)
@EnableBinding({Source.class})
public class ContentCenterApplication {

支持的配置项

Java代码方式支持的配置项

配置属性方式支持的配置项

配置最佳实践

Ribbon配置 VS Feign配置

Feign代码方式 vs 属性方式

最佳实践

Feign的继承

关于继承的争议

  • 官方观点:官方不推荐使用
  • 业界观点:很多公司使用
  • 个人观点:权衡利弊

多参数请求构造

Get请求

TestController
@GetMapping("test-get")
public UserDTO query(UserDTO userDTO) {
return testUserCenterFeignClient.query(userDTO);
}

方法1

TestUserCenterFeignClient
import com.itmuch.contentcenter.domain.dto.user.UserDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.GetMapping; @FeignClient(name = "user-center")
public interface TestUserCenterFeignClient {
@GetMapping("/q")
UserDTO query(@SpringQueryMap UserDTO userDTO);
}

方法二

@FeignClient(name = "user-center")
public interface UserFeignClient {
@RequestMapping(value = "/q", method = RequestMethod.GET)
public UserDTO query(@RequestParam("id") Long id, @RequestParam("username") String username);
}

POST请求包含多个参数

下面来讨论如何使用Feign构造包含多个参数的POST请求。假设服务提供者的Controller是这样编写的:

@RestController
public class UserController {
@PostMapping("/post")
public User post(@RequestBody User user) {
...
}
}
我们要如何使用Feign去请求呢?答案非常简单,示例:
@FeignClient(name = "microservice-provider-user")
public interface UserFeignClient {
@RequestMapping(value = "/post", method = RequestMethod.POST)
public User post(@RequestBody User user);
}

Feign脱离Ribbon的使用

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping; // 脱离ribbon的使用
@FeignClient(name = "baidu", url = "http://www.baidu.com")
public interface TestBaiduFeignClient {
@GetMapping("")
String index();
}

RestTemplate vs Feign

Feign性能优化

  • 连接池[提升15%左右]
feign:
sentinel: # 为feign整合sentinel
enabled: true
client:
config:
# 全局配置
default:
loggerLevel: full
requestInterceptors:
- com.itmuch.contentcenter.feignclient.interceptor.TokenRelayRequestIntecepor
httpclient:
# 让feign使用apache httpclient做请求;而不是默认的urlconnection
enabled: true
# feign的最大连接数
max-connections: 200
# feign单个路径的最大连接数
max-connections-per-route: 50
目前,在Spring cloud中服务之间通过restful方式调用有两种方式
  • restTemplate+Ribbon
  • feign

从实践上看,采用feign的方式更优雅(feign内部也使用了ribbon做负载均衡)。

3.【Spring Cloud Alibaba】声明式HTTP客户端-Feign的更多相关文章

  1. spring cloud 声明式rest客户端feign调用远程http服务

    在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.Feign就是Spring Cloud提供的一种声明式R ...

  2. Spring Cloud 入门教程(六): 用声明式REST客户端Feign调用远端HTTP服务

    首先简单解释一下什么是声明式实现? 要做一件事, 需要知道三个要素,where, what, how.即在哪里( where)用什么办法(how)做什么(what).什么时候做(when)我们纳入ho ...

  3. 声明式HTTP客户端-Feign 使用入门详解

    什么是 OpenFeign OpenFeign (以下统一简称为 Feign) 是 Netflix 开源的声明式 HTTP 客户端,集成了 Ribbon 的负载均衡.轮询算法和 RestTemplat ...

  4. net core天马行空系列-微服务篇:全声明式http客户端feign快速接入微服务中心nacos

    1.前言 hi,大家好,我是三合,距离上一篇博客已经过去了整整两年,这两年里,博主通关了<人生>这个游戏里的两大关卡,买房和结婚.最近闲了下来,那么当然要继续写博客了,今天这篇博客的主要内 ...

  5. SpringCloud学习笔记(9)----Spring Cloud Netflix之声明式 REST客户端 -Feign的使用

    1. 什么是Feign? Feign是一种声明式.模板化的HTTP客户端,在SpringCloud中使用Feign.可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到 ...

  6. SpringCloud学习笔记(10)----Spring Cloud Netflix之声明式 REST客户端 -Feign的高级特性

    1. Feign的默认配置 Feign 的默认配置 Spring Cloud Netflix 提供的默认实现类:FeignClientsConfiguration 解码器:Decoder feignD ...

  7. Spring Cloud 2-Feign 声明式服务调用(三)

    Spring Cloud Feign  1. pom.xml 2. application.yml 3. Application.java 4. Client.java 简化RestTemplate调 ...

  8. 声明式服务调用Feign

    什么是 Feign Feign 是种声明式.模板化的 HTTP 客户端(仅在 consumer 中使用).   什么是声明式,有什么作用,解决什么问题? 声明式调用就像调用本地方法一样调用远程方法;无 ...

  9. Spring Cloud官方文档中文版-声明式Rest客户端:Feign

    官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#spring-cloud-feign 文中例子我做了一些测试在:http ...

随机推荐

  1. JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解

    在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...

  2. __new__ 方法

    1.构造方法 实例化过程:构造->初始化 构成方法必须要有返回值,返回给初始化方法的self class A: def __init__(self): self.x = 1 print('ini ...

  3. javascript 内置对象和方法

    一.自定义对象 方法1 /* 自定义对象 */ var sex= "gender" var person={"name": "tom", & ...

  4. 一行代码去掉Devexpress弹窗

    使用的是.net hook方法: 使用代码: using System; using System.Windows.Forms; namespace AlexDevexpressToolTest { ...

  5. [bzoj4825] [loj#2018] [Hnoi2017] 单旋

    Description \(H\) 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(\(splay\))是一种数据 结构,因为代码好写,功能多,效率高,掌握这种数据结构 ...

  6. 个人第四次作业:Alpha项目测试

    个人第四次作业:Alpha项目测试 格式描述 详情 这个作业属于哪个课程 http://edu.cnblogs.com/campus/xnsy/GeographicInformationScience ...

  7. JavaWeb高级编程(上)

    好久没更新了,发一篇以前记录学习的笔记. 面向读者:已经具有丰富的Java语言和Java SE平台知识的软件开发者和软件工程师. 预掌握知识: Internet.TCP.HTTP协议 HTML(5) ...

  8. zookeeper3.4.6安装

    1.关闭防火墙 service iptables stop chkconfig iptables off 2.编辑hosts文件: vi /etc/hosts 192.168.99.6 JacK6 1 ...

  9. 关于基本布局之——Grid布局

    Gird布局 一.关于概念 网格布局(Grid)是一个很强大的 CSS 布局方案.它可以将网页划分为多个网格任意拼接的布局,可以灵活的运用并实现出多种布局形式. (grid和inline-grid区别 ...

  10. JVM源码分析-JVM源码编译与调试

    要分析JVM的源码,结合资料直接阅读是一种方式,但是遇到一些想不通的场景,必须要结合调试,查看执行路径以及参数具体的值,才能搞得明白.所以我们先来把JVM的源码进行编译,并能够使用GDB进行调试. 编 ...