博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hystrix命令入门使用
阅读量:5947 次
发布时间:2019-06-19

本文共 7258 字,大约阅读时间需要 24 分钟。

主要介绍Hystrix各接口和注解的使用方法。

创建请求命令

Hystrix命令就是我们之前所说的HystrixCommand,他用来封装具体的依赖服务调用逻辑。

继承方式实现HystrixCommand

首先通过代码实现HystrixCommand

package cn.sh.ribbon.command;import cn.sh.common.entity.User;import com.netflix.hystrix.HystrixCommand;import org.springframework.web.client.RestTemplate;/** * @author sh */public class UserCommand extends HystrixCommand
{ 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() throws Exception { return restTemplate.getForObject("http://USER-SERVICE/users/{1}", User.class, id); }}

通过上面实现的UserCommand,我们即可以实现请求的同步执行也可以实现异步执行,相关代码如下:

package cn.sh.ribbon.service;import cn.sh.common.entity.User;import cn.sh.ribbon.command.UserCommand;import com.netflix.hystrix.HystrixCommandGroupKey;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.web.client.RestTemplate;import java.util.concurrent.ExecutionException;import java.util.concurrent.Future;/** * @author sh */@Servicepublic class HelloService {    private static final Logger logger = LoggerFactory.getLogger(HelloService.class);    @Autowired    private RestTemplate restTemplate;    /**     * 第一种使用命令的方式     * @param id     * @return     */    public User getUserById(Long id) {        HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey("userKey");        com.netflix.hystrix.HystrixCommand.Setter setter = com.netflix.hystrix.HystrixCommand.Setter.withGroupKey(groupKey);        UserCommand userCommand = new UserCommand(setter, restTemplate, id);        // 同步执行获取结果//        return userCommand.execute();        // 异步执行获取结果        Future
future = userCommand.queue(); try { return future.get(); } catch (Exception e) { logger.info("获取结果发生异常", e); } return null; }}

注解方式使用HystrixCommand

通过HystrixCommand注解可以更优雅的实现Hystrix命令的定义,如下:

package cn.sh.ribbon.service;import cn.sh.common.entity.User;import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.web.client.RestTemplate;/** * @author sh */@Servicepublic class HelloService {    private static final Logger logger = LoggerFactory.getLogger(HelloService.class);    @Autowired    private RestTemplate restTemplate;    /**     * 通过注解方式获取User     * @param id     * @return     */    @HystrixCommand    public User findUserById(Long id) {        return restTemplate.getForObject("http://USER-SERVICE/users/{1}", User.class, id);    }}

上述代码虽然可以优雅的实现Hystrix命令,但是上述获取User的方式只是同步执行的实现,如果需要实现异步执行则需要进行如下改造:

package cn.sh.ribbon.service;import cn.sh.common.entity.User;import cn.sh.ribbon.command.UserCommand;import com.netflix.hystrix.HystrixCommandGroupKey;import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import com.netflix.hystrix.contrib.javanica.command.AsyncResult;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.web.client.RestTemplate;import rx.Observable;import rx.Subscription;import rx.functions.Action1;import java.util.concurrent.Future;/** * @author sh */@Servicepublic class HelloService {    private static final Logger logger = LoggerFactory.getLogger(HelloService.class);    @Autowired    private RestTemplate restTemplate;        /**     * 通过注解方式异步执行获取User     * @param id     * @return     */    @HystrixCommand    public Future
asyncFindUserFutureById(Long id) { return new AsyncResult
() { @Override public User invoke() { return restTemplate.getForObject("http://USER-SERVICE/users/{1}", User.class, id); } }; }}

响应执行

除了传统的同步执行与异步执行之外,我们还可以将HystrixCommand通过Observable来实现响应式执行方式。通过调用observe()和toObservable()可以返回Observable对象, 如下:

Observable
observe = userCommand.observe();Observable
observe = userCommand.toObservable();

前者返回的是一个Hot Observable,该命令会在observe调用的时候立即执行,当Observable每次被订阅的时候都会重放它的行为。

后者返回的是一个Cold Observable,toObservable()执行之后,命令不会被立即执行,只有当所有订阅者都订阅他之后才会执行。

HystrixCommand具备了observe()和toObservable()的功能,但是它的实现有一定的局限性,它返回的Observable只能发射一次数据,所以Hystrix提供了另外的一个特殊命令封装HysrtixObservableCommand,通过命令可以发射多次的Observable

响应执行自定义命令

相关代码如下:

package cn.sh.ribbon.command;import cn.sh.common.entity.User;import com.netflix.hystrix.HystrixObservableCommand;import org.springframework.web.client.RestTemplate;import rx.Observable;/** * @author sh */public class UserObservableCommand extends HystrixObservableCommand
{ 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
construct() { return Observable.create(subscriber -> { if (!subscriber.isUnsubscribed()) { User user = restTemplate.getForObject("http://USER-SERVICE/users/{1}", User.class, id); subscriber.onNext(user); subscriber.onCompleted(); } }); }}

响应执行使用注解@HystrixCommand

相关代码如下:

package cn.sh.ribbon.service;import cn.sh.common.entity.User;import cn.sh.ribbon.command.UserCommand;import cn.sh.ribbon.command.UserObservableCommand;import com.netflix.hystrix.HystrixCommandGroupKey;import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import com.netflix.hystrix.contrib.javanica.command.AsyncResult;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.web.client.RestTemplate;import rx.Observable;import rx.Observer;import rx.Subscriber;import rx.Subscription;/** * @author sh */@Servicepublic class HelloService {    private static final Logger logger = LoggerFactory.getLogger(HelloService.class);    @Autowired    private RestTemplate restTemplate;    /**     * 使用注解实现响应式命令     * @param id     * @return     */    @HystrixCommand    public Observable
observableGetUserId(Long id) { return Observable.create(subscriber -> { if (!subscriber.isUnsubscribed()) { User user = restTemplate.getForObject("http://USER-SERVICE/users/{1}", User.class, id); subscriber.onNext(user); subscriber.onCompleted(); } }); }}

使用@HystrixCommand注解实现响应式命令,可以通过observableExecutionMode参数来控制是使用observe()还是toObservable()的执行方式。该参数有下面两种设置方式:

  1. @HystrixCommand(observableExecutionMode = ObservableExecutionMode.EAGER): EAGER是该参数的模式值,表示使用observe()执行方式。
  2. @HystrixCommand(observableExecutionMode = ObservableExecutionMode.LAZY): 表示使用toObservable()执行方式。

代码地址

转载地址:http://qqbxx.baihongyu.com/

你可能感兴趣的文章
hdu1231-最大连续子序列
查看>>
TMG阵列部署选择
查看>>
Repeater 控件 当数据源没有数据的时候显示 暂无数据 的两种方式
查看>>
大型网站的架构设计图分享-转
查看>>
9.15游戏化体验的原则初探
查看>>
(function(){...}())与(function(){...})()
查看>>
css实现气泡框效果
查看>>
【原创】已知四个坐标点求其两条直线交点坐标
查看>>
request 路径随笔
查看>>
.NET基础之自定义泛型
查看>>
HTML5 Canvas 实现的9个 Loading 效果
查看>>
java.lang.NoClassDefFoundError: org/apache/avro/ipc/Responder
查看>>
利用JasperReport+iReport进行Web报表开发
查看>>
JSON and Microsoft Technologies(翻译)
查看>>
ylbtech-LanguageSamples-ConditionalMethods(条件方法)
查看>>
js 判断各种数据类型
查看>>
【leetcode】Find Peak Element ☆
查看>>
linux:sed高级命令之n、N(转)
查看>>
触发器更新多条数据
查看>>
微信公众平台原创声明功能公测 自媒体原创保护的福音
查看>>