【Spring Boot】 Spring Boot之Hystrix使用介绍

一、Maven依赖

 

一、Maven依赖 

<!-- hystrix -->
<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-core</artifactId>
    <version>1.5.18</version>
</dependency>
<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-javanica</artifactId>
    <version>1.5.18</version>
</dependency>
<dependency>
    <groupId>de.ahus1.prometheus.hystrix</groupId>
    <artifactId>prometheus-hystrix</artifactId>
    <version>4.0.0</version>
    <exclusions>
        <exclusion>
            <artifactId>simpleclient</artifactId>
            <groupId>io.prometheus</groupId>
        </exclusion>
        <exclusion>
            <artifactId>simpleclient_common</artifactId>
            <groupId>io.prometheus</groupId>
        </exclusion>
        <exclusion>
            <artifactId>hystrix-core</artifactId>
            <groupId>com.netflix.hystrix</groupId>
        </exclusion>
    </exclusions>
</dependency>
Hystrix Maven依赖坐标

二、添加核心类

优化点:

1、自定义并发策略,主要重写了线程池的拒绝策略,默认是直接拒绝(主线程执行并告警)

2、统一了线程池的定义方式以及启动初始化线程池 (这样处理的好处就是简化了使用)

/**
 * @Author zhangboqing
 * @Date 2020/11/17
 */
@Configuration
@Slf4j
public class HystrixCircuitBreakerConfiguration {
 
   @Autowired(required = false)
   private HystrixConcurrencyStrategy existingConcurrencyStrategy;
   @Autowired
   CollectorRegistry registry;
 
   @Bean
   public HystrixCommandAspect hystrixCommandAspect() {
      return new HystrixCommandAspect();
   }
 
   @Bean
   public HystrixShutdownHook hystrixShutdownHook() {
      return new HystrixShutdownHook();
   }
 
   @Bean
   DefaultHystrixConcurrencyStrategy defaultHystrixConcurrencyStrategy(Tracing tracing, SpanNamer spanNamer) {
      return new DefaultHystrixConcurrencyStrategy(tracing, spanNamer);
   }
 
   @PostConstruct
   public void init() {
      // Keeps references of existing Hystrix plugins.
      HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance()
            .getEventNotifier();
      HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance()
            .getMetricsPublisher();
      HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance()
            .getPropertiesStrategy();
      HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance()
            .getCommandExecutionHook();
      HystrixConcurrencyStrategy concurrencyStrategy = detectRegisteredConcurrencyStrategy();
 
      HystrixPlugins.reset();
      // Registers existing plugins excepts the Concurrent Strategy plugin.
      HystrixPlugins.getInstance().registerConcurrencyStrategy(concurrencyStrategy);
      HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
      HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
      HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
      HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);
 
        HystrixPrometheusMetricsPublisher.builder().withRegistry(registry).shouldExportProperties(true).buildAndRegister();
 
        // 初始化线程池
      initThreadPoolKey();
   }
 
   private void initThreadPoolKey() {
      HystrixThreadPoolKeyEnum[] values = HystrixThreadPoolKeyEnum.values();
      if (values.length > 0) {
         Arrays.stream(values).forEach(key->{
            new BaseHystrixCommand(key) {
               @Override
               protected Object run() throws Exception {
                  return null;
               }
            }.execute();
         });
      }
   }
 
   private HystrixConcurrencyStrategy detectRegisteredConcurrencyStrategy() {
      HystrixConcurrencyStrategy registeredStrategy = HystrixPlugins.getInstance()
            .getConcurrencyStrategy();
      if (existingConcurrencyStrategy == null) {
         return registeredStrategy;
      }
      // Hystrix registered a default Strategy.
      if (registeredStrategy instanceof HystrixConcurrencyStrategyDefault) {
         return existingConcurrencyStrategy;
      }
      // If registeredStrategy not the default and not some use bean of
      // existingConcurrencyStrategy.
      if (!existingConcurrencyStrategy.equals(registeredStrategy)) {
         log.warn(
               "Multiple HystrixConcurrencyStrategy detected. Bean of HystrixConcurrencyStrategy was used.");
      }
      return existingConcurrencyStrategy;
   }
 
   /**
    * {@link DisposableBean} that makes sure that Hystrix internal state is cleared when
    * {@link ApplicationContext} shuts down.
    */
   private class HystrixShutdownHook implements DisposableBean {
 
      @Override
      public void destroy() throws Exception {
         // Just call Hystrix to reset thread pool etc.
         Hystrix.reset();
      }
 
   }
 
}
HystrixCircuitBreakerConfiguration
/**
 * @Author zhangboqing
 * @Date 2020/11/12
 */
@Component
@Slf4j
public class DefaultHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
 
    @Autowired
    private PolarisMetricsService polarisMetricsService;
 
 
    @Override
    public ThreadPoolExecutor getThreadPool(final HystrixThreadPoolKey threadPoolKey, HystrixProperty<Integer> corePoolSize, HystrixProperty<Integer> maximumPoolSize, HystrixProperty<Integer> keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        final ThreadFactory threadFactory = getThreadFactory(threadPoolKey);
 
        final int dynamicCoreSize = corePoolSize.get();
        final int dynamicMaximumSize = maximumPoolSize.get();
 
 
        if (dynamicCoreSize > dynamicMaximumSize) {
            log.error("Hystrix ThreadPool configuration at startup for : " + threadPoolKey.name() + " is trying to set coreSize = " +
                    dynamicCoreSize + " and maximumSize = " + dynamicMaximumSize + ".  Maximum size will be set to " +
                    dynamicCoreSize + ", the coreSize value, since it must be equal to or greater than the coreSize value");
            return new ThreadPoolExecutor(dynamicCoreSize, dynamicCoreSize, keepAliveTime.get(), unit, workQueue, threadFactory, new DefaultRejectedExecutionHandler(polarisMetricsService,threadPoolKey));
        } else {
            return new ThreadPoolExecutor(dynamicCoreSize, dynamicMaximumSize, keepAliveTime.get(), unit, workQueue, threadFactory, new DefaultRejectedExecutionHandler(polarisMetricsService,threadPoolKey));
        }
    }
 
    @Override
    public ThreadPoolExecutor getThreadPool(final HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties threadPoolProperties) {
        final ThreadFactory threadFactory = getThreadFactory(threadPoolKey);
 
        final boolean allowMaximumSizeToDivergeFromCoreSize = threadPoolProperties.getAllowMaximumSizeToDivergeFromCoreSize().get();
        final int dynamicCoreSize = threadPoolProperties.coreSize().get();
        final int keepAliveTime = threadPoolProperties.keepAliveTimeMinutes().get();
        final int maxQueueSize = threadPoolProperties.maxQueueSize().get();
        final BlockingQueue<Runnable> workQueue = getBlockingQueue(maxQueueSize);
 
        if (allowMaximumSizeToDivergeFromCoreSize) {
            final int dynamicMaximumSize = threadPoolProperties.maximumSize().get();
            if (dynamicCoreSize > dynamicMaximumSize) {
                log.error("Hystrix ThreadPool configuration at startup for : " + threadPoolKey.name() + " is trying to set coreSize = " +
                        dynamicCoreSize + " and maximumSize = " + dynamicMaximumSize + ".  Maximum size will be set to " +
                        dynamicCoreSize + ", the coreSize value, since it must be equal to or greater than the coreSize value");
                return new ThreadPoolExecutor(dynamicCoreSize, dynamicCoreSize, keepAliveTime, TimeUnit.MINUTES, workQueue, threadFactory, new DefaultRejectedExecutionHandler(polarisMetricsService,threadPoolKey));
            } else {
                return new ThreadPoolExecutor(dynamicCoreSize, dynamicMaximumSize, keepAliveTime, TimeUnit.MINUTES, workQueue, threadFactory, new DefaultRejectedExecutionHandler(polarisMetricsService,threadPoolKey));
            }
        } else {
            return new ThreadPoolExecutor(dynamicCoreSize, dynamicCoreSize, keepAliveTime, TimeUnit.MINUTES, workQueue, threadFactory, new DefaultRejectedExecutionHandler(polarisMetricsService,threadPoolKey));
        }
    }
 
    private static ThreadFactory getThreadFactory(final HystrixThreadPoolKey threadPoolKey) {
        if (!PlatformSpecific.isAppEngineStandardEnvironment()) {
            return new ThreadFactory() {
                private final AtomicInteger threadNumber = new AtomicInteger(0);
 
                @Override
                public Thread newThread(Runnable r) {
                    Thread thread = new Thread(r, "hystrix-" + threadPoolKey.name() + "-" + threadNumber.incrementAndGet());
                    thread.setDaemon(true);
                    return thread;
                }
 
            };
        } else {
            return PlatformSpecific.getAppEngineThreadFactory();
        }
    }
 
    public static class DefaultRejectedExecutionHandler implements RejectedExecutionHandler {
 
        private PolarisMetricsService polarisMetricsService;
        private HystrixThreadPoolKey threadPoolKey;
 
        public DefaultRejectedExecutionHandler(PolarisMetricsService polarisMetricsService, HystrixThreadPoolKey threadPoolKey) {
            this.polarisMetricsService = polarisMetricsService;
            this.threadPoolKey = threadPoolKey;
        }
 
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            // 请求阻塞,告警
            polarisMetricsService.recordMetrics(PolarisCommonMetricEnum.HYSTRIX_THREAD_POOL_FULL_WARNING.generatePolarisParam("Hystrix Warning", "Hystrix线程池队列已满,请扩容,threadPoolKey:" + threadPoolKey.name()));
            if (!executor.isShutdown()) {
                r.run();
            }
        }
    }
}
DefaultHystrixConcurrencyStrategy
/**
 * @Author zhangboqing
 * @Date 2020/11/17
 */
public abstract class BaseHystrixCommand<R> extends HystrixCommand<R> {
 
    public BaseHystrixCommand(HystrixThreadPoolKeyEnum threadPoolKeyEnum) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(threadPoolKeyEnum.getThreadPoolKey()))
                /* 使用HystrixThreadPoolKey工厂定义线程池名称*/
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(threadPoolKeyEnum.getThreadPoolKey()))
                .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                        .withExecutionTimeoutEnabled(threadPoolKeyEnum.getExecutionTimeoutEnabled())
                        .withExecutionTimeoutInMilliseconds(threadPoolKeyEnum.getExecutionTimeoutInMilliseconds()))
                .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter().withCoreSize(threadPoolKeyEnum.getCoreSize()).withMaximumSize(threadPoolKeyEnum.getMaximumSize()).withMaxQueueSize(threadPoolKeyEnum.getMaxQueueSize()).withQueueSizeRejectionThreshold(threadPoolKeyEnum.getMaxQueueSize() + 1)));
    }
 
 
    public BaseHystrixCommand(HystrixThreadPoolKeyEnum threadPoolKeyEnum,Integer timeoutInMilliseconds) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(threadPoolKeyEnum.getThreadPoolKey()))
                /* 使用HystrixThreadPoolKey工厂定义线程池名称*/
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(threadPoolKeyEnum.getThreadPoolKey()))
                .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                        .withExecutionTimeoutEnabled(true)
                        .withExecutionTimeoutInMilliseconds(timeoutInMilliseconds))
                .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter().withCoreSize(threadPoolKeyEnum.getCoreSize()).withMaximumSize(threadPoolKeyEnum.getMaximumSize()).withMaxQueueSize(threadPoolKeyEnum.getMaxQueueSize()).withQueueSizeRejectionThreshold(threadPoolKeyEnum.getMaxQueueSize() + 1)));
    }
}
BaseHystrixCommand
/**
 * @Author zhangboqing
 * @Date 2020/11/18
 */
@SuppressWarnings(value = "all")
public class HystrixProperties {
 
    // 线程池名称
    // 注意,增加新的线程名必须同时在HystrixThreadPoolKeyEnum中也新增一个,保持1对1的关系
    public static class ThreadPoolName {
 
        public static final String DEFAULT_THREADPOOLKEY = "DEFUALT"; // 默认线程池名称
    }
 
    // 默认属性
    public static final String DEFAULT_EXECUTIONTIMEOUTINMILLISECONDS = "5000"; // 超时时间,单位毫秒
    public static final String DEFAULT_EXECUTIONTIMEOUTENABLED = "false"; // 是否允许超时
    public static final String DEFAULT_CORESIZE = "20"; // 核心线程数
    public static final String DEFAULT_MAXIMUMSIZE = "100"; // 最大线程数
    public static final String DEFAULT_KEEPALIVETIMEMINUTES = "1"; // 闲置线程存活时间,单位分钟
    public static final String DEFAULT_MAXQUEUESIZE = "500"; // 线程池最大队列大小
}
HystrixProperties
 
/**
 * @Author zhangboqing
 * @Date 2020/11/18
 */
@SuppressWarnings(value = "all")
public enum HystrixThreadPoolKeyEnum {
    DEFAULT_HYSTRIX_THREAD_POOL(
            String.valueOf(HystrixProperties.ThreadPoolName.DEFAULT_THREADPOOLKEY),
            Boolean.valueOf(HystrixProperties.DEFAULT_EXECUTIONTIMEOUTENABLED),
            Integer.valueOf(HystrixProperties.DEFAULT_EXECUTIONTIMEOUTINMILLISECONDS),
            Integer.valueOf(HystrixProperties.DEFAULT_CORESIZE),
            Integer.valueOf(HystrixProperties.DEFAULT_MAXIMUMSIZE),
            Integer.valueOf(HystrixProperties.DEFAULT_KEEPALIVETIMEMINUTES),
            Integer.valueOf(HystrixProperties.DEFAULT_MAXQUEUESIZE)
    );
 
 
    HystrixThreadPoolKeyEnum(String threadPoolKey, Boolean executionTimeoutEnabled, Integer executionTimeoutInMilliseconds, Integer coreSize, Integer maximumSize, Integer keepAliveTimeMinutes, Integer maxQueueSize) {
        Assert.hasText(threadPoolKey, "threadPoolKey can not empty");
        Assert.notNull(executionTimeoutEnabled, "executionTimeoutEnabled can not empty");
        Assert.notNull(executionTimeoutInMilliseconds, "executionTimeoutInMilliseconds can not empty");
        Assert.notNull(coreSize, "coreSize can not empty");
        Assert.notNull(maximumSize, "maximumSize can not empty");
        Assert.notNull(keepAliveTimeMinutes, "keepAliveTimeMinutes can not empty");
        Assert.notNull(maxQueueSize, "maxQueueSize can not empty");
 
        this.threadPoolKey = threadPoolKey;
        this.executionTimeoutInMilliseconds = executionTimeoutInMilliseconds;
        this.coreSize = coreSize;
        this.maximumSize = maximumSize;
        this.keepAliveTimeMinutes = keepAliveTimeMinutes;
        this.maxQueueSize = maxQueueSize;
        this.executionTimeoutEnabled = executionTimeoutEnabled;
    }
 
    private final String threadPoolKey;   // 线程池名称
    private final Integer executionTimeoutInMilliseconds; // 超时时间,单位毫秒
    private final Boolean executionTimeoutEnabled; // // 是否允许超时
 
    private final Integer coreSize;  // 核心线程数
    private final Integer maximumSize; // 最大线程数
    private final Integer keepAliveTimeMinutes; // 闲置线程存活时间,单位分钟
    private final Integer maxQueueSize; // 线程池最大队列大小
 
    public String getThreadPoolKey() {
        return threadPoolKey;
    }
 
    public Integer getExecutionTimeoutInMilliseconds() {
        return executionTimeoutInMilliseconds;
    }
 
    public Integer getCoreSize() {
        return coreSize;
    }
 
    public Integer getMaximumSize() {
        return maximumSize;
    }
 
    public Integer getKeepAliveTimeMinutes() {
        return keepAliveTimeMinutes;
    }
 
    public Integer getMaxQueueSize() {
        return maxQueueSize;
    }
 
    public Boolean getExecutionTimeoutEnabled() {
        return executionTimeoutEnabled;
    }
}
HystrixThreadPoolKeyEnum

三、Grafana监控面板配置

 

{
  "annotations": {
    "list": [
      {
        "builtIn": 1,
        "datasource": "-- Grafana --",
        "enable": true,
        "hide": true,
        "iconColor": "rgba(0, 211, 255, 1)",
        "name": "Annotations & Alerts",
        "type": "dashboard"
      }
    ]
  },
  "description": "",
  "editable": true,
  "gnetId": 7145,
  "graphTooltip": 0,
  "id": 3,
  "iteration": 1605446629324,
  "links": [],
  "panels": [
    {
      "collapsed": false,
      "datasource": null,
      "gridPos": {
        "h": 1,
        "w": 24,
        "x": 0,
        "y": 0
      },
      "id": 21,
      "panels": [],
      "title": "Command",
      "type": "row"
    },
    {
      "aliasColors": {},
      "bars": false,
      "cacheTimeout": null,
      "dashLength": 10,
      "dashes": false,
      "datasource": "Prometheus",
      "fieldConfig": {
        "defaults": {
          "custom": {},
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "red",
                "value": 80
              }
            ]
          }
        },
        "overrides": []
      },
      "fill": 1,
      "fillGradient": 0,
      "gridPos": {
        "h": 8,
        "w": 24,
        "x": 0,
        "y": 1
      },
      "hiddenSeries": false,
      "hideTimeOverride": true,
      "id": 2,
      "interval": null,
      "legend": {
        "avg": false,
        "current": false,
        "max": false,
        "min": false,
        "show": true,
        "total": false,
        "values": false
      },
      "lines": true,
      "linewidth": 1,
      "links": [],
      "maxDataPoints": 100,
      "nullPointMode": "null",
      "options": {
        "alertThreshold": true
      },
      "percentage": false,
      "pluginVersion": "7.3.2",
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "spaceLength": 10,
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "expr": "sum(increase({__name__=~\"hystrix_command_event_total\",command_group=~\"$commandGroup\",command_name=~\"$commandName\",job=~\"$service\",instance=~\"$instance\"}[5m])) by (event)",
          "format": "time_series",
          "hide": false,
          "instant": false,
          "interval": "",
          "intervalFactor": 1,
          "legendFormat": "{{event}}",
          "metric": "ml_hystrix_command_is_circuit_breaker_open",
          "refId": "A",
          "step": 1
        },
        {
          "expr": "sum(increase({__name__=~\"hystrix_command_event_total\",event=\"fallback_success\",command_group=~\"$commandGroup\",command_name=~\"$commandName\",job=~\"$service\",instance=~\"$instance\"}[5m])) by (event)",
          "hide": true,
          "interval": "",
          "legendFormat": "",
          "refId": "B"
        },
        {
          "expr": "sum(increase({__name__=~\"hystrix_command_event_total\",event=\"fallback_failure\",command_group=~\"$commandGroup\",command_name=~\"$commandName\",job=~\"$service\",instance=~\"$instance\"}[5m])) by (event)",
          "hide": true,
          "interval": "",
          "legendFormat": "",
          "refId": "C"
        },
        {
          "expr": "sum(increase({__name__=~\"hystrix_command_event_total\",event=\"fallback_missing\",command_group=~\"$commandGroup\",command_name=~\"$commandName\",job=~\"$service\",instance=~\"$instance\"}[5m])) by (event)",
          "hide": true,
          "interval": "",
          "legendFormat": "",
          "refId": "D"
        },
        {
          "expr": "sum(increase({__name__=~\"hystrix_command_event_total\",terminal=\"true\",command_group=~\"$commandGroup\",command_name=~\"$commandName\",job=~\"$service\",instance=~\"$instance\"}[5m])) by (event)",
          "hide": true,
          "interval": "",
          "legendFormat": "",
          "refId": "E"
        }
      ],
      "thresholds": [],
      "timeFrom": "15s",
      "timeRegions": [],
      "timeShift": null,
      "title": "Event Statistics",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        },
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    },
    {
      "aliasColors": {},
      "bars": false,
      "dashLength": 10,
      "dashes": false,
      "datasource": null,
      "description": "",
      "fieldConfig": {
        "defaults": {
          "custom": {}
        },
        "overrides": []
      },
      "fill": 1,
      "fillGradient": 0,
      "gridPos": {
        "h": 8,
        "w": 12,
        "x": 0,
        "y": 9
      },
      "hiddenSeries": false,
      "id": 23,
      "legend": {
        "avg": false,
        "current": false,
        "max": false,
        "min": false,
        "show": true,
        "total": false,
        "values": false
      },
      "lines": true,
      "linewidth": 1,
      "nullPointMode": "null",
      "options": {
        "alertThreshold": true
      },
      "percentage": false,
      "pluginVersion": "7.3.2",
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "spaceLength": 10,
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "expr": "hystrix_command_is_circuit_breaker_open{command_group=~\"$commandGroup\",command_name=~\"$commandName\",job=~\"$service\",instance=~\"$instance\"}",
          "interval": "",
          "legendFormat": "{{command_group}}--{{command_name}}",
          "refId": "A"
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "断路器状态",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        },
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    },
    {
      "aliasColors": {},
      "bars": false,
      "dashLength": 10,
      "dashes": false,
      "datasource": null,
      "fieldConfig": {
        "defaults": {
          "custom": {}
        },
        "overrides": []
      },
      "fill": 1,
      "fillGradient": 0,
      "gridPos": {
        "h": 8,
        "w": 12,
        "x": 12,
        "y": 9
      },
      "hiddenSeries": false,
      "id": 25,
      "legend": {
        "avg": false,
        "current": false,
        "max": false,
        "min": false,
        "show": true,
        "total": false,
        "values": false
      },
      "lines": true,
      "linewidth": 1,
      "nullPointMode": "null",
      "options": {
        "alertThreshold": true
      },
      "percentage": false,
      "pluginVersion": "7.3.2",
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "spaceLength": 10,
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "expr": "hystrix_command_execution_semaphore_permits_in_use{command_group=~\"$commandGroup\",command_name=~\"$commandName\",job=~\"$service\",instance=~\"$instance\"}",
          "interval": "",
          "legendFormat": "{{command_group}}--{{command_name}}",
          "refId": "A"
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "并发执行统计",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        },
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    },
    {
      "aliasColors": {},
      "bars": false,
      "dashLength": 10,
      "dashes": false,
      "datasource": null,
      "fieldConfig": {
        "defaults": {
          "custom": {}
        },
        "overrides": []
      },
      "fill": 1,
      "fillGradient": 0,
      "gridPos": {
        "h": 8,
        "w": 12,
        "x": 0,
        "y": 17
      },
      "hiddenSeries": false,
      "id": 27,
      "legend": {
        "avg": false,
        "current": false,
        "max": false,
        "min": false,
        "show": true,
        "total": false,
        "values": false
      },
      "lines": true,
      "linewidth": 1,
      "nullPointMode": "null",
      "options": {
        "alertThreshold": true
      },
      "percentage": false,
      "pluginVersion": "7.3.2",
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "spaceLength": 10,
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "expr": "sum by(command_group,command_name) (irate(hystrix_command_latency_total_seconds_count{command_group=~\"$commandGroup\",command_name=~\"$commandName\",job=~\"$service\",instance=~\"$instance\"}[5m]))",
          "interval": "",
          "legendFormat": "{{command_group}}--{{command_name}}",
          "refId": "A"
        },
        {
          "expr": "sum(irate(hystrix_command_latency_total_seconds_count{command_group=~\"$commandGroup\",command_name=~\"$commandName\",job=~\"$service\",instance=~\"$instance\"}[5m]))",
          "interval": "",
          "legendFormat": "qps",
          "refId": "B"
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "命令执行次数统计",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        },
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    },
    {
      "aliasColors": {},
      "bars": false,
      "dashLength": 10,
      "dashes": false,
      "datasource": null,
      "fieldConfig": {
        "defaults": {
          "custom": {}
        },
        "overrides": []
      },
      "fill": 1,
      "fillGradient": 0,
      "gridPos": {
        "h": 8,
        "w": 12,
        "x": 12,
        "y": 17
      },
      "hiddenSeries": false,
      "id": 29,
      "legend": {
        "avg": false,
        "current": false,
        "max": false,
        "min": false,
        "show": true,
        "total": false,
        "values": false
      },
      "lines": true,
      "linewidth": 1,
      "nullPointMode": "null",
      "options": {
        "alertThreshold": true
      },
      "percentage": false,
      "pluginVersion": "7.3.2",
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "spaceLength": 10,
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "expr": "sum by (command_group,command_name)(irate(hystrix_command_latency_total_seconds_sum{command_group=~\"$commandGroup\",command_name=~\"$commandName\",job=~\"$service\",instance=~\"$instance\"}[5m])) / sum by (command_group,command_name)(irate(hystrix_command_latency_execute_seconds_count{command_group=~\"$commandGroup\",command_name=~\"$commandName\",job=~\"$service\",instance=~\"$instance\"}[5m])) ",
          "interval": "",
          "legendFormat": "{{command_group}}--{{command_name}}",
          "refId": "A"
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "命令执行时间统计",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        },
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    },
    {
      "aliasColors": {},
      "bars": false,
      "dashLength": 10,
      "dashes": false,
      "datasource": null,
      "fieldConfig": {
        "defaults": {
          "custom": {}
        },
        "overrides": []
      },
      "fill": 1,
      "fillGradient": 0,
      "gridPos": {
        "h": 8,
        "w": 12,
        "x": 0,
        "y": 25
      },
      "hiddenSeries": false,
      "id": 31,
      "legend": {
        "avg": false,
        "current": false,
        "max": false,
        "min": false,
        "show": true,
        "total": false,
        "values": false
      },
      "lines": true,
      "linewidth": 1,
      "nullPointMode": "null",
      "options": {
        "alertThreshold": true
      },
      "percentage": false,
      "pluginVersion": "7.3.2",
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "spaceLength": 10,
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "expr": "irate(hystrix_command_error_total{command_group=~\"$commandGroup\",command_name=~\"$commandName\",job=~\"$service\",instance=~\"$instance\"}[5m])",
          "interval": "",
          "legendFormat": "{{command_group}}--{{command_name}}",
          "refId": "A"
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "命令失败统计",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        },
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    },
    {
      "aliasColors": {},
      "bars": false,
      "dashLength": 10,
      "dashes": false,
      "datasource": null,
      "fieldConfig": {
        "defaults": {
          "custom": {}
        },
        "overrides": []
      },
      "fill": 1,
      "fillGradient": 0,
      "gridPos": {
        "h": 8,
        "w": 12,
        "x": 12,
        "y": 25
      },
      "hiddenSeries": false,
      "id": 33,
      "legend": {
        "avg": false,
        "current": false,
        "max": false,
        "min": false,
        "show": true,
        "total": false,
        "values": false
      },
      "lines": true,
      "linewidth": 1,
      "nullPointMode": "null",
      "options": {
        "alertThreshold": true
      },
      "percentage": false,
      "pluginVersion": "7.3.2",
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "spaceLength": 10,
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "expr": "irate(hystrix_command_total{command_group=~\"$commandGroup\",command_name=~\"$commandName\",job=~\"$service\",instance=~\"$instance\"}[5m])",
          "interval": "",
          "legendFormat": "{{command_group}}--{{command_name}}",
          "refId": "A"
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "命令成功统计",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        },
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    },
    {
      "collapsed": false,
      "datasource": null,
      "gridPos": {
        "h": 1,
        "w": 24,
        "x": 0,
        "y": 33
      },
      "id": 19,
      "panels": [],
      "title": "Thread",
      "type": "row"
    },
    {
      "aliasColors": {},
      "bars": false,
      "dashLength": 10,
      "dashes": false,
      "datasource": null,
      "fieldConfig": {
        "defaults": {
          "custom": {}
        },
        "overrides": []
      },
      "fill": 1,
      "fillGradient": 0,
      "gridPos": {
        "h": 8,
        "w": 12,
        "x": 0,
        "y": 34
      },
      "hiddenSeries": false,
      "id": 35,
      "legend": {
        "avg": false,
        "current": false,
        "max": false,
        "min": false,
        "show": true,
        "total": false,
        "values": false
      },
      "lines": true,
      "linewidth": 1,
      "nullPointMode": "null",
      "options": {
        "alertThreshold": true
      },
      "percentage": false,
      "pluginVersion": "7.3.2",
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "spaceLength": 10,
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "expr": "hystrix_thread_pool_thread_active_count{pool_name=~\"$pool_name\",job=~\"$service\",instance=~\"$instance\"}",
          "hide": true,
          "interval": "",
          "legendFormat": "{{pool_name}}【active】",
          "refId": "A"
        },
        {
          "expr": "hystrix_thread_pool_property_value_core_pool_size{pool_name=~\"$pool_name\",job=~\"$service\",instance=~\"$instance\"}-hystrix_thread_pool_thread_active_count{pool_name=~\"$pool_name\",job=~\"$service\",instance=~\"$instance\"}",
          "interval": "",
          "legendFormat": "{{pool_name}}【idle】",
          "refId": "B"
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "空闲线程数",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        },
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    },
    {
      "aliasColors": {},
      "bars": false,
      "dashLength": 10,
      "dashes": false,
      "datasource": null,
      "fieldConfig": {
        "defaults": {
          "custom": {}
        },
        "overrides": []
      },
      "fill": 1,
      "fillGradient": 0,
      "gridPos": {
        "h": 8,
        "w": 12,
        "x": 12,
        "y": 34
      },
      "hiddenSeries": false,
      "id": 37,
      "legend": {
        "avg": false,
        "current": false,
        "max": false,
        "min": false,
        "show": true,
        "total": false,
        "values": false
      },
      "lines": true,
      "linewidth": 1,
      "nullPointMode": "null",
      "options": {
        "alertThreshold": true
      },
      "percentage": false,
      "pluginVersion": "7.3.2",
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "spaceLength": 10,
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "expr": "hystrix_thread_pool_queue_size{pool_name=~\"$pool_name\",job=~\"$service\",instance=~\"$instance\"}",
          "hide": true,
          "interval": "",
          "legendFormat": "{{pool_name}}【used】",
          "refId": "A"
        },
        {
          "expr": "hystrix_thread_pool_property_value_queue_size_rejection_threshold{pool_name=~\"$pool_name\",job=~\"$service\",instance=~\"$instance\"}-hystrix_thread_pool_queue_size{pool_name=~\"$pool_name\",job=~\"$service\",instance=~\"$instance\"}",
          "interval": "",
          "legendFormat": "{{pool_name}}【idle】",
          "refId": "B"
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "剩余队列大小",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        },
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    }
  ],
  "refresh": "5s",
  "schemaVersion": 26,
  "style": "dark",
  "tags": [],
  "templating": {
    "list": [
      {
        "allValue": null,
        "current": {
          "selected": false,
          "text": "All",
          "value": "$__all"
        },
        "datasource": "Prometheus",
        "definition": "",
        "error": null,
        "hide": 0,
        "includeAll": true,
        "label": "Service",
        "multi": true,
        "name": "service",
        "options": [],
        "query": "label_values(job)",
        "refresh": 1,
        "regex": "",
        "skipUrlSync": false,
        "sort": 0,
        "tagValuesQuery": "",
        "tags": [],
        "tagsQuery": "",
        "type": "query",
        "useTags": false
      },
      {
        "allValue": null,
        "current": {
          "selected": true,
          "text": [
            "All"
          ],
          "value": [
            "$__all"
          ]
        },
        "datasource": "Prometheus",
        "definition": "query_result({job=~\"$service\"})",
        "error": null,
        "hide": 0,
        "includeAll": true,
        "label": "Instance",
        "multi": true,
        "name": "instance",
        "options": [],
        "query": "query_result({job=~\"$service\"})",
        "refresh": 1,
        "regex": "/instance=\"(.*?)\".*/",
        "skipUrlSync": false,
        "sort": 0,
        "tagValuesQuery": "",
        "tags": [],
        "tagsQuery": "",
        "type": "query",
        "useTags": false
      },
      {
        "allValue": null,
        "current": {
          "selected": true,
          "text": [
            "All"
          ],
          "value": [
            "$__all"
          ]
        },
        "datasource": "Prometheus",
        "definition": "query_result({job=~\"$service\",instance=~\"$instance\"})",
        "error": null,
        "hide": 0,
        "includeAll": true,
        "label": "Command Group",
        "multi": true,
        "name": "commandGroup",
        "options": [],
        "query": "query_result({job=~\"$service\",instance=~\"$instance\"})",
        "refresh": 1,
        "regex": "/command_group=\"(.*?)\".*/",
        "skipUrlSync": false,
        "sort": 0,
        "tagValuesQuery": "",
        "tags": [],
        "tagsQuery": "",
        "type": "query",
        "useTags": false
      },
      {
        "allValue": null,
        "current": {
          "selected": false,
          "text": "All",
          "value": "$__all"
        },
        "datasource": "Prometheus",
        "definition": "query_result({job=~\"$service\",instance=~\"$instance\",command_group=~\"$commandGroup\"})",
        "error": null,
        "hide": 0,
        "includeAll": true,
        "label": "Command Name",
        "multi": true,
        "name": "commandName",
        "options": [],
        "query": "query_result({job=~\"$service\",instance=~\"$instance\",command_group=~\"$commandGroup\"})",
        "refresh": 1,
        "regex": "/command_name=\"(.*?)\".*/",
        "skipUrlSync": false,
        "sort": 0,
        "tagValuesQuery": "",
        "tags": [],
        "tagsQuery": "",
        "type": "query",
        "useTags": false
      },
      {
        "allValue": null,
        "current": {
          "selected": false,
          "text": "All",
          "value": "$__all"
        },
        "datasource": "Prometheus",
        "definition": "query_result({job=~\"$service\",instance=~\"$instance\"})",
        "error": null,
        "hide": 0,
        "includeAll": true,
        "label": "Pool_Name",
        "multi": true,
        "name": "pool_name",
        "options": [],
        "query": "query_result({job=~\"$service\",instance=~\"$instance\"})",
        "refresh": 1,
        "regex": "/pool_name=\"(.*?)\".*/",
        "skipUrlSync": false,
        "sort": 0,
        "tagValuesQuery": "",
        "tags": [],
        "tagsQuery": "",
        "type": "query",
        "useTags": false
      }
    ]
  },
  "time": {
    "from": "now-5m",
    "to": "now"
  },
  "timepicker": {
    "refresh_intervals": [
      "5s",
      "10s",
      "30s",
      "1m",
      "5m",
      "15m",
      "30m",
      "1h",
      "2h",
      "1d"
    ],
    "time_options": [
      "5m",
      "15m",
      "1h",
      "6h",
      "12h",
      "24h",
      "2d",
      "7d",
      "30d"
    ]
  },
  "timezone": "browser",
  "title": "Custom Hystrix Dashboard",
  "uid": "DqrjMNKik",
  "version": 19
}
Hystrix 监控面板json数据

四、使用Demo

1)代码方式

/**
 * @Author zhangboqing
 * @Date 2020/11/18
 * 命令方式
 */
@Slf4j
@Builder
public class TestHystrixCommand extends BaseHystrixCommand<String> {
 
    String value;
 
    public TestHystrixCommand(String value) {
        super(HystrixThreadPoolKeyEnum.DEFAULT_HYSTRIX_THREAD_POOL);
        this.value = value;
    }
 
    @Override
    protected String run() throws Exception {
        log.info("invoke");
        return value;
    }
 
    // 实现降级逻辑(发生超时或异常执行)
    @Override
    protected String getFallback() {
        return "getFallback";
    }
 
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 同步调用
        String execute = TestHystrixCommand.builder().value("212").build().execute();
        log.info("result:{}",execute);
 
        // 异步调用
        // 关注结果
        Future<String> future = TestHystrixCommand.builder().value("212").build().queue();
        log.info("result:{}",future.get());
 
        // 不关注结果
        TestHystrixCommand.builder().value("212").build().observe().subscribe();
    }
}
TestHystrixCommand

2)注解方式

/**
 * @Author zhangboqing
 * @Date 2020/11/18
 * 注解方式
 */
@Service
@Slf4j
public class TestHystrixAnnotation {
 
    /**
     * 同步
     */
    // 不设置超时
    @HystrixCommand(
            groupKey = HystrixProperties.ThreadPoolName.DEFAULT_THREADPOOLKEY,
            commandProperties = {
                    @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_TIMEOUT_ENABLED, value = HystrixProperties.DEFAULT_EXECUTIONTIMEOUTENABLED)
            },
            fallbackMethod = "runFallback"
    )
    public Object run() {
        int a = 1 / 0;
        log.info(">>>>>>> execute run");
        return "run";
    }
 
 
    // 设置超时
    @HystrixCommand(
            groupKey = HystrixProperties.ThreadPoolName.DEFAULT_THREADPOOLKEY,
            commandProperties = {
                    @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_TIMEOUT_IN_MILLISECONDS, value = HystrixProperties.DEFAULT_EXECUTIONTIMEOUTINMILLISECONDS)
            },
            fallbackMethod = "runFallback"
    )
    public Object run2() {
        log.info(">>>>>>> execute run");
        return "run";
    }
 
    public String runFallback() {
        return "runFallback";
    }
 
 
    @HystrixCommand(
            groupKey = HystrixProperties.ThreadPoolName.DEFAULT_THREADPOOLKEY,
            commandProperties = {
                    @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_TIMEOUT_ENABLED, value = HystrixProperties.DEFAULT_EXECUTIONTIMEOUTENABLED)
            }
    )
    public Object run3() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info(">>>>>>> execute run3");
        return "run";
    }
 
 
    /**
     * 异步
     */
    @HystrixCommand(
            groupKey = HystrixProperties.ThreadPoolName.DEFAULT_THREADPOOLKEY,
            commandProperties = {
                    @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_TIMEOUT_ENABLED, value = HystrixProperties.DEFAULT_EXECUTIONTIMEOUTENABLED)
            }
    )
    public Future<String> run4() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info(">>>>>>> execute run4");
        return new AsyncResult<String>() {
            @Override
            public String invoke() {
                return "run4";
            }
        };
    }
}
TestHystrixService

 

posted @ 2021-01-31 23:37  N!CE波  阅读(561)  评论(0编辑  收藏  举报