• 客户端简单实现断路器


     1:断路器只有两种状态,开启和关闭,默认不开启

    2:通过两个变量保存总请求数和异常请求书-->线程安全

    3:给定一个最大异常的阈值-->到达最大开启断路器

    4:给定一个异常比例阈值-->

    -->当请求数大于0 且 异常请求数大于0

    -->异常/总请求>异常比例

    -->到达开启断路器

    5:定义两个自增计数器保存请求和异常请求

    6:给定一个充值方法,可以通过异步线程重置

    1. package com.trpc.protection;
    2. import java.util.Random;
    3. import java.util.concurrent.atomic.AtomicInteger;
    4. /**
    5. * 断路器
    6. */
    7. public class CircuitBreaker {
    8. //默认不开启
    9. private volatile boolean isOpen=false;
    10. //总请求
    11. private AtomicInteger requestCount=new AtomicInteger(0);
    12. //异常请求
    13. private AtomicInteger errorRequest=new AtomicInteger(0);
    14. //异常阈值
    15. private int maxErrorRequest;
    16. private float MaxErrorRate;
    17. public CircuitBreaker(int maxErrorRequest, float maxErrorRate) {
    18. this.maxErrorRequest = maxErrorRequest;
    19. this.MaxErrorRate = maxErrorRate;
    20. }
    21. /**
    22. * 判断是否开启
    23. */
    24. public synchronized boolean isBreak(){
    25. //1 断路器打开状态
    26. if (isOpen){
    27. return true;
    28. }
    29. //2 异常超过最大数
    30. if (errorRequest.get() > maxErrorRequest){
    31. this.isOpen=true;
    32. return true;
    33. }
    34. //3 存在正确请求和异常请求 同时:大于异常比例
    35. if (errorRequest.get() > 0 && errorRequest.get() > 0 &&
    36. errorRequest.get()/(float)requestCount.get() >MaxErrorRate
    37. ){
    38. this.isOpen=true;
    39. return true;
    40. }
    41. return false;
    42. }
    43. //记录请求数
    44. public void recordRequest(){
    45. this.requestCount.getAndIncrement(); //自增
    46. }
    47. //记录异常请求数
    48. public void recordErrorRequest(){
    49. this.errorRequest.getAndIncrement(); //自增
    50. }
    51. /**
    52. * 重置
    53. */
    54. public void reset(){
    55. this.isOpen=false;
    56. this.requestCount.set(0);
    57. this.errorRequest.set(0);
    58. }
    59. }

    测试方法

    1. public static void main(String[] args) {
    2. //
    3. // CircuitBreaker circuitBreaker = new CircuitBreaker(3,0.5F);
    4. // //熔断比例超过1.1F出现三个异常
    5. // new Thread(() ->{
    6. // for (int i = 0; i < 1000; i++) {
    7. //
    8. // try {
    9. // Thread.sleep(100);
    10. // } catch (InterruptedException e) {
    11. // throw new RuntimeException(e);
    12. // }
    13. // //添加总请求数
    14. // circuitBreaker.recordRequest();
    15. // int num = new Random().nextInt(100);
    16. // if(num > 70){
    17. // //添加异常请求
    18. // circuitBreaker.recordErrorRequest();
    19. // }
    20. //
    21. // boolean aBreak = circuitBreaker.isBreak();
    22. //
    23. // String result = aBreak ? "断路器阻塞了请求":"断路器放行了请求";
    24. //
    25. // System.out.println(result);
    26. //
    27. // }
    28. // }).start();
    29. //
    30. // //每隔两秒钟重置熔断器
    31. // new Thread(() -> {
    32. // for (;;) {
    33. // try {
    34. // Thread.sleep(2000);
    35. // } catch (InterruptedException e) {
    36. // throw new RuntimeException(e);
    37. // }
    38. // System.out.println("-----------------------------------------");
    39. // circuitBreaker.reset();
    40. // }
    41. // }).start();
    42. //
    43. // try {
    44. // Thread.sleep(1000000);
    45. // } catch (InterruptedException e) {
    46. // throw new RuntimeException(e);
    47. // }
    48. //
    49. }

  • 相关阅读:
    【设计模式之策略模式 -- C++】
    轻量级CI/CD发布部署环境搭建及使用_01_基本介绍
    Tomcat(一) 系统架构
    大师傅敢死队风格
    Linux:基础命令
    以变化的角度看待 dpdk 中向量收发包函数的限制
    JAVASE语法零基础——Object类
    若依3.x.x版本环境搭建
    49. Group Anagrams
    前端JavaScript中异步的终极解决方案:async/await
  • 原文地址:https://blog.csdn.net/asmall_cat/article/details/132839746