spring boot      1.5.9.RELEASE

spring cloud    Dalston.SR1

1.前言

什么是Feign?

  为了简化我们的开发,Spring Cloud Feign出现了!它基于 Netflix Feign 实现,整合了 Spring Cloud Ribbon 与 Spring Cloud Hystrix,

除了整合这两者的强大功能之外,它还提 供了声明式的服务调用(不再通过RestTemplate)。

  事实上很早Feign就已经停止维护了 ,spring推出了 open Feign ,原理基本一样 ,但是 Feign还是有必要了解怎么使用的。

2.操作

(1)引入依赖

完成的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.atguigu.springcloud</groupId>
<!-- 父级maven模块的工程名字-->
<artifactId>microservicecloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.example</groupId>
<artifactId>demo-my-cen-feign</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo-my-cen-feign</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency> <!-- Ribbon相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency> <!-- 修改后立即生效,热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency> <!--feign依赖包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency> </dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>

(2)新建一个装 Feign 接口的文件夹 ,我这里设为 feignInter

目录结构截图

(3)编写一个目标微服务的接口 FeignServuce1  ,名字随意 ,一般一个微服务实例则装载一个文件里或者一个一个文件夹里面

package com.example.demomycenfeign.feignInter;

import com.example.demomycenfeign.feignInter.myFallbackFactory.FeignServuce1FallbackFactory;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; //注入服务的应用名
@FeignClient(value = "MICROSERVICECLOUD-DEPT1", fallbackFactory = FeignServuce1FallbackFactory.class)
public interface FeignServuce1 { @RequestMapping(value = "/ask", method = RequestMethod.GET)
public String ask(); }

注解 @FeignClient 是用来标记这个接口是用来映射微服务接口的 ,参数 value 是为微服务提供者的应用名 ,在eureka可以查到 ,fallbackFactory 是当服务熔断后调用这个类的方法,

接口具体的路径和参数应该与服务提供者的一样。

(3)编写熔断抛出的类 FeignServuce1FallbackFactory,类似于抛出异常操作

package com.example.demomycenfeign.feignInter.myFallbackFactory;

import com.example.demomycenfeign.feignInter.FeignServuce1;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component; import java.util.Date; /**
* feign使用断路器【熔断器】 ,当熔断发生后,运行这里的方法。类似于异常抛出
* 这里主要是处理异常出错的情况(降级/熔断时服务不可用,fallback就会找到这里来)
*/
@Component // 不要忘记添加,不要忘记添加,不加则无法使用熔断器
public class FeignServuce1FallbackFactory implements FallbackFactory<FeignServuce1> {
@Override
public FeignServuce1 create(Throwable throwable) {
return new FeignServuce1() {
@Override
public String ask() {
return "feign使用了断路器【熔断器】,限制服务处于熔断状态,运行了类似于抛出异常的方法,时间=" + new Date();
}
};
}
}

注解 @Component 很重要,否则熔断后无法找到,请求会一直在等待

开启熔断器,还有关键的一步,去applicable.properties 配置  ,因为feign 底层熔断器就是使用 Hystrix

完整的配置

server.port=520
spring.application.name=520love
# 当前微服务不注册到eureka中(消费端)
eureka.client.register-with-eureka=false
eureka.client.service-url.defaultZone=http://localhost:7001/eureka/
#
#
#
# feign开启熔断器必须加这句话,不然无法使用,直接报500状态码
feign.hystrix.enabled=true
#
#
#
##
##是否开启超时熔断, 如果为false, 则熔断机制只在服务不可用时开启,即忽略hystrix的超时时间
# hystrix.command.default.execution.timeout.enabled=true
## 设置超时熔断时间
# hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=1000
# ##全局配置
## 请求连接的超时时间 默认的时间为 1 秒
#ribbon.ConnectTimeout=5000
## 请求处理的超时时间
#ribbon.ReadTimeout=5000
#
## 开启饥饿加载 解决第一次feign调用失败的问题
#ribbon.eager-load.enabled=true
##需要饥饿加载的服务名称
#ribbon.eager-load.clients=commodity-center
#

(4)默认客户端负载均衡策略是轮询策略 ,想要修改,有3种办法 ,这里只介绍一种 ,使用注解 @Configuration

新建一个配置类

现在去启动类开启 Feign 和设置负载均衡策略

package com.example.demomycenfeign;

import com.example.demomycenfeign.cfgBean.ConfigBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.ribbon.RibbonClient; @SpringBootApplication
@EnableEurekaClient
//
//
@EnableFeignClients(basePackages = {"com.example.demomycenfeign.feignInter"})
//开启客户端负载均衡自定义策略,参数name是该服务器的应用名字 ,configuration设置 策略配置类
@RibbonClient(name = "520love" ,configuration = ConfigBean.class)
//
public class DemoMyCenFeignApplication { public static void main(String[] args) {
SpringApplication.run(DemoMyCenFeignApplication.class, args);
} }

注解 @ EnableFeignClients 是开启 Feign ,参数  basePackages 是指 装有 目标微服务的接口 的文件夹 ,用于Feign扫描接口才能知道在服务接口在哪里

注解 @RibbonClient 开启客户端负载均衡自定义策略,参数name是该服务器的应用名字 ,configuration设置 策略配置类

(5)到了关键的一步,怎么使用 Feign 调用服务呢?

很简单

package com.example.demomycenfeign.GGController;

import com.example.demomycenfeign.feignInter.FeignServuce1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; @RestController
//@PropertySource("classpath:my.properties")
public class GGController { // private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT1"; @Autowired
private FeignServuce1 feignServuce1; @RequestMapping("/bb")
public String bb(){ // Food d = new Food();
// d.setApple("苹果");
// d.setEgg("鸡蛋");
// System.out.println(d);
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// } // System.out.println("调用服务,开启负载均衡Ribbon");
//使用restTemplate 直接调用 ,postForObject 是post请求方式 ,getForObject是get请求方式,根据服务提供者的接口选择,这个是需要提前知道服务提供者的接口格式的
// return restTemplate.getForObject(REST_URL_PREFIX + "/ask", String.class) +"===========消费者端口是"+port;
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// } return feignServuce1.ask()+"===========我的消费者端口是"+port; } @Value("${server.port}")
private String port; // public String myFallback(){
// return "服务繁忙,已经开启了Hystrix";
// } @RequestMapping("/cc")
public String otherService() {
return "我是其他服务";
} }

3.测试

(1)提前准备 并开启  1个注册中心端口7001 , 2个服务提供者端口8001,8003 【集群】,一个消费者端口520

(2)端口520 ,浏览器输入 http://localhost:520/bb ,可以正常访问

浏览器输入 http://localhost:520/cc ,可以正常访问

(3)现在使用JMeter 工具做压力测试 ,建立2000个线程,同时访问http://localhost:520/bb

(4)端口520 ,再次浏览器输入 http://localhost:520/bb ,可以看到服务熔断了,对服务做降级保护,运行了fallbackFactory的类方法

再次访问其他端口 ,  浏览器输入 http://localhost:520/cc ,可以正常访问,接口并没有崩溃 ,但是。。。。多访问几次,会发现端口520崩了。。。/cc访问不到

结论是:2000线程访问http://localhost:520/bb ,导致 端口520崩溃 ,

猜测,feign 熔断只是对远程服务接口负责,当服务不可用或者服务响应超时,则会熔断/服务降级

//需要验证一下

4.第二次测试

(1)只开一个服务端口8001 ,

在端口520 ,浏览器输入 http://localhost:520/bb ,可以正常访问服务

(2)使用JMeter 工具做压力测试 ,建立2000个线程,同时访问http://localhost:8001/ask ,导致服务8001端口崩了

端口520 ,浏览器输入 http://localhost:520/bb ,发现接口熔断了

(3)关闭2000线程后,端口520 ,浏览器输入 http://localhost:520/bb,有可以调用接口了

结论:feign 熔断只是对远程服务接口负责,当服务不可用或者服务响应超时,则会熔断/服务降级,消费者端口不可再调用服务

最简单的证明就是把服务提供者服务器直接关掉,服务消费者的调用接口直接熔断,无法使用,展示这里就不写了

spring cloud --- Feign --- 心得的更多相关文章

  1. 笔记:Spring Cloud Feign Ribbon 配置

    由于 Spring Cloud Feign 的客户端负载均衡是通过 Spring Cloud Ribbon 实现的,所以我们可以直接通过配置 Ribbon 的客户端的方式来自定义各个服务客户端调用的参 ...

  2. 笔记:Spring Cloud Feign Hystrix 配置

    在 Spring Cloud Feign 中,除了引入了用户客户端负载均衡的 Spring Cloud Ribbon 之外,还引入了服务保护与容错的工具 Hystrix,默认情况下,Spring Cl ...

  3. 笔记:Spring Cloud Feign 其他配置

    请求压缩 Spring Cloud Feign 支持对请求与响应进行GZIP压缩,以减少通信过程中的性能损耗,我们只需要通过下面二个参数设置,就能开启请求与响应的压缩功能,yml配置格式如下: fei ...

  4. 笔记:Spring Cloud Feign 声明式服务调用

    在实际开发中,对于服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以我们通常会针对各个微服务自行封装一些客户端类来包装这些依赖服务的调用,Spring Cloud Feign 在此基础上做了进 ...

  5. 第六章:声明式服务调用:Spring Cloud Feign

    Spring Cloud Feign 是基于 Netflix Feign 实现的,整合了 Spring Cloud Ribbon 和 Spring Cloud Hystrix,除了提供这两者的强大功能 ...

  6. Spring Cloud Feign Ribbon 配置

    由于 Spring Cloud Feign 的客户端负载均衡是通过 Spring Cloud Ribbon 实现的,所以我们可以直接通过配置 Ribbon 的客户端的方式来自定义各个服务客户端调用的参 ...

  7. Spring Cloud feign

    Spring Cloud feign使用 前言 环境准备 应用模块 应用程序 应用启动 feign特性 综上 1. 前言 我们在前一篇文章中讲了一些我使用过的一些http的框架 服务间通信之Http框 ...

  8. 微服务架构之spring cloud feign

    在spring cloud ribbon中我们用RestTemplate实现了服务调用,可以看到我们还是需要配置服务名称,调用的方法 等等,其实spring cloud提供了更优雅的服务调用方式,就是 ...

  9. Spring Cloud Feign 在调用接口类上,配置熔断 fallback后,输出异常

    Spring Cloud Feign 在调用接口类上,配置熔断 fallback后,出现请求异常时,会进入熔断处理,但是不会抛出异常信息. 经过以下配置,可以抛出异常: 将原有ErrorEncoder ...

随机推荐

  1. 【C/C++】贪心/算法笔记4.4/PAT B1020月饼/PAT B1023组内最小数

    简单贪心 所谓简单贪心,就是每步都取最优的一种方法. 月饼问题:有N种月饼,市场最大需求量D,给出每种月饼的库存量和总售价. 思路:从贵的往便宜的卖.如果当前的已经卖完了,就卖下一个.如果剩余D不足, ...

  2. 【划重点】Python遍历列表的四种方法

    一.通过for循环直接遍历 user1 = ["宋江","林冲","卢俊义","吴用"] for user in use ...

  3. bjdctf_2020_router

    这道题其实主要考linux下的命令.我们来试一下!!! 可以看到,只要我们在命令之间加上分号,就可以既执行前面的命令,又执行后面的命令... 这道题就不看保护了,直接看一下关键的代码. 这里可以看到s ...

  4. 预算(Project)

    <Project2016 企业项目管理实践>张会斌 董方好 编著 预算是件重要的事,不然银几一花没边了,那结果可是要牺牺的(以下省略具体描述9^323字) 在Project里做预算,步骤不 ...

  5. 解决Tensorflow ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type numpy.ndarray)

    问题描述 在将一个数组送入tensorflow训练时,报错如下: ValueError: Failed to convert a NumPy array to a Tensor (Unsupporte ...

  6. UVA10079 Pizza Cutting 题解

    Content 求用 \(n\) 条直线最多能将平面分成多少块区域. 多组输入,以一个负数结束. 数据范围:\(0\leqslant n\leqslant 2.1\times 10^8\). Solu ...

  7. 关于后端 Entity Model Domain 的分界线

    前言:在我们开发中经常用一种类型的值来接收来自Dao层的数据并将它传送给前端,或者作为逻辑处理,一般这种类型有三种 Entity  Model  Domain  我们该如何准确的应用这三种类型呢?这三 ...

  8. 如何在服务器上新建一个svn的目录工程文件

    如何在服务器上新建一个svn的目录工程文件

  9. JAVA判断URL地址是否非法

    /** * 判断请求url是否非法 * @param url * @return */ public static boolean isValidRequestUri(String url) { if ...

  10. PC chrome开启自带的dark mode

    地址 复制下面的地址到chrome地址栏打开,再设置为 Enable 就可以开启了. chrome://flags/#enable-force-dark