zoukankan      html  css  js  c++  java
  • 基础篇——Spring Cloud Hystrix

    一、Hystrix使用之创建请求命令

      继承HystrixCommand:

    public class UserCommand extends HystrixCommand<User> {
    
        private RestTemplate restTemplate;
    
        private Long id;
    
        public UserCommand(Setter setter, RestTemplate restTemplate, Long id) {
            super(setter);
            this.restTemplate = restTemplate;
            this.id = id;
        }
    
        @Override
        protected User run() {
            return restTemplate.getForObject("http://USER-SERVICE/user?id={1}",     
            User.class, id);
        }
    }

      注:同步执行,User user = new UserCommand(restTemplate, 1L).execute();

        异步执行,Future<User> futureUser = new UserCommand(restTemplate, 1L).queue();

        Hot Observable,Observable<String> ho = new UserCommand(restTemplate, 1L).observe();

        Cold Observable,Observable<String> go = new UserCommand(restTemplate, 1L).toObservable();

      注解@HystrixCommand实现同步执行:

    public class UserService {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @HystrixCommand
        public User getUserById(Long id) {
            return restTemplate.getForObject("http://USER-SERVICE/user?id={1}", 
            User.class, id);
        }
    }

      注解@HystrixCommand实现异步执行:

    public class UserService {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @HystrixCommand
        public Future<User> getUserByIdAsync(final String id) {
            return new AsyncResult<User>() {
                @Override
                public User invoke() {
                    return restTemplate.getForObject("http://USER-SERVICE/user?id= 
                    {1}", User.class, id);
                }
            };
        }
    }

      继承HystrixObservableCommand:

    public class UserObservableCommand extends HystrixObservableCommand<User> {
    
        private RestTemplate restTemplate;
    
        private Long id;
    
        public UserObservableCommand(Setter setter, RestTemplate restTemplate, Long id) {
            super(setter);
            this.restTemplate = restTemplate;
            this.id = id;
        }
    
        @Override
        protected Observable<User> construct() {
            return Observable.create(new Observable.OnSubscribe<User>(){
                @Override
                public void call(Subscribe<? super User> observable) {
                    try {
                        if (!observable.isSubscribed()) {
                            User user = restTemplate.getForObject("http://USER-SERVICE/user?id={1}", User.class, id);
                            observable.onNext(user);
                            observable.onCompleted();
                        }
                    } catch (Exception e) {
                        observable.onError(e);
                    }
                }
            });
        }
    }

      注解@HystrixCommand实现响应式命令:

    public class UserService {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @HystrixCommand
        public Observable<User> getUserById(final String id) {
            return Observable.create(new Observable.OnSubscribe<User>() {
                @Override
                public void call(Subscribe<? super User> observable) {
                    try {
                        if (!observable.isSubscribe()) {
                            User user = restTemplate.getForObject("http://USER-SERVICE/user?id={1}", User.class, id);
                            observable.onNest(user);
                            observable.onCompleted();
                        }
                    } catch (Exception e) {
                        observable.onError(e);
                    }
                }
            });
        }
    }

    二、定义服务降级

      对于有返回值的服务,也就是说调用者需要请求服务获取到某些有用的信息,如果在HystrixCommand或HystrixObservableCommand执行出现错误、超时、线程池拒绝、断路器熔断等情况,需要进行服务降级处理来保障调用者的体验。对于继承HystrixCommand执行请求服务,需要重写getFallBack方法;

    public class UserCommand extends HystrixCommand<User> {
    
        @Override
        protected User getFallBack() {
            return new User();
        }
    }

      对于继承HystrixObservableCommand执行请求服务,需要重写resumeWithFallBack方法;

    public class UserObservableCommand extends HystrixObservableCommand<User> {
    
        @Override
        protected User resumeWithFallBack() {
            return new User();
        }
    }

      对于注解@HystrixCommand执行请求服务,需要使用属性fallBackMethod="方法名",且“方法名”必须在同一类中;

    public class UserService {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @HystrixCommand(fallBackMethod="defaultUserById")
        public Observable<User> getUserById(final String id) {
            return Observable.create(new Observable.OnSubscribe<User>() {
                @Override
                public void call(Subscribe<? super User> observable) {
                    try {
                        if (!observable.isSubscribe()) {
                            User user = restTemplate.getForObject("http://USER-SERVICE/user?id={1}", User.class, id);
                            observable.onNest(user);
                            observable.onCompleted();
                        }
                    } catch (Exception e) {
                        observable.onError(e);
                    }
                }
            });
        }
    
        protected User defaultUserById() {
            return new User();
        }
    }

      当然对于一些不需要服务返回必须有用信息的请求,可以选择不使用服务降级处理,可以直接将错误信息返回给调用者即可。例如:使用HystrixCommand请求写操作的服务,如果写入不成功,直接将错误返回给调用者,通知其稍后重试即可。

    三、异常处理

      Hystrix执行请求服务的异常有两种,HystrixBadRequestException和其他。因为服务降级策略的存在,除了由HystrixBadRequestException包装的异常外,其他的所有异常都会触发服务降级策略。注解@HystrixCommand通过属性ignoreExceptions实现指定异常向HystrixBadRequestException的包装,当服务请求出现指定异常时,不触发服务降级策略。

      当发生服务降级时,获取详细的异常服务,在继承类HystrixCommand或HystrixObserableCommand中,通过其父类方法getExecutionException获得;

        @Override
        protected User getFallBack() {
            Throwable e = getExecutionException();
            return new User();
        }

      注解@HystrixCommand属性fallBackMethod指定方法中接收参数Throwable e;

        protected User defaultUserById(Throwable e) {
            return new User();
        }

    四、命令名称、分组以及线程池划分

      分组、命令名称和线程池划分是Hystrix对服务请求的细粒化分配,即此次服务请求被分配到某组某个线程池的某个命令,能够更好的统计和分配,在继承方式中设置组名、命令名称和划分的线程池名称;

        public UserCommand(RestTemplate restTemplate, Long id) {
            super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("GroupName"))
                    .andCommandKey(HystrixCommandKey.Factory.asKey("CommandName"))
                    .andThreadPoolKey(HystrixCommandThreadPoolKey.Factory.asKey("ThreadPoolKey")));
            this.restTemplate = restTemplate;
            this.id = id;
        }

      注解@HystrixCommand通过属性groupKey、commandKey、threadPoolKey来设置服务请求的组、命令和线程池划分;

        @HystrixCommand(fallBackMethod="defaultUserById", groupKey="UserGroup", commandKey="getUserById", threadPoolKey="userThreadPool")
        public Observable<User> getUserById(final String id) {
            return Observable.create(new Observable.OnSubscribe<User>() {
                @Override
                public void call(Subscribe<? super User> observable) {
                    try {
                        if (!observable.isSubscribe()) {
                            User user = restTemplate.getForObject("http://USER-SERVICE/user?id={1}", User.class, id);
                            observable.onNest(user);
                            observable.onCompleted();
                        }
                    } catch (Exception e) {
                        observable.onError(e);
                    }
                }
            });
        }
  • 相关阅读:
    PostMan-NewMan运行参数
    shell脚本学习简单记录笔记
    android开发okhttp-4.9.1源码大致流程解读
    android开发获取键盘高度以及判断键盘是否显示(兼容分屏模式)
    Android开发The style on this component requires your app theme to be Theme.AppCompat (or a descendant)的解决方法
    Linux开发Ubuntu安装man手册
    Android开发源码解读四大组件源码解读简单梳理
    Android开发涉及到的AMS类和ActivityThread类源码解读
    Android开发为什么主线程可以一直运行而不会退出来
    前端CryptoJS加密、后端解密代码实现参考
  • 原文地址:https://www.cnblogs.com/zzb-yp/p/13471034.html
Copyright © 2011-2022 走看看