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

核心思想:

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

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

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

理解:

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

  

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger; @Aspect
@Component
@Slf4j
public class CircuitBreakerAspect {
// 阀值
private static final Integer THRESHOLD = 3;
//记录失败的次数
private Map<String, AtomicInteger> counter = new ConcurrentHashMap<>();
// 记录被保护的次数
private Map<String, AtomicInteger> breakCounter = new ConcurrentHashMap<>(); /**
*
* @param pjp 程序连接点
* @return
* @throws Throwable
*/
@Around("execution(* 拦截的区域")
public Object doWithCircuitBreaker(ProceedingJoinPoint pjp) throws Throwable {
// 获取当前执行的方法
String signature = pjp.getSignature().toLongString();
log.info("Invoke {}", signature);
Object retVal;
try {
if (counter.containsKey(signature)) {
// 失败次数达到预制,如果保护次数没到,返回null
if (counter.get(signature).get() > THRESHOLD &&
breakCounter.get(signature).get() < THRESHOLD) {
log.warn("Circuit breaker return null, break {} times.",
breakCounter.get(signature).incrementAndGet());
return null;
}
} else {
counter.put(signature, new AtomicInteger(0));
breakCounter.put(signature, new AtomicInteger(0));
}
retVal = pjp.proceed();
counter.get(signature).set(0);
breakCounter.get(signature).set(0);
} catch (Throwable t) {
log.warn("Circuit breaker counter: {}, Throwable {}",
counter.get(signature).incrementAndGet(), t.getMessage());
breakCounter.get(signature).set(0);
throw t;
}
return retVal;
}
}

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引入

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

  application.properties


feign.client.config.default.connect-timeout=500
feign.client.config.default.read-timeout=500

#开启feign支持
feign.hystrix.enabled=true #cousul连接配置
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
spring.cloud.consul.discovery.prefer-ip-address=true
 

bootstarp.properties

spring.application.name=name-service

开启注解:

@EnableDiscoveryClient // 注册发现服务
@EnableFeignClients // feign的支持
@EnableCircuitBreaker // feignClient的演示
  //Spring  cloud 支持
@PostMapping("/order")
@HystrixCommand(fallbackMethod = "fallbackCreateOrder")
public CoffeeOrder createOrder() {
/*业务代码*/
return order;
} public CoffeeOrder fallbackCreateOrder() {
log.warn("Fallback to NULL order.");
return null;
}
//FeignClient 的支持

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.RequestParam; import java.util.List; @FeignClient(name = "waiter-service", contextId = "coffee",
qualifier = "coffeeService", path="/coffee",
fallback = FallbackCoffeeService.class)
// 如果用了Fallback,不要在接口上加@RequestMapping,path可以用在这里
public interface TestService { @GetMapping("/{id}")
Product getById(@PathVariable Long id); } /*实现TestService*/ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import java.util.Collections;
import java.util.List; @Slf4j
@Component
public class FallbackTestService implements TestService{ @Override
public Product getById(Long id) {
/**发送了垄断的逻辑代码*/
return null;
} }
/**Controller调用*/ @GetMapping("testGetById")
public String testGetById() {
TestService.getById((long) 1);
return "";
}

断路器,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. python 安装 pip ,并使用pip 安装 filetype

    闲话少说,直接上操作. python版本为2.7.6 可以直接到官网下载,我也提供一个百度云的下载地址 https://pan.baidu.com/s/1kWPXG8Z 这个是window版本,lin ...

  2. idea旗舰版续命

    首先鼓励大家使用正版!我一直用的是免费的社区版,但发现有一些功能被阉割了,比如weblogbic就不支持,无奈现在的项目要用到这个,只能去下载旗舰版. 旗舰版需要付费,作为程序员的我为了一个临时的项目 ...

  3. Python在线IDE | 谷歌Colaboratory云端IDE介绍

    目录 1. 推荐阅读 2. 本文地址 3. 按 4. 使用篇 6. 教学篇 1. 推荐阅读 Python基础入门一文通 | Python2 与Python3及VSCode下载和安装.PyCharm破解 ...

  4. javaweb各种框架组合案例(九):springboot+tk.mybatis+通用service

    一.项目结构 二.pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns= ...

  5. java并发学习--第六章 线程之间的通信

    一.等待通知机制wait()与notify() 在线程中除了线程同步机制外,还有一个最重要的机制就是线程之间的协调任务.比如说最常见的生产者与消费者模式,很明显如果要实现这个模式,我们需要创建两个线程 ...

  6. 伊朗Cisco路由器遭黑客攻击 全国互联网几乎瘫痪

    2018年4月9日,黑客攻击了伊朗的国家信息数据中心.伊朗internet信息安全部称,此次大规模袭击影响了全球约二十万个思科Cisco路由交换器,也包括伊朗的几千个路由器.攻击也影响了互联网服务供应 ...

  7. RAC搭建---自己做

    一.本地磁盘是指你本身加上去的磁盘,只能本机使用的.共享磁盘是指可以多台机器同时读取写入.你做RAC就要用到共享存储: 二.ORC分区一般1G*3  数据分区5G*3  ,FRA分区一般5G*3  这 ...

  8. 029:url标签使用详解

    url标签使用详解: 在模版中,我们经常要写一些 url ,比如某个 a 标签中需要定义 href 属性.当然如果通过硬编码的方式直接将这个 url 写死在里面也是可以的.但是这样对于以后项目维护可能 ...

  9. JavaWeb(四):JDBC

    数据持久化(persistence) 把数据保存到可掉电式存储设备中以供之后使用. 大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以”固化”,而持久化的实现过程大多通过各 ...

  10. 【leetcode】1026. Maximum Difference Between Node and Ancestor

    题目如下: Given the root of a binary tree, find the maximum value V for which there exists different nod ...