Feign的目标

feign是声明式的web service客户端,它让微服务之间的调用变得更简单了,类似controller调用service。Spring Cloud集成了Ribbon和Eureka,可在使用Feign时提供负载均衡的http客户端。

引入Feign

项目中使用了gradle作为依赖管理,maven类似。

dependencies {

//feign

implementation('org.springframework.cloud:spring-cloud-starter-openfeign:2.0.2.RELEASE')

//web

implementation('org.springframework.boot:spring-boot-starter-web')

//eureka client

implementation('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:2.1.0.M1')

//test

testImplementation('org.springframework.boot:spring-boot-starter-test')

}

因为feign底层是使用了ribbon作为负载均衡的客户端,而ribbon的负载均衡也是依赖于eureka 获得各个服务的地址,所以要引入eureka-client。

SpringbootApplication启动类加上@FeignClient注解,以及@EnableDiscoveryClient。

@EnableFeignClients

@EnableDiscoveryClient

@SpringBootApplication

public class ProductApplication {

public static void main(String[] args) {

SpringApplication.run(ProductApplication.class, args);

}

}

yaml配置:

server:

port: 8082

#配置eureka

eureka:

client:

service-url:

defaultZone: http://localhost:8761/eureka

instance:

status-page-url-path: /info

health-check-url-path: /health

#服务名称

spring:

application:

name: product

profiles:

active: ${boot.profile:dev}

#feign的配置,连接超时及读取超时配置

feign:

client:

config:

default:

connectTimeout: 5000

readTimeout: 5000

loggerLevel: basic

Feign的使用

@FeignClient(value = "CART")

public interface CartFeignClient {

@PostMapping("/cart/{productId}")

Long addCart(@PathVariable("productId")Long productId);

}

上面是最简单的feign client的使用,声明完为feign client后,其他spring管理的类,如service就可以直接注入使用了,例如:

//这里直接注入feign client

@Autowired

private CartFeignClient cartFeignClient;

@PostMapping("/toCart/{productId}")

public ResponseEntity addCart(@PathVariable("productId") Long productId){

Long result = cartFeignClient.addCart(productId);

return ResponseEntity.ok(result);

}

可以看到,使用feign之后,我们调用eureka 注册的其他服务,在代码中就像各个service之间相互调用那么简单。

FeignClient注解的一些属性

属性名

默认值

作用

备注

value

空字符串

调用服务名称,和name属性相同

serviceId

空字符串

服务id,作用和name属性相同

已过期

name

空字符串

调用服务名称,和value属性相同

url

空字符串

全路径地址或hostname,http或https可选

decode404

false

配置响应状态码为404时是否应该抛出FeignExceptions

configuration

{}

自定义当前feign client的一些配置

参考FeignClientsConfiguration

fallback

void.class

熔断机制,调用失败时,走的一些回退方法,可以用来抛出异常或给出默认返回数据。

底层依赖hystrix,启动类要加上@EnableHystrix

path

空字符串

自动给所有方法的requestMapping前加上前缀,类似与controller类上的requestMapping

primary

true

此外,还有qualifier及fallbackFactory,这里就不再赘述。

Feign自定义处理返回的异常

这里贴上GitHub上openFeign的wiki给出的自定义errorDecoder例子。

public class StashErrorDecoder implements ErrorDecoder {

@Override

public Exception decode(String methodKey, Response response) {

if (response.status() >= 400 && response.status() <= 499) {

//这里是给出的自定义异常

return new StashClientException(

response.status(),

response.reason()

);

}

if (response.status() >= 500 && response.status() <= 599) {

//这里是给出的自定义异常

return new StashServerException(

response.status(),

response.reason()

);

}

//这里是其他状态码处理方法

return errorStatus(methodKey, response);

}

}

自定义好异常处理类后,要在@Configuration修饰的配置类中声明此类。

Feign使用OKhttp发送request

Feign底层默认是使用jdk中的HttpURLConnection发送HTTP请求,feign也提供了OKhttp来发送请求,具体配置如下:

feign:

client:

config:

default:

connectTimeout: 5000

readTimeout: 5000

loggerLevel: basic

okhttp:

enabled: true

hystrix:

enabled: true

Feign原理简述

启动时,程序会进行包扫描,扫描所有包下所有@FeignClient注解的类,并将这些类注入到spring的IOC容器中。当定义的Feign中的接口被调用时,通过JDK的动态代理来生成RequestTemplate。

RequestTemplate中包含请求的所有信息,如请求参数,请求URL等。

RequestTemplate声场Request,然后将Request交给client处理,这个client默认是JDK的HTTPUrlConnection,也可以是OKhttp、Apache的HTTPClient等。

最后client封装成LoadBaLanceClient,结合ribbon负载均衡地发起调用。

详细原理请参考源码解析。

Feign开启GZIP压缩

Spring Cloud Feign支持对请求和响应进行GZIP压缩,以提高通信效率。

application.yml配置信息如下:

feign:

compression:

request: #请求

enabled: true #开启

mime-types: text/xml,application/xml,application/json #开启支持压缩的MIME TYPE

min-request-size: 2048 #配置压缩数据大小的下限

response: #响应

enabled: true #开启响应GZIP压缩

注意:

由于开启GZIP压缩之后,Feign之间的调用数据通过二进制协议进行传输,返回值需要修改为ResponseEntity才可以正常显示,否则会导致服务之间的调用乱码。

示例如下:

@PostMapping("/order/{productId}")

ResponseEntity addCart(@PathVariable("productId") Long productId);

作用在所有Feign Client上的配置方式

方式一:通过java bean 的方式指定。

@EnableFeignClients注解上有个defaultConfiguration属性,可以指定默认Feign Client的一些配置。

@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration.class)

@EnableDiscoveryClient

@SpringBootApplication

@EnableCircuitBreaker

public class ProductApplication {

public static void main(String[] args) {

SpringApplication.run(ProductApplication.class, args);

}

}

DefaultFeignConfiguration内容:

@Configuration

public class DefaultFeignConfiguration {

@Bean

public Retryer feignRetryer() {

return new Retryer.Default(1000,3000,3);

}

}

方式二:通过配置文件方式指定。

feign:

client:

config:

default:

connectTimeout: 5000 #连接超时

readTimeout: 5000 #读取超时

loggerLevel: basic #日志等级

Feign Client开启日志

日志配置和上述配置相同,也有两种方式。

方式一:通过java bean的方式指定

@Configuration

public class DefaultFeignConfiguration {

@Bean

public Logger.Level feignLoggerLevel(){

return Logger.Level.BASIC;

}

}

方式二:通过配置文件指定

logging:

level:

com.xt.open.jmall.product.remote.feignclients.CartFeignClient: debug

Feign 的GET的多参数传递

目前,feign不支持GET请求直接传递POJO对象的,目前解决方法如下:

把POJO拆散城一个一个单独的属性放在方法参数中

把方法参数编程Map传递

使用GET传递@RequestBody,但此方式违反restful风格

介绍一个最佳实践,通过feign的拦截器来实现。

@Component

@Slf4j

public class FeignCustomRequestInteceptor implements RequestInterceptor {

@Autowired

private ObjectMapper objectMapper;

@Override

public void apply(RequestTemplate template) {

if (HttpMethod.GET.toString() == template.method() && template.body() != null) {

//feign 不支持GET方法传输POJO 转换成json,再换成query

try {

Map> map = objectMapper.readValue(template.bodyTemplate(), new TypeReference>>() {

});

template.body(null);

template.queries(map);

} catch (IOException e) {

log.error("cause exception", e);

}

}

}

feign扫描_微服务实战SpringCloud之Feign简介及使用相关推荐

  1. feign扫描_微服务通信之feign的注册、发现过程

    前言 feign 是目前微服务间通信的主流方式,是springCloud中一个非常重要的组件.他涉及到了负载均衡.限流等组件.真正意义上掌握了feign可以说就掌握了微服务. 一.feign的使用 f ...

  2. springcloud全局过滤_微服务技术SpringCloud 互联网网站架构演变过程

    网站架构演变过程 传统架构 传统的SSH架构,分为三层架构 web控制层.业务逻辑层.数据库访问层. 传统架构也就是单点应用,就是大家在刚开始初学JavaEE技术的时候SSH架构或者SSM架构,业务没 ...

  3. java微服务项目简历_微服务框架-SpringCloud简介

    前面一篇文章谈到微服务基础框架,而Netflix的多个开源组件一起正好可以提供完整的分布式微服务基础架构环境,而对于Spring Cloud正是对Netflix的多个开源组件进一步的封装而成,同时又实 ...

  4. mqtt发布json数据_微服务实战:从架构到发布(一)

    引言:"微服务"是当前软件架构领域非常热门的词汇,能找到很多关于微服务的定义.准则,以及如何从微服务中获益的文章,在企业的实践中去应用"微服务"的资源却很少.本 ...

  5. 微服务笔记:第一章_微服务简介|Eureka注册中心|Nacos注册中心|Nacos配置管理|Feign|Gateway服务网关

    微服务笔记:第一章_微服务简介|Eureka注册中心|Nacos注册中心|Nacos配置管理|Feign|Gateway服务网关 1. 微服务简介 1.1 服务架构演变 1.2 SpringCloud ...

  6. springcloud 微服务鉴权_我对微服务、SpringCloud、k8s、Istio的一些杂想

    一.微服务与SOA "微服务"是一个名词,没有这个名词之前也有"微服务",一个朗朗上口的名词能让大家产生一个认知共识,这对推动一个事务的发展挺重要的,不然你叫微 ...

  7. Java架构师面试问些什么?微服务之springcloud面试题(共22题,含详细解答)

    [Java架构师面试网]收集整理了几乎整个架构师学习途中会遇到的面试题,希望大家都能早日圆自己的架构师梦~ 公众号:Java架构师面试网,关注回复"资料"即可领取精美整理的面试资料 ...

  8. docker -v 文件夹下没有数据_微服务就是Dubbo?并没有那么简单!微服务架构+Docker+k8s了解下...

    微服务算是面试中非常高频的词汇了! 之前我就遇到一个候选人,我问他微服务是什么,他说:"微服务就是 Dubbo--",然后把 Dubbo 的原理说的清清楚楚.回答的我都动心了,我猜 ...

  9. Spring Cloud微服务实战:手把手带你整合eurekazuulfeignhystrix(附源码)

    Spring Cloud微服务实战:手把手带你整合eureka&zuul&feign&hystrix(附源码) Spring Cloud简介 Spring Cloud是一个基于 ...

  10. 最新微服务框架SpringCloud Alibaba介绍,搭建

    微服务和SpringCloud Alibaba详细介绍(一),手把手搭建微服务框架 PS:本博客是本人参照B站博主:JAVA阿伟如是说 的视频讲解手敲整理的笔记 跟着一起手动搭建的框架 供大家一起学习 ...

最新文章

  1. Burpsuite学习(4)
  2. 差分隐私 机器学习_满足差分隐私的经验误差最小化方法
  3. java system.runfinalization()_Android中缓存理解(一)
  4. 杨百万建议股民可以从以下几个方面进行
  5. Machine Learning week 7 quiz: Unsupervised Learning
  6. [工具]-电脑磁盘爆满了,但又不知道哪些文件占用的空间,怎么办?
  7. jQuery之end()和pushStack()
  8. CoDeSys的前世今生
  9. 信息学奥赛C++语言: 抽奖2
  10. python独立图形_在networkx中查找图形对象中的独立图形
  11. 云小课 | 玩转HiLens Studio之手机实时视频流调试代码
  12. java sql编写教务系统_教务管理系统的设计与实现(SQLServer)
  13. MATLAB视频转图片保存
  14. 安规的XY电容器件作用
  15. 最简单的U盘安装windows系统教程
  16. 现在更新鸿蒙会成为小白鼠吗,猫和老鼠鸿蒙版下载-猫和老鼠网易官方手游鸿蒙版 v7.8.4-114手机乐园...
  17. 第26课:个人高效的秘籍 OKR 工作法
  18. python plt.imshow函数显示图像颜色失真
  19. Qt中提示“常量中有换行符“的解决方法
  20. 基于FPGA低频方波测量-频率与占空比

热门文章

  1. 玩转windows内置linux子系统_1.安装
  2. 微软 Windows 10 将支持 8 英寸以下 ARM 平板设备
  3. Android学习4—短信发送器的实现
  4. zabbix(三)—— update
  5. centos如何使用nomachine远程连接GNOME桌面(二)
  6. 在Vmware中安装archlinux(2008.3core)的流程与心得
  7. iPhone入门知识普及
  8. getElementsByName和getElementByID
  9. 11、旋转数组的最小数字
  10. mac终端支持git