一、官网文档阅读

较低级别的服务中的服务故障可能导致级联故障一直到用户。 当对特定服务的调用超过circuitBreaker.requestVolumeThreshold(默认值:20个请求)且失败百分比大于circuit.rolllingStats.timeInMilliseconds定义的滚动窗口中的circuitBreaker.errorThresholdPercentage(默认值:> 50%)时(默认值:10秒) ,电路打开,没有拨打电话。 在出现错误和开路的情况下,开发人员可以提供回退。

二、示例

添加hystrix依赖

        <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

修改movie服务的controller

 package com.zwjk.cloud.controller;

 import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.zwjk.cloud.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; /**
* @author : Jixiaohu
* @Date : 2019-04-11.
* @Time : 9:38.
* @Description :
*/
@RestController
public class MovieController { @Autowired
private RestTemplate restTemplate; @Value("${user.userServicePath}")
private String userServicePath; @GetMapping("/movie/{id}")
@HystrixCommand(fallbackMethod = "findByIdFallback")
public User findById(@PathVariable Long id) {
return this.restTemplate.getForObject(this.userServicePath + id, User.class);
} public User findByIdFallback(Long id) {
User user = new User();
user.setId(0L);
user.setName("失败");
return user;
}
}

这边需要注意的是,fallbackMethod方法的返回值和入参,必须和原方法一致,下面进行测试:

可以看到,这里返回了正常的结果,下面停掉user服务

可以看到,这里返回的结果,就是fallbackMethod里面返回的内容,hystrix就起了作用。

下面,继续看一下

Feign Hystrix Support

参考官网使用示例:

 @FeignClient(name = "hello", fallback = HystrixClientFallback.class)
protected interface HystrixClient {
@RequestMapping(method = RequestMethod.GET, value = "/hello")
Hello iFailSometimes();
} static class HystrixClientFallback implements HystrixClient {
@Override
public Hello iFailSometimes() {
return new Hello("fallback");
}
}

在配置文件中,增加开启feign使用断路器

feign:
hystrix:
enabled: true

按照示例,我们在movie服务中,新增UserFeignClientFallback类

 package com.zwjk.cloud.fegin;

 import com.zwjk.cloud.entity.User;
import org.springframework.stereotype.Component; /**
* @author : Jixiaohu
* @Date : 2019-04-17.
* @Time : 18:20.
* @Description :
*/
@Component
public class UserFeignClientFallback implements UserFeignClient {
@Override
public User findById(Long id) {
User user = new User();
user.setId(0L);
return user;
}
}

在fegin上增加相应的注解:

 package com.zwjk.cloud.fegin;

 import com.zwjk.cloud.entity.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; /**
* @author : Jixiaohu
* @Date : 2019-04-12.
* @Time : 16:50.
* @Description :
*/
@FeignClient(name = "microservice-provider-user", fallback = UserFeignClientFallback.class)
public interface UserFeignClient {
//@PathVariable得设置value
@GetMapping("/simple/{id}")
User findById(@PathVariable("id") Long id); //@PathVariable得设置value
}

启动项目,进行测试,

同样的,停掉user服务,再次访问这个地址:

就可以实现熔断服务

当一个项目中,有个feign时,如何禁用一些feign的hystrix?

查看一下官网文档

通过配置加上feignBuilder,就可以禁用指定fegin的hystrix

查看一下代码实现:

 package com.zwjk.cloud.controller;

 import com.zwjk.cloud.entity.User;
import com.zwjk.cloud.fegin.UserFeignClient2;
import com.zwjk.cloud.fegin.UserFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController; /**
* @author : Jixiaohu
* @Date : 2019-04-11.
* @Time : 9:38.
* @Description :
*/
@RestController
public class MovieController { @Autowired
private UserFeignClient userFeignClient; @Autowired
private UserFeignClient2 userFeignClient2; @GetMapping("/movie/{id}")
public User findById(@PathVariable Long id) {
return this.userFeignClient.findById(id);
} @GetMapping("/{serviceName}")
public String findServiceInfoFromEurekaByServiceName(@PathVariable String serviceName) {
return this.userFeignClient2.findServiceInfoFromEurekaByServiceName(serviceName);
} }

两个fegin:

 package com.zwjk.cloud.fegin;

 import com.zwjk.cloud.entity.User;
import com.zwjk.config.UserConfiguration;
import feign.Param;
import feign.RequestLine;
import org.springframework.cloud.openfeign.FeignClient; /**
* @author : Jixiaohu
* @Date : 2019-04-12.
* @Time : 16:50.
* @Description :
*/
@FeignClient(name = "microservice-provider-user", configuration = UserConfiguration.class, fallback =
UserFeignClientFallback.class)
public interface UserFeignClient {
//@PathVariable得设置value
@RequestLine("GET /simple/{id}")
User findById(@Param("id") Long id); //@PathVariable得设置value }
 package com.zwjk.cloud.fegin;

 import com.zwjk.config.UserConfiguration2;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; /**
* @author : Jixiaohu
* @Date : 2019-04-13.
* @Time : 11:23.
* @Description :
*/
@FeignClient(name = "xxxx", url = "http://192.168.1.114:8761/", configuration = UserConfiguration2.class)
public interface UserFeignClient2 {
@RequestMapping(value = "/eureka/apps/{serviceName}")
public String findServiceInfoFromEurekaByServiceName(@PathVariable("serviceName") String serviceName);
}

两个fallback

 package com.zwjk.cloud.fegin;

 import org.springframework.stereotype.Component;

 /**
* @author : Jixiaohu
* @Date : 2019-04-17.
* @Time : 18:20.
* @Description :
*/
@Component
public class UserFeignClient2Fallback implements UserFeignClient2 { @Override
public String findServiceInfoFromEurekaByServiceName(String serviceName) {
return "hahahha";
}
}
 package com.zwjk.cloud.fegin;

 import com.zwjk.cloud.entity.User;
import org.springframework.stereotype.Component; /**
* @author : Jixiaohu
* @Date : 2019-04-17.
* @Time : 18:20.
* @Description :
*/
@Component
public class UserFeignClientFallback implements UserFeignClient {
@Override
public User findById(Long id) {
User user = new User();
user.setId(0L);
return user;
}
}

看一下两个配置文件

 package com.zwjk.config;

 import feign.Contract;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; /**
* @author : Jixiaohu
* @Date : 2019-04-13.
* @Time : 10:20.
* @Description :
*/
@Configuration
public class UserConfiguration { @Bean
public Contract feignContract() {
return new feign.Contract.Default();
} @Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
 package com.zwjk.config;

 import feign.Feign;
import feign.auth.BasicAuthRequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope; /**
* @author : Jixiaohu
* @Date : 2019-04-13.
* @Time : 11:25.
* @Description :
*/
@Configuration
public class UserConfiguration2 {
@Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor("user", "password123");
} @Configuration
public class FooConfiguration {
@Bean
@Scope("prototype")
public Feign.Builder feignBuilder() {
return Feign.builder();
}
}
}

启动服务,进行测试

下面,我们停掉eureka,和user服务,在一次查看返回结果

启用hystrix的返回结果如下:

没有启用hystrix的返回结果,提示500错误

从中,可以看出,hytrix的熔断,可以有很细的粒度。

如果想要查看fallback回退的原因,可以使用可以使用@FeignClient中的fallbackFactory属性。

看一下如何实现?

参考一下官网文档:

先写一个hystrixFactory:

 package com.zwjk.cloud.fegin;

 import com.zwjk.cloud.entity.User;
import feign.hystrix.FallbackFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; /**
* @author : Jixiaohu
* @Date : 2019-04-17.
* @Time : 19:37.
* @Description :
*/
@Component
public class UserFeginClientFactory implements FallbackFactory<UserFeignClient> { private static final Logger Log = LoggerFactory.getLogger(UserFeginClientFactory.class); @Override
public UserFeignClient create(Throwable cause) {
UserFeginClientFactory.Log.info("fallback:reason was : {}", cause.getMessage());
return id -> {
User user = new User();
user.setId(-1L);
user.setName("haha");
return user;
};
}
}

修改一下原feignClient

 package com.zwjk.cloud.fegin;

 import com.zwjk.cloud.entity.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; /**
* @author : Jixiaohu
* @Date : 2019-04-12.
* @Time : 16:50.
* @Description :
*/
@FeignClient(name = "microservice-provider-user", fallbackFactory =
UserFeginClientFactory.class)
public interface UserFeignClient {
//@PathVariable得设置value
@GetMapping("/simple/{id}")
User findById(@PathVariable("id") Long id); //@PathVariable得设置value
}

启动user服务,movie服务,先正常访问:

然后关闭user服务,会发现控制台开始打印日志:

这是为什么呢?因为此时,断路器并没有打开,实际的原因是TimeoutException

当断路器打开时,就会答应异常的信息。

从零开始学spring cloud(十) -------- hystrix简单代码示例的更多相关文章

  1. 从零开始学spring cloud(十一) -------- hystrix监控

    一.官方文档阅读 服务启动后,可以通过/health和hystrix.stream查看效果,实际上,访问上述两个地址,会出现404,这是因为spring boot版本的问题, 我在这里使用的sprin ...

  2. 从零开始学spring cloud(七) -------- Spring Cloud OpenFegin

    一.OpenFegin 介绍 Feign是一个声明性的Web服务客户端. 它使编写Web服务客户端变得更容易. 要使用Feign,请创建一个界面并对其进行注释. 它具有可插入的注释支持,包括Feign ...

  3. 从零开始学spring cloud(六) -------- Ribbon

    一.Ribbon介绍 Ribbon就是客户端侧负责均衡实现的一种方式,那么Ribbon是什么呢? Ribbon是Netflix发布的云中间层服务开源项目,其主要功能是提供客户端侧负载均衡算法.Ribb ...

  4. 从零开始学spring cloud(四) -------- 基础项目搭建

    1.创建一个spring cloud项目 1.1.使用工具创建--idea 点击creat new project,选择spring initializr 点击next,选择下一步 填入自己的Grou ...

  5. 从零开始学spring cloud(五) -------- 将服务注册到Eureka上

    一.开发前准备工作: 官方文档地址:https://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/2.1.0.RELEASE/mul ...

  6. 从零开始学spring cloud(一) -------- spring cloud 简介

    1.微服务简介 1.1.单体架构 一个归档包(例如war格式)包含了应用所有功能的应用程序,我们通常称之为单体应用.架构单体应用的方法论,我们称之为单体应用架构. 缺点:1. 复杂性高以笔者经手的一个 ...

  7. 从零开始学spring cloud(九) -------- 超时机制,断路器模式介绍

    目前存在的问题: 现在我们假设一下,服务提供者响应非常缓慢,那么消费者对提供者的请求就会被强制等待,直到服务返回.在高负载场景下,如果不做任何处理,这种问题很可能造成所有处理用户请求的线程都被耗竭,而 ...

  8. 从零开始学spring cloud(八) -------- Eureka 高可用机制

    一.Eureka高可用机制介绍 Eureka服务器没有后端存储,但注册表中的服务实例都必须发送心跳以使其注册保持最新(因此可以在内存中完成). 客户端还有一个Eureka注册的内存缓存(因此,他们不必 ...

  9. 从零开始学spring cloud(三) -------- Eureka简介

    1.服务发现组件:Eureka Eureka的开源文档介绍地址:https://github.com/Netflix/eureka/wiki/Eureka-at-a-glance What is Eu ...

随机推荐

  1. 怎么安装Scrapy框架以及安装时出现的一系列错误(win7 64位 python3 pycharm)

    因为要学习爬虫,就打算安装Scrapy框架,以下是我安装该模块的步骤,适合于刚入门的小白: 一.打开pycharm,依次点击File---->setting---->Project---- ...

  2. 五、使用druid管理数据库,mybatis连接mysql数据库

    简介:    使用 mybatis 连接 mysql 数据库, 一套简单的增删改查流程, 前台用 bootstrap, bootstrap-table 框架, 最后用 druid 监控数据库连接情况 ...

  3. About Gnu Linker1

    1 OverView ld combines a number of object and archive files, relocates their data and ties up symbol ...

  4. PROC IMPORT 选项

    GETNAMES=YES;导入源文件字段名作为SAS数据集的字段名MIXED=NO;若某一列中包含数值型和字符型变量,将数值型按照缺省值处理.若选的是YES则是将数值型转换成字符型存储,默认为NOSC ...

  5. How To Upgrade ASMLib Kernel Driver as Part of Kernel Upgrade? (文档 ID 1391807.1)

    How To Upgrade ASMLib Kernel Driver as Part of Kernel Upgrade? (文档 ID 1391807.1)

  6. python定时器

    1.定时器用法 [1]需要注意的就是创建定时器后,会创建一个线程,程序退出之前需要调用cancel()函数关闭定时器,否则程序退不出. # -*- coding: utf-8 -*- import o ...

  7. 采用自定义协议代替OCX组件

    事情起源:公司视频播放一直是采用的嵌入浏览器组件实现视频的预览回放等功能.这种实现方式要求客户使用IE浏览器. 最近上线项目使用Html 5开发,要求IE11.项目中使用了视频播放功能,如果全部升级到 ...

  8. Java使用Jedis操作Redis大全

    Java操作Redis需要导入两个jar: commons-pool2-2.4.2.jar jedis-2.1.0.jar package com.chinasofti.test; import ja ...

  9. es6 和 python 语法比较

    http://www.linchaoqun.com/html/cms/content.jsp?id=1509528630774 Python3笔记:Python与ECMAScript部分语法对比 ht ...

  10. 稀疏矩阵 part 4

    ▶ 各种稀疏矩阵数据结构下 y(n,1) = A(n,m) * x(m,1) 的实现,GPU版本 ● MAT 乘法 __global__ void dotGPU(const MAT *a, const ...