Hystrix注意项

@HystrixCommand修饰的方法为什么不能再private上?
代理机制的要求
Spring Cloud Netflix Hystrix 使用代理来实现对方法的拦截和熔断逻辑的添加。
对于基于代理的 AOP(Aspect - Oriented Programming)实现,代理需要能够访问被代理方法的元信息,包括方法签名等内容。
如果将@HystrixCommand标注在private方法上,代理无法访问private方法,因为private方法的访问权限仅限于类内部。
这就导致 Hystrix 无法为这样的private方法创建代理,从而不能正确地实现熔断、降级等功能。

动态代理的限制
Spring Cloud Hystrix 通常是基于动态代理(如 Java 的 JDK 动态代理或 CGLIB 动态代理)来实现的。
JDK 动态代理要求被代理的方法必须是定义在接口中的方法,并且通过接口来进行代理。
private方法不能在接口中定义,所以 JDK 动态代理无法对private方法进行操作。
即使是 CGLIB 动态代理,虽然它可以代理类而不是接口,但是它也需要能够访问方法的元信息来生成代理类。
private方法的访问限制使得 CGLIB 无法有效地对其进行代理,从而不能应用@HystrixCommand的相关功能。
 

 
@HystrixCommand 注解参数解释


 
/**
 * 此注解用于指定某些应作为Hystrix命令进行处理的方法。
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface HystrixCommand {

    /**
     * 命令组键(group key)用于将多个命令分组,例如用于报告、告警、仪表盘展示或者区分团队/库的所属关系等用途。
     * <p/>
     * 默认值 => 被注解方法的运行时类名。
     */
    String groupKey() default "";

    /**
     * Hystrix命令键(command key)。
     * <p/>
     * 默认值 => 被注解方法的名称。例如:
     * <code>
     *    ...
     *     @HystrixCommand
     *     public User getUserById(...)
     *    ...
     *     命令名称将会是:'getUserById'
     * </code>
     *
     * @return 命令键(command key)
     */
    String commandKey() default "";

    /**
     * 线程池键(thread-pool key)用于表示一个HystrixThreadPool,以便进行监控、指标发布、缓存以及其他类似用途。
     */
    String threadPoolKey() default "";

    /**
     * 指定用于处理回退(fallback)逻辑的方法。
     * 回退方法应定义在使用了HystrixCommand注解的同一个类中。
     * 并且回退方法的签名应与作为Hystrix命令调用的方法签名相同。
     * 例如:
     * <code>
     *      @HystrixCommand(fallbackMethod = "getByIdFallback")
     *      public String getById(String id) {...}
     *
     *      private String getByIdFallback(String id) {...}
     * </code>
     */
    String fallbackMethod() default "";

    /**
     * 指定命令属性。
     */
    HystrixProperty[] commandProperties() default {};

    /**
     * 指定线程池属性。
     */
    HystrixProperty[] threadPoolProperties() default {};

    /**
     * 定义应该被忽略的异常。
     * 如果 raiseHystrixExceptions 包含 RUNTIME_EXCEPTION,这些异常可以选择性地被包装在HystrixRuntimeException中。
     */
    Class<? extends Throwable>[] ignoreExceptions() default {};

    /**
     * 指定用于执行Hystrix可观察命令(observable command)的模式。
     * 更多信息请参见 {@link ObservableExecutionMode}。
     */
    ObservableExecutionMode observableExecutionMode() default ObservableExecutionMode.EAGER;

    /**
     * 当包含 RUNTIME_EXCEPTION时,任何未被忽略的异常都会被包装在HystrixRuntimeException中。
     */
    HystrixException[] raiseHystrixExceptions() default {};

    /**
     * 为命令指定默认的回退方法。如果同时指定了 {@link #fallbackMethod} 和 {@link #defaultFallback} 方法,
     * 则会使用特定的那个方法。
     * 注意:默认回退方法不能有参数,其返回类型应与命令的返回类型兼容。
     */
    String defaultFallback() default "";
}
 
groupKey
  • 用途:用于将多个相关的HystrixCommand分组。这有助于在监控和管理熔断策略时进行分类。例如,将所有与用户服务相关的命令归为一组,所有与订单服务相关的命令归为另一组
    @HystrixCommand(groupKey = "userService")
    public User getUserById(Long id) {
        // 调用远程服务获取用户信息
        return userServiceClient.getUserById(id);
    }
    

    commandKey

  • 用途:唯一标识一个HystrixCommand。如果不指定,默认是被注解的方法名【会是这个getUserById】。它在 Hystrix 的监控和配置中用于区分不同的命令,特别是当你需要为特定的命令进行单独的配置时很有用

    • @HystrixCommand(commandKey = "getUserByIdCommand", groupKey = "userService")
      public User getUserById(Long id) {
          // 调用远程服务获取用户信息
          return userServiceClient.getUserById(id);
      }
      

       

      threadPoolKey
用途:指定用于执行此命令的线程池的键。通过指定不同的线程池,可以隔离不同类型的命令,防止一个命令的故障影响到其他命令。例如,将高优先级的命令放在一个线程池,低优先级的命令放在另一个线程池。
@HystrixCommand(threadPoolKey = "highPriorityThreadPool", groupKey = "userService")
public User getUserById(Long id) {
    // 调用远程服务获取用户信息
    return userServiceClient.getUserById(id);
}

fallbackMethod

  • 用途:当原始方法执行出现故障(如超时、异常等)时,指定调用的备用方法。这个备用方法应该具有与原始方法相同的参数列表和返回类型(或者是兼容的返回类型)。
@HystrixCommand(fallbackMethod = "getUserByIdFallback", groupKey = "userService")
public User getUserById(Long id) {
    // 调用远程服务获取用户信息
    return userServiceClient.getUserById(id);
}
public User getUserByIdFallback(Long id) {
    // 返回一个默认用户或者空用户对象
    return new User();
}

 

commandProperties

  • 用途:用于配置HystrixCommand的各种属性。这些属性包括但不限于超时时间、熔断器开启和关闭的条件等。每个属性通过HystrixProperty对象进行配置。
    @HystrixCommand(commandProperties = {
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
    }, groupKey = "userService")
    public User getUserById(Long id) {
        // 调用远程服务获取用户信息
        return userServiceClient.getUserById(id);
    }
    
      • 在这个例子中,配置了命令的超时时间为 2000 毫秒。如果方法调用超过这个时间,就会触发熔断机制并调用备用方法(如果有)。


    threadPoolProperties

    • 用途:用于配置HystrixCommand所使用的线程池的属性,如线程池大小、队列大小等。这有助于优化线程池的性能和资源利用。
      @HystrixCommand(threadPoolProperties = {
          @HystrixProperty(name = "coreSize", value = "10"),
          @HystrixProperty(name = "maxQueueSize", value = "100")
      }, groupKey = "userService")
      public User getUserById(Long id) {
          // 调用远程服务获取用户信息
          return userServiceClient.getUserById(id);
      }
      

      ignoreExceptions

      • 用途:指定哪些异常在执行命令时应该被忽略,不会触发熔断机制。这在你希望区分对待不同类型的异常时很有用,例如,对于一些可预期的业务异常,你可能不希望触发熔断。
      @HystrixCommand(ignoreExceptions = {BusinessException.class}, groupKey = "userService")
      public User getUserById(Long id) {
          try {
              // 调用远程服务获取用户信息
              return userServiceClient.getUserById(id);
          } catch (BusinessException e) {
              // 业务异常,不触发熔断,直接抛出
              throw e;
          } catch (Exception e) {
              // 其他异常可能触发熔断
              //...
          }
      }
      

       observableExecutionMode

      • 用途:用于控制HystrixCommand返回的Observable的执行模式。Observable是 RxJava 中的概念,用于处理异步和事件流。EAGER模式表示立即执行ObservableLAZY模式表示延迟执行,直到有订阅者订阅。
        @HystrixCommand(observableExecutionMode = ObservableExecutionMode.LAZY, groupKey = "userService")
        public Observable<User> getUserByIdObservable(Long id) {
            // 返回一个Observable对象,可能是通过RxJava操作符构建的
            return Observable.just(userServiceClient.getUserById(id));
        }
        

         

        raiseHystrixExceptions
        • 用途:用于指定在执行命令过程中应该抛出的HystrixException类型。这可以帮助你更精细地控制异常的抛出和处理,特别是在结合fallbackMethod使用时。
          @HystrixCommand(raiseHystrixExceptions = {HystrixRuntimeException.class}, groupKey = "userService")
          public User getUserById(Long id) {
              try {
                  // 调用远程服务获取用户信息
                  return userServiceClient.getUserById(id);
              } catch (HystrixRuntimeException e) {
                  // 抛出指定类型的Hystrix异常,可能会触发特定的处理逻辑
                  throw e;
              } catch (Exception e) {
                  //...
              }
          }
          
          1. defaultFallback

            • 用途:提供一个全局的备用方法。如果没有为@HystrixCommand指定fallbackMethod,并且配置了defaultFallback,那么在命令执行失败时就会调用这个全局备用方法。
              @HystrixCommand(defaultFallback = "globalFallback", groupKey = "userService") public User getUserById(Long id) { // 调用远程服务获取用户信息 return userServiceClient.getUserById(id); } public User globalFallback() { // 返回一个默认用户或者空用户对象 return new User(); }




posted @ 2025-01-06 22:18  余生请多指教ANT  阅读(30)  评论(0)    收藏  举报