【SpringCloud学习笔记】Hystrix

Hystrix

  • 搭建项目
  • 服务降级
  • 服务熔断
  • 请求合并
  • 如何和Feign一起使用

搭建项目

【SpringCloud学习笔记】Hystrix_第1张图片

–|eureka-registry --注册中心
–|hystrix-service – 调用用户服务
–|user-service --用户服务

  • hystrix-service
server:
  port: 9002
spring:
  application:
    name: hystrix-service

eureka:
  instance:
    hostname: 127.0.0.1
  client:
    register-with-eureka: true #默认值是true,是否将自己注册到注册中心
    fetch-registry: true #默认值是true,是否从注册中心拉取服务
    service-url: #注册中信对外暴露的注册中心地址
      defaultZone: http://localhost:8761/eureka/
feign:
  hystrix:
    enabled: true #在Feign中开启Hystrix
  • user-service
server:
  port: 9001
spring:
  application:
    name: user-service
  datasource: # 数据源
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    username: root
    password: root

eureka:
  instance:
    hostname: 127.0.0.1
  client:
    register-with-eureka: true #默认值是true,是否将自己注册到注册中心
    fetch-registry: false # 默认值是true,是否从注册中心拉取服务
    service-url: #注册中信对外暴露的注册中心地址
      defaultZone: http://localhost:8761/eureka/

服务降级

  • 在 pom.xml 文件中引入hystrix的起步依赖
<dependency>
     <groupId>org.springframework.cloudgroupId>
     <artifactId>spring-cloud-starter-netflix-hystrixartifactId>
dependency>
  • 在应用的启动类上使用@EnableCircuitBreaker开启hystrix的功能
@SpringBootApplication
@EnableCircuitBreaker
@MapperScan("user.service.provider.mapper")
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}
  • 使用注解 @HystrixCommand 标记调用失败时需要熔断的方法,fallbackMethod 属性指定降级方法,注意:指定的降级方法需要和降级方法相同入参
@RestController
@RequestMapping(value = "/user")
public class UserController {

    @Autowired
    private UserMapper userMapper;
    
    /*
     * 查询所有用户信息
     * 当该方法出现异常等信息,会返回兜底数据,
     * 不会直接将错误信息返回,导致服务不可用
     */
    @GetMapping(value = "/selectUserInfo")
    @HystrixCommand(fallbackMethod = "fallbackMethod")
    public List<UserInfo> selectUserInfo() {
        //int i = 1/0;
        return userMapper.selectAll();
    }

    /**
     * 兜底数据
     */
    public List<UserInfo> fallbackMethod(){
        List<UserInfo> list = new ArrayList<>();
        UserInfo userInfo = new UserInfo();
        userInfo.setName("兜底数据");
        userInfo.setAge(20);
        userInfo.setAddress("兜底数据");
        list.add(userInfo);
        return list;
    }
 }

服务熔断

  • 服务熔断就是,当在单位时间内触发了超过N次服务降级,并且服务降级占比超过阈值之后,就会触发服务熔断。当服务过来的时候,直接拒绝尝试服务调用,直接让服务降级处理。之后再慢慢尝试恢复。就相当于家里面的电路熔断器,当电流超负荷时,熔断器就会起作用烧断保险丝,将电停掉,导致全家断点
    @HystrixCommand(fallbackMethod = "hystrixMethod",commandProperties = {
            //是否开启断路器
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
            //请求次数,默认20次
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "2"),
            //时间窗口期,默认5s
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000"),
            //失败率达到多少后跳闸,默认50%
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),
    })
    @GetMapping(value = "/selectUserInfoByName")
    public UserInfo selectUserInfoByName(@RequestParam("name") String name){
        UserInfo userInfo = userMapper.selectUserInfoByName(name);
        if (null == userInfo){
            throw new RuntimeException("用户信息为空");
        }
        return userInfo;
    }
    
    /**
     * 兜底数据
     */
    public UserInfo hystrixMethod(String name){
        UserInfo userInfo = new UserInfo();
        userInfo.setName(name + "托底用户");
        userInfo.setAge(20);
        userInfo.setAddress("杭州市");
        return userInfo;
    }

请求合并

  • 请求合并:是将在指定的时间内的请求或者是指定时间内请求达到设置值,将多次请求合并为一次请求
    @HystrixCollapser(
            batchMethod = "selectUserByListId",
            scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,
            collapserProperties = {
                    //隔离多久会进行请求合并,默认10ms
                    @HystrixProperty(name = "timerDelayInMilliseconds", value = "5000"),
                    //最大请求条数
                    @HystrixProperty(name = "maxRequestsInBatch", value = "2")
            })
    @GetMapping(value = "/selectUserInfoById")
    public UserInfo selectUserInfoById(@RequestParam("id") Integer id) {
        return userMapper.selectUserInfoById(id);
    }

    /**
     * 处理合并后的请求方法
     */
    @HystrixCommand
    public List<UserInfo> selectUserByListId(List<Integer> ids) {
        System.out.println("请求合并入参:" + ids);
        ArrayList<UserInfo> list = new ArrayList<>();
        for (Integer id : ids) {
            UserInfo userInfo = userMapper.selectUserInfoById(id);
            list.add(userInfo);
        }
        System.out.println("请求合并处理结果:" + list);
        return list;
    }

【SpringCloud学习笔记】Hystrix_第2张图片

如何和Feign一起使用

  • 上面的例子中,都是在服务端做的,消费者是通过feign远程调用,那如何实现,首先需要在配置文件中开启,hystrix-service模块的配置文件
feign:
  hystrix:
    enabled: true #在Feign中开启Hystrix
  • Feign的远程调用接口,就是调用user-service服务
@FeignClient(name = "user-service", fallback = UserFallBackService.class)
public interface UserServiceApi {

    @GetMapping(value = "user/selectUserInfo")
    List<UserInfo> selectUserInfo();

    @GetMapping(value = "user/selectUserInfoByName")
    UserInfo selectUserInfoByName(@RequestParam("name") String name);

    @GetMapping(value = "user/selectUserInfoById")
    UserInfo selectUserInfoById(@RequestParam("id") Integer id);
}
  • 针对Feign接口,需要写一个实现类,上面feignClient注解中的fallback对应的就是该实现类
@Component
public class UserFallBackService implements UserServiceApi{

    @Override
    public List<UserInfo> selectUserInfo() {
        ArrayList<UserInfo> userInfos = new ArrayList<>();
        UserInfo userInfo = new UserInfo();
        userInfo.setName("托底用户");
        userInfo.setAge(20);
        userInfo.setAddress("杭州市");
        userInfos.add(userInfo);
        return userInfos;
    }

    @Override
    public UserInfo selectUserInfoByName(String name) {
        UserInfo userInfo = new UserInfo();
        userInfo.setName(name + "托底用户");
        userInfo.setAge(20);
        userInfo.setAddress("杭州市");
        return userInfo;
    }

    @Override
    public UserInfo selectUserInfoById(Integer id) {
        UserInfo userInfo = new UserInfo();
        userInfo.setName("托底用户");
        userInfo.setAge(20);
        userInfo.setAddress("杭州市");
        return userInfo;
    }

【SpringCloud学习笔记】Hystrix_第3张图片

你可能感兴趣的:(spring,cloud)