Hystrix面试 - 基于本地缓存的 fallback 降级机制

Hystrix 出现以下四种情况,都会去调用 fallback 降级机制:

  • 断路器处于打开的状态。
  • 资源池已满(线程池+队列 / 信号量)。
  • Hystrix 调用各种接口,或者访问外部依赖,比如 MySQL、Redis、Zookeeper、Kafka 等等,出现了任何异常的情况。
  • 访问外部依赖的时候,访问时间过长,报了 TimeoutException 异常。

两种最经典的降级机制

  • 纯内存数据
    在降级逻辑中,你可以在内存中维护一个 ehcache,作为一个纯内存的基于 LRU 自动清理的缓存,让数据放在缓存内。如果说外部依赖有异常,fallback 这里直接尝试从 ehcache 中获取数据。

  • 默认值
    fallback 降级逻辑中,也可以直接返回一个默认值。

在 HystrixCommand,降级逻辑的书写,是通过实现 getFallback() 接口;而在 HystrixObservableCommand 中,则是实现 resumeWithFallback() 方法。

现在,我们用一个简单的栗子,来演示 fallback 降级是怎么做的。

比如,有这么个场景。我们现在有个包含 brandId 的商品数据,假设正常的逻辑是这样:拿到一个商品数据,根据 brandId 去调用品牌服务的接口,获取品牌的最新名称 brandName。

假如说,品牌服务接口挂掉了,那么我们可以尝试从本地内存中,获取一份稍过期的数据,先凑合着用。

步骤一:本地缓存获取数据

本地获取品牌名称的代码大致如下。

/*** 品牌名称本地缓存**/public class BrandCache {private static Map<Long, String> brandMap = new HashMap<>();static {brandMap.put(1L, "Nike");}/*** brandId 获取 brandName* @param brandId 品牌id* @return 品牌名*/public static String getBrandName(Long brandId) {return brandMap.get(brandId);}

步骤二:实现 GetBrandNameCommand

在 GetBrandNameCommand 中,run() 方法的正常逻辑是去调用品牌服务的接口获取到品牌名称,如果调用失败,报错了,那么就会去调用 fallback 降级机制。

这里,我们直接模拟接口调用报错,给它抛出个异常。

而在 getFallback() 方法中,就是我们的降级逻辑,我们直接从本地的缓存中,获取到品牌名称的数据。

/*** 获取品牌名称的command**/public class GetBrandNameCommand extends HystrixCommand<String> {private Long brandId;public GetBrandNameCommand(Long brandId) {super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("BrandService")).andCommandKey(HystrixCommandKey.Factory.asKey("GetBrandNameCommand")).andCommandPropertiesDefaults(HystrixCommandProperties.Setter()// 设置降级机制最大并发请求数.withFallbackIsolationSemaphoreMaxConcurrentRequests(15)));this.brandId = brandId;}@Overrideprotected String run() throws Exception {// 这里正常的逻辑应该是去调用一个品牌服务的接口获取名称// 如果调用失败,报错了,那么就会去调用fallback降级机制// 这里我们直接模拟调用报错,抛出异常throw new Exception();}@Overrideprotected String getFallback() {return BrandCache.getBrandName(brandId);}
}

FallbackIsolationSemaphoreMaxConcurrentRequests 用于设置 fallback 最大允许的并发请求量,默认值是 10,是通过 semaphore 信号量的机制去限流的。如果超出了这个最大值,那么直接 reject。

步骤三:CacheController 调用接口

在 CacheController 中,我们通过 productInfo 获取 brandId,然后创建 GetBrandNameCommand 并执行,去尝试获取 brandName。这里执行会报错,因为我们在 run() 方法中直接抛出异常,Hystrix 就会去调用 getFallback() 方法走降级逻辑。

@Controller
public class CacheController {@RequestMapping("/getProductInfo")@ResponseBodypublic String getProductInfo(Long productId) {HystrixCommand<ProductInfo> getProductInfoCommand = new GetProductInfoCommand(productId);ProductInfo productInfo = getProductInfoCommand.execute();Long brandId = productInfo.getBrandId();HystrixCommand<String> getBrandNameCommand = new GetBrandNameCommand(brandId);// 执行会抛异常报错,然后走降级String brandName = getBrandNameCommand.execute();productInfo.setBrandName(brandName);System.out.println(productInfo);return "success";}
}

关于降级逻辑的演示,基本上就结束了。

转载来源:https://github.com/doocs/advanced-java/blob/master/docs/high-availability/hystrix-fallback.md

Hystrix面试 - 基于本地缓存的 fallback 降级机制相关推荐

  1. java 降级_基于本地缓存的 fallback 降级机制

    基于本地缓存的 fallback 降级机制 Hystrix 出现以下四种情况,都会去调用 fallback 降级机制: 断路器处于打开的状态. 资源池已满(线程池+队列 / 信号量). Hystrix ...

  2. Hystrix面试 - 基于 request cache 请求缓存技术优化批量商品数据查询接口

    Hystrix面试 - 基于 request cache 请求缓存技术优化批量商品数据查询接口 Hystrix command 执行时 8 大步骤第三步,就是检查 Request cache 是否有缓 ...

  3. Hystrix面试 - 基于 Hystrix 信号量机制实现资源隔离

    Hystrix面试 - 基于 Hystrix 信号量机制实现资源隔离 Hystrix 里面核心的一项功能,其实就是所谓的资源隔离,要解决的最最核心的问题,就是将多个依赖服务的调用分别隔离到各自的资源池 ...

  4. Hystrix面试 - 基于 timeout 机制为服务接口调用超时提供安全保护

    Hystrix面试 - 基于 timeout 机制为服务接口调用超时提供安全保护 一般来说,在调用依赖服务的接口的时候,比较常见的一个问题就是超时.超时是在一个复杂的分布式系统中,导致系统不稳定,或者 ...

  5. Hystrix面试 - 基于 Hystrix 线程池技术实现资源隔离

    Hystrix面试 - 基于 Hystrix 线程池技术实现资源隔离 上一讲提到,如果从 Nginx 开始,缓存都失效了,Nginx 会直接通过缓存服务调用商品服务获取最新商品数据(我们基于电商项目做 ...

  6. Hystrix面试 - 用 Hystrix 构建高可用服务架构

    Hystrix面试 - 用 Hystrix 构建高可用服务架构 Hystrix 是什么? 在分布式系统中,每个服务都可能会调用很多其他服务,被调用的那些服务就是依赖服务,有的时候某些依赖服务出现故障也 ...

  7. Hystrix面试 - 深入 Hystrix 执行时内部原理

    Hystrix面试 - 深入 Hystrix 执行时内部原理 前面我们了解了 Hystrix 最基本的支持高可用的技术:资源隔离 + 限流. 创建 command: 执行这个 command: 配置这 ...

  8. Hystrix面试 - 深入 Hystrix 断路器执行原理

    Hystrix面试 - 深入 Hystrix 断路器执行原理 RequestVolumeThreshold HystrixCommandProperties.Setter().withCircuitB ...

  9. 本地缓存、分布式缓存以及多级缓存

    像MySql等传统的关系型数据库已经不能适用于所有的业务场景,比如电商系统的秒杀场景,APP首页的访问流量高峰场景,很容易造成关系型数据库的瘫痪,随着缓存技术的出现很好的解决了这个问题. 一.缓存的概 ...

最新文章

  1. pytorch 不同设备下保存和加载模型,需要指定设备
  2. 通过TCP调试助手传输数据时的注意事项
  3. 【Java10】lambda表达式(函数式编程),Stream流,File类,字节/字符流,乱码,缓冲/转换/序列化/打印流,Properties
  4. Python3之configparser模块
  5. 企业版Java EE正式易主 甲骨文再次放手
  6. thinkphp福娃源码交易网站源码
  7. 7-192 素因子分解 (20 分)
  8. spring 事务管理之只读事务@Transactional(readOnly = true)
  9. YouTube 多目标排序系统:如何推荐接下来收看的视频
  10. Java开发熟手该当心的11个错误
  11. python 全国内地高风险地区数量查询与可视化(分省)
  12. 会声会影滤镜特效教程之气泡滤镜
  13. Jlink之J-Scope虚拟示波器
  14. Linux wifi hostpad,将你的电脑变身无线路由wifi host, ipad/ipod/手机一起来无线互联吧...
  15. 教你一招设计图纸不被外泄的方法
  16. CrossFire和SLI
  17. 人生效率手册:如何卓有成效地过好每一天--By张萌姐姐--读书笔记
  18. 山东二本计算机排名大学最新,2018山东二本大学排名
  19. 傻瓜式免费自助建站系统,菜鸟建站理想工具
  20. 浅谈绝对定位与相对定位

热门文章

  1. IndexedDB:浏览器里内置的数据库
  2. 两个SEO技巧让你的网站排名靠前
  3. Python读取dat文件数据并构成Dataframe对象
  4. Tensorflow object detection API 搭建自己的目标检测模型并迁移到Android上
  5. SQL Server流程介绍
  6. 数组的操作与方法的操作 0303 2101
  7. DbHelper重用性方案 优化工具类 jdbc
  8. celery-03-操作a-发布人一方
  9. Laravel Collection 常用方法(1)
  10. 算法--生成可重集排列