断路器:https://martinfowler.com/bliki/CircutiBreaker.html

核心思想:

  在断路器对象中封装受保护的方法调用。

  该断路器监控调用和断路情况

  调用失败触发阈值后,后续调用直接由短路器返回错误,不再执行实际调用。

理解:

  客户端通过circuit breaker调用服务提供者,正常的时候可以调用。如果服务提供方出现了问题,发生了超时, 前几次可以超时处理, 到达一个阀值可以通过断路器进行处理, 就不再向服务方发起请求。

  

  1. import lombok.extern.slf4j.Slf4j;
  2. import org.aspectj.lang.ProceedingJoinPoint;
  3. import org.aspectj.lang.annotation.Around;
  4. import org.aspectj.lang.annotation.Aspect;
  5. import org.springframework.stereotype.Component;
  6.  
  7. import java.util.Map;
  8. import java.util.concurrent.ConcurrentHashMap;
  9. import java.util.concurrent.atomic.AtomicInteger;
  10.  
  11. @Aspect
  12. @Component
  13. @Slf4j
  14. public class CircuitBreakerAspect {
  15. // 阀值
  16. private static final Integer THRESHOLD = 3;
  17. //记录失败的次数
  18. private Map<String, AtomicInteger> counter = new ConcurrentHashMap<>();
  19. // 记录被保护的次数
  20. private Map<String, AtomicInteger> breakCounter = new ConcurrentHashMap<>();
  21.  
  22. /**
  23. *
  24. * @param pjp 程序连接点
  25. * @return
  26. * @throws Throwable
  27. */
  28. @Around("execution(* 拦截的区域")
  29. public Object doWithCircuitBreaker(ProceedingJoinPoint pjp) throws Throwable {
  30. // 获取当前执行的方法
  31. String signature = pjp.getSignature().toLongString();
  32. log.info("Invoke {}", signature);
  33. Object retVal;
  34. try {
  35. if (counter.containsKey(signature)) {
  36. // 失败次数达到预制,如果保护次数没到,返回null
  37. if (counter.get(signature).get() > THRESHOLD &&
  38. breakCounter.get(signature).get() < THRESHOLD) {
  39. log.warn("Circuit breaker return null, break {} times.",
  40. breakCounter.get(signature).incrementAndGet());
  41. return null;
  42. }
  43. } else {
  44. counter.put(signature, new AtomicInteger(0));
  45. breakCounter.put(signature, new AtomicInteger(0));
  46. }
  47. retVal = pjp.proceed();
  48. counter.get(signature).set(0);
  49. breakCounter.get(signature).set(0);
  50. } catch (Throwable t) {
  51. log.warn("Circuit breaker counter: {}, Throwable {}",
  52. counter.get(signature).incrementAndGet(), t.getMessage());
  53. breakCounter.get(signature).set(0);
  54. throw t;
  55. }
  56. return retVal;
  57. }
  58. }

Hystrix

Hystrix [hɪst'rɪks],中文含义是豪猪,因其背上长满棘刺,从而拥有了自我保护的能力。本文所说的Hystrix是Netflix开源的一款容错框架,同样具有自我保护能力。为了实现容错和自我保护,下面我们看看Hystrix如何设计和实现的。

Hystrix设计目标

  • 对来自依赖的延迟和故障进行防护和控制——这些依赖通常都是通过网络访问的
  • 阻止故障的连锁反应
  • 快速失败并迅速恢复
  • 回退并优雅降级
  • 提供近实时的监控

实现了断路服务器模式

在需要服务熔断的方法上添加@HystrixCommand注解, fallbackMethod指定熔断的地址,默认情况下@HystrixCommand是在另外一个线程执行的。可以做一些超时的处理。

@HystrixProperty(name="excution.isolation.strategy",value="SEMAPHORE")设置为信号

  

Hystrix配置项参考:

Spring cloud 支持

  spring-cloud-starter-netfixi-hystrix

  @EnableCircuitBreaker

Feign支持

  feign.hystrix.enable=true

  @FeignClient

    fallback / fallbackFactory

简单示例:

  pom引入

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
  4. </dependency>

  application.properties

  1.  
  1. feign.client.config.default.connect-timeout=500
    feign.client.config.default.read-timeout=500
  1.  
  2. #开启feign支持
  3. feign.hystrix.enabled=true
  4.  
  5. #cousul连接配置
  1. spring.cloud.consul.host=localhost
    spring.cloud.consul.port=8500
    spring.cloud.consul.discovery.prefer-ip-address=true
  1.  

bootstarp.properties

  1. spring.application.name=name-service

开启注解:

  1. @EnableDiscoveryClient // 注册发现服务
    @EnableFeignClients // feign的支持
    @EnableCircuitBreaker // feignClient的演示
  1.   //Spring cloud 支持
  2. @PostMapping("/order")
  3. @HystrixCommand(fallbackMethod = "fallbackCreateOrder")
  4. public CoffeeOrder createOrder() {
  5. /*业务代码*/
  6. return order;
  7. }
  8.  
  9. public CoffeeOrder fallbackCreateOrder() {
  10. log.warn("Fallback to NULL order.");
  11. return null;
  12. }
  1. //FeignClient 的支持
  2.  
  3. import org.springframework.cloud.openfeign.FeignClient;
  4. import org.springframework.web.bind.annotation.GetMapping;
  5. import org.springframework.web.bind.annotation.PathVariable;
  6. import org.springframework.web.bind.annotation.RequestParam;
  7.  
  8. import java.util.List;
  9.  
  10. @FeignClient(name = "waiter-service", contextId = "coffee",
  11. qualifier = "coffeeService", path="/coffee",
  12. fallback = FallbackCoffeeService.class)
  13. // 如果用了Fallback,不要在接口上加@RequestMapping,path可以用在这里
  14. public interface TestService {
  15.  
  16. @GetMapping("/{id}")
  17. Product getById(@PathVariable Long id);
  18.  
  19. }
  20.  
  21. /*实现TestService*/
  22.  
  23. import lombok.extern.slf4j.Slf4j;
  24. import org.springframework.stereotype.Component;
  25.  
  26. import java.util.Collections;
  27. import java.util.List;
  28.  
  29. @Slf4j
  30. @Component
  31. public class FallbackTestService implements TestService{
  32.  
  33. @Override
  34. public Product getById(Long id) {
  35. /**发送了垄断的逻辑代码*/
  36. return null;
  37. }
  38.  
  39. }
  40. /**Controller调用*/
  41.  
  42. @GetMapping("testGetById")
  43. public String testGetById() {
  44. TestService.getById((long) 1);
  45. return "";
  46. }

断路器,AOP实现断路器模式 ------------Hystrix的更多相关文章

  1. 为了支持AOP的编程模式,我为.NET Core写了一个轻量级的Interception框架[开源]

    ASP.NET Core具有一个以ServiceCollection和ServiceProvider为核心的依赖注入框架,虽然这只是一个很轻量级的框架,但是在大部分情况下能够满足我们的需要.不过我觉得 ...

  2. Hibernate 延迟加载的代理模式 和 Spring AOP的代理模式

    Hibernate 延迟加载的代理模式 和 Spring AOP的代理模式 主题 概念 Hibernate 延迟加载的代理模式 Spring AOP的代理模式 区别和联系 静态代理和动态代理 概念 代 ...

  3. AOP基础—代理模式

    代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代 ...

  4. 3.静态AOP实现-代理模式

    通过代理模式实现在RegUser()方法本身业务前后加上一些自己的功能,如:BeforeProceed和AfterProceed,即不修改UserProcessor类又能增加新功能 定义1个用户接口, ...

  5. C# Aspect-Oriented Programming(AOP) 利用多种模式实现动态代理

    什么是AOP(Aspect-Oriented Programming)? AOP允许开发者动态地修改静态的OO模型,构造出一个能够不断增长以满足新增需求的系统,就象现实世界中的对象会在其生命周期中不断 ...

  6. 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)

    好长时间没有用过Spring了. 突然拿起书.我都发现自己对AOP都不熟悉了. 其实AOP的意思就是面向切面编程. OO注重的是我们解决问题的方法(封装成Method),而AOP注重的是许多解决解决问 ...

  7. 关于在C#中实现AOP 拦截编程模式的新的探索

    前面有篇文章,是从其他个人博客中贴过来的.地址:http://www.lanhusoft.com/Article/240.html 作者总结实现的挺好. 但是.不能不考虑性能!!使用 ContextB ...

  8. 5.动态代理AOP实现-DynamicProxy模式

    通过动态代理模式Interceptor实现在RegUser()方法本身业务前后加上一些自己的功能,如:PreProceed和PostProceed,即不修改UserProcessor类又能增加新功能 ...

  9. AOP的工作模式

    代理主要有静态代理和动态代理. 静态代理:在代理中实现接口并创建实现类对象,在对实现类的方法增加功能(不常用). 动态代理:实现implements InvocationHandler接口.实现方法: ...

随机推荐

  1. 【记录】Git pull(拉取),push(上传)命令整理(详细)

    前言:博主最近在学习git命令,因为git是一个非常好用的分布式版本管理工具,功能比svn强大,与SVN不同点是Git去中心化,每一个分支都是一个中心,并且支持本地仓库存储,像如今很多大公司都用git ...

  2. nodejs 更新代码自动刷新页面

    安装第三方工具: nodemon npm install --global nodemon 安装完毕后使用: 之前使用: node xxx.js 改成 nodemon xxx.js 只要通过nodem ...

  3. es6 扩展运算符 三个点...

    es6中引入扩展运算符…,它用于把一个数组转化为用逗号分隔的参数序列,它常用在不定参数个数时的函数调用,数组合并等情形.因为typeScript是es6的超集,所以typeScript也支持扩展运算符 ...

  4. idhttp.get返回403错误解决办法

    在GET之前,先指定UserAgent参数IdHTTP1.Request.UserAgent := 'Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; Ma ...

  5. c#Main()方法,java 是小写main

    main 方法,staitc 静态关键首字母大写,区分大小写,java 是main小写,返回值 ,vodi,int参数:可选static void Main(string[] args){ }

  6. python网络编程之验证客户端链接的合法性

    六.socket的更多方法介绍 服务端套接字函数s.bind() 绑定(主机,端口号)到套接字s.listen() 开始TCP监听s.accept() b被动接收TCP客户的连接,(阻塞式)等待连接的 ...

  7. Fckeditor实现WORD粘贴图片自动上传

    在之前在工作中遇到在富文本编辑器中粘贴图片不能展示的问题,于是各种网上扒拉,终于找到解决方案,在这里感谢一下知乎中众大神以及TheViper. 通过知乎提供的思路找到粘贴的原理,通过TheViper找 ...

  8. vue动态路由传值以及get传值及编程式导航

    1.动态路由传值 1.配置路由处 { path: '/content/:id', component: Content }, // 动态路由 2.对应页面传值 <router-link :to= ...

  9. python中将12345转换为54321

    #将12345转换为54321 a = 12345789 ret = 0 #当a不为零的时候,循环条件为true,执行语句块 while a : #对a求余数,第一次循环则把5求出来 last = a ...

  10. ZOJ 3822 ( 2014牡丹江区域赛D题) (概率dp)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5376 题意:每天往n*m的棋盘上放一颗棋子,求多少天能将棋盘的每行每列都至少有 ...