Spring Could Hystrix 使用详细

目录

介绍

注: pom.xml和application.properties键“服务容错保护:Spring Could Hystrix”

1 请求命令的创建

1.1 未使用@HystrixCommand注解形式

Hystrix创建通过继承HystrixCommand类来实现。getFallback()方法定义降级错误返回。

public class UserCommand extends HystrixCommand<User> {
    @Autowired
    private RestTemplate restTemplate;

    public UserCommand() {
        super(HystrixCommandGroupKey.Factory.asKey("UserCommand"));
    }

    @Override
    protected User run() throws Exception {
        System.out.println("");
        return  restTemplate.getForObject("http://hello-service/user/login",User.class);
    }

    @Override
    protected User getFallback() {
        System.out.println("==================================");
        System.out.println(getFailedExecutionException().getMessage());
        return new User("def","def");
    }
}

测试:

1 同步执行:User u = new UserCommand().execute()
2 异步执行:Future<User> fWorld = new UserCommand().queue();
3 通过:Observable实现响应   
Observable<User> observe = new UserCommand().observe();
Observable<User> userObservable = new UserCommand().toObservable();

1.2 使用@HystrixCommand注解

@Service("userService")
public class UserService {
    /**获取logger实例*/
    private final Logger logger = Logger.getLogger(getClass().toString());

    @Autowired
    private RestTemplate restTemplate;

    /**
     *同步调用
     * @return
     */
    @HystrixCommand(fallbackMethod = "notFindFallback1")
    public String login()
    {
        logger.info("调用:http://hello-service/user/login");
       // ResponseEntity<String> forEntity = restTemplate.getForEntity("http://hello-service/user/login", String.class);
        String forObject = restTemplate.getForObject("http://hello-service/user/login", String.class);
        return "我是一个消费者去调用==》"+forObject;
    }


    /**
     *异步调用
     * @return
     */
    @HystrixCommand(fallbackMethod = "notFindFallback")
    public Future<String> loginAsync()
    {
        return new AsyncResult<String>() {
            @Override
            public String invoke() {
                String forObject = restTemplate.getForObject("http://hello-service/user/login", String.class);
                return "我是一个消费者去调用==》"+forObject;
            }
        };
    }

    /**
     * 异常触发方法
     * @return
     */
    public String notFindFallback()
    {
        return "error";
    }

    /**
     * 异常捕获方法,可捕获异常
     * @return
     */
    public String notFindFallback1(Throwable e)
    {
        return e.getMessage();
    }
}

@HystrixCommand注解属性

1 fallbackMethod指定异常降级方法
2 observableExecutionMode = ObservableExecutionMode.EAGER表示.observe()执行方式observableExecutionMode = ObservableExecutionMode.LAYZ表示.toObservable();
3 ignoreExceptions 指定某类异常触发时,不走fallbackMethod降级方法
4 commandKey 指定命名名,groupKey指定组名,threadPoolKey指定线程。用于划分Hystrix分组,默认同组名化一个线程池组。所以需要指定线程划分。(setter设置)

注:一些情况不需要做降级处理。如写操作,批处理或者离线计算。(操作的返回一般为void

2 请求缓存

Hystrix提供请求缓存,减轻高并发情况下服务的压力。

2.1 通过重写getCache()方法

继承HystrixCommand类,重写getCacheKey()方法。getCache()方法返回缓存key值。
清理缓存使用HystrixRequestCache.clear()。(getCacheKey()默认返回null,缓存未开启)

2.2 使用缓存注解(必须配合@HystrixCommand使用)

@CacheResult标记结果加入缓存
@CacheRemove请求缓存失效
@CacheKey标记缓存的key

2.2.1 使用@CacheResult实现缓存功能

@CacheResult(cacheKeyMethod = "getCacheKey")
@HystrixCommand(commandKey = "findUserById", groupKey = "UserService", threadPoolKey = "userServiceThreadPool")
public UserVO findById(Long id) {
    ResponseEntity<UserVO> user = restTemplate.getForEntity("http://users-service/user?id={id}", UserVO.class, id);
    return user.getBody();
}

public String getCacheKey(Long id) {
    return String.valueOf(id);
}

2.2.2 使用@CacheResult和@CacheKey实现缓存功能

@CacheResult
@HystrixCommand(commandKey = "findUserById", groupKey = "UserService", threadPoolKey = "userServiceThreadPool")
public UserVO findById2(@CacheKey("id") Long id) {
    ResponseEntity<UserVO> user = restTemplate.getForEntity("http://users-service/user?id={id}", UserVO.class, id);
    return user.getBody();
}

2.2.3 使用@CacheRemove清空缓存

@CacheRemove(commandKey = "findUserById")
@HystrixCommand(commandKey = "updateUser",groupKey = "UserService",threadPoolKey = "userServiceThreadPool")
public void updateUser(@CacheKey("id")UserVO user){
    restTemplate.postForObject("http://users-service/user",user,UserVO.class);
}

请求合并

2 总结

参考:

1 《Spring Could 微服务实战》 翟永超 电子工业出版社 2017.5

参考网站:http://blog.didispace.com/Spring-Cloud基础教程/
        https://springcloud.cc
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章