在微服务中由于细粒度的拆分,通常一个业务逻辑可能会有一条长长的服务调用链,一旦基础服务出现了故障就会引起“级联故障”,从而产生“雪崩效应”。通过集成hystrix熔断器,可以在服务调用发生故障时按照我们预定的方式进行回退以及延时,从而避免雪崩。


在服务中引入hystrix只需要在pom文件中引入对hystrix的依赖,并在启动类添加“@EnableHystrix”注解。

(一)ribbon中使用hytirx:在使用restTemplate进行服务调用的方法上使用“@HystrixCommand”注解,指明服务调用失败时执行的方法。

    @HystrixCommand(fallbackMethod = "getUserByUsernameFallback",commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000"), //服务调用超时时间
            @HystrixProperty(name = "execution.isolation.strategy ",value = "Thread") //HystrixCommand隔离级别:Thread表示重新开始一个线程执行回滚;Semaphore表示在当前调用线程执行回滚
    },threadPoolProperties = {
            @HystrixProperty(name = "coreSize",value = "1"),
            @HystrixProperty(name = "maxQueueSize",value = "10")
    })
    public User getUserByUsername(String username){
        return this.restTemplate.getForObject("http://cms-admin/user/" + username,User.class);
    }

    public User getUserByUsernameFallback(){
        User user = new User();
        user.setId("-1");
        return user;
    }

上述代码中指明了ribbon调用失败时执行的回退方法,并且设置了一些参数。其中需要注意的是hystrixCommand默认的线程隔离级别是”Thread”,表示重新开启一个线程执行回退,这种方式的线程产生方式使用了线程池技术,可以对线程池进行一些自定义的设置,如上述代码中的”threadPoolProperties”属性设置;“Semaphore”隔离级别表示在当前调用线程执行回退,代价较小,但受到请求信号量的影响。推荐使用”thread”隔离级别,但如果要在回退的方法中使用线程本地上下文,就只能使用信号量隔离级别了。

(二)Feign使用hystrix

@FeignClient(name = "cms-admin",configuration = FeignConfiguration.class,fallbackFactory = UserServiceHystric.class)
@RequestMapping("/user")
public interface UserService {

    @GetMapping(value = "/username/{username}")
    User getUserByUsername(@PathVariable("username") String username);

    @GetMapping(value = "/userinfo/{username}")
    ResponseResult getUserInfoByUsername(@PathVariable("username") String username);

}
----------
@Component
public class UserServiceHystric implements FallbackFactory<UserService>{

    private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceHystric.class);

    @Override
    public UserService create(Throwable throwable) {
        return new UserService() {
            @Override
            public User getUserByUsername(String username) {
                LOGGER.info("根据用户名获取用户失败:" + throwable);
                return null;
            }

            @Override
            public ResponseResult getUserInfoByUsername(String username) {
                LOGGER.info("根据用户名获取用户信息失败:" + throwable);
                return null;
            }
        };
    }
}

上述代码中通过fallbackFactory属性指明了feign调用失败时的回退,使用这种方式可以访问到调用失败的原因;也可以只定义一个集成feign接口的实现类,重写其中的方法完成回退,此时应该使用“fallback”属性指明回退类,但这种方式无法得知feign调用失败的原因。

(三)hystrix监控

hystrix的监控信息以”text/event-stream”的方式暴露给外部系统,因此我们可以很方便的看到这些信息。

  1. 使用ribbon调用的服务只需添加”actuator”依赖,访问”/hystrix”路径即可看到ribbon调用时的监控信息;
  2. 使用feign调用的服务中需要添加”hystrix”依赖,并在启动类设置”@@EnableCircuitBreaker”注解,然后即可通过”/hystrix.stream”访问监控信息;
  3. 可以另起一个项目,添加”hystrix-dashboard”依赖,在启动类上添加”@EnableHystrixDashboard”注解,然后即可在可视化的界面中查看指定调用链路的监控信息;

(四)Turbine聚合监控数据
            前面介绍的都是单服务的数据监控,实际意义并不大,我们可以使用turbine实现服务的聚合监控。通过turbine可以将单个服务的”hystrix.stream”聚合成为”turbine.stream”,并通过dashboard可视化即可查看聚合监控数据。
              这里写图片描述


 1. 新建dashboard项目;
 2. 新建turbine项目,引入turbine依赖,并在启动类配置"@EnableTurbine",并通过配置文件指明进行监控数据聚合的服
 务,配置如下:
    server:
    port: 9998
    spring:
      application:
        name: cms-monitor
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:11000/eureka/
      instance:
        prefer-ip-address: true
    turbine:
      app-config: cms-gateway,cms-admin
      cluster-name-expression: "'default'"
 3.依次启动,并进行服务调用,在dashboadr访问"turbine.stream",即可看到聚合的监控数据:

这里写图片描述
这里写图片描述
(四)通过消息中间件收集聚合信息

    为了防止turbine监控的微服务与turbine服务的网络不同等问题,我们可以将”hystrix.stream”信息发送至消息中间件,turbine从消息中间件中获取监控数据。

  • 安装rabbitMq;//自行百度
  • 改造微服务:
 - 将对hystrix的依赖修改为“hystrix-stream”+“stream-rabbit”的依赖;
 - 添加rabbitmq配置信息:
      spring:
          rabbitmq:
            host: localhost
            port: 5672
            username: guest
            password: guest

  • 改造turbine:
  •  - 删除turbine依赖,添加"turbine-stream""stream-rabbit"的依赖;
     - @EnableTurbine修改为@EnableTurbineStream;
     - 配置rabbitmq;
     - 删除turbine中配置的监控的服务信息

  • 依次启动,可以在rabbitmq和dashboard中查看持续的服务调用信息。
  • 这里写图片描述
    这里写图片描述

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐