HystrixRPC保护的原理,HystrixCommand命令的执行方法

前面讲到,独立使用HystrixCommand命令主要有以下两个步骤:

(1)继承HystrixCommand类,将正常的业务逻辑实现在继承的run方法中,将回退的业务逻辑实现在继承的getFallback方法中。

(2)使用HystrixCommand类提供的执行启动方法启动命令的执行。

HystrixCommand提供了4个执行启动的方法:execute()、queue()、observe()和toObservable()。

execute()方法

============

HystrixCommand的execute()方法以同步堵塞方式执行run()。一旦开始执行该命令,当前线程就会阻塞,直到该命令返回结果,然后才能继续执行下面的逻辑。

HystrixCommand的execute()方法的使用示例如下:

package com.crazymaker.demo.hystrix;

@Slf4j

public class HystryxCommandExcecuteDemo

{

public static final int COUNT = 5;

/**

*测试同步执行

*/

@Test

public void testExecute() throws Exception

{

/**

*使用统一配置类

*/

HystrixCommand.Setter setter = SetterDemo.buildSetter(

“group-1”,

“testCommand”,

“testThreadPool”);

/**

*循环 5 次

*/

for (int i = 0; i < COUNT; i++)

{

String result =

new HttpGetterCommand(HELLO_TEST_URL, setter).execute();

log.info(“result={}”, result);

}

Thread.sleep(Integer.MAX_VALUE);

}

}

运行测试用例前需要启动demo-provider实例,确保其REST接口/api/demo/hello/v1可以正常访问。执行上面的程序,输出的主要结果如下:

08:20:05.488 [hystrix-testThreadPool-1] INFO c.c.d.h.HttpGetterCommand - 第1次请求-> begin…

08:20:08.698 [hystrix-testThreadPool-1] INFO c.c.d.h.HttpGetterCommand - 第1次请求-> end!

08:20:08.708 [main] INFO c.c.d.h.CommandTester - 第1次请求的结果:{“status”:200,“msg”:“操作成功”,“data”:{“hello”:“world”}}

08:20:08.710 [hystrix-testThreadPool-2] INFO c.c.d.h.HttpGetterCommand - 第2次请求-> begin…

08:20:10.741 [hystrix-testThreadPool-2] INFO c.c.d.h.HttpGetterCommand - 第2次请求-> end!

08:20:10.744 [main] INFO c.c.d.h.CommandTester - 第2次请求的结果:{“status”:200,“msg”:“操作成功”,“data”:{“hello”:“world”}}

08:20:10.751 [hystrix-testThreadPool-3] INFO c.c.d.h.HttpGetterCommand - 第3次请求-> begin…

08:20:12.766 [hystrix-testThreadPool-3] INFO c.c.d.h.HttpGetterCommand - 第3次请求-> end!

08:20:12.767 [main] INFO c.c.d.h.CommandTester - 第3次请求的结果:{“status”:200,“msg”:“操作成功”,“data”:{“hello”:“world”}}

//省略后面的重复请求输出

从结果中可以看出,Hystrix会从线程池中取一个线程来执行HttpGetterCommand命令的run()方法,命令执行过程中,main线程一直在等待其返回值。

queue()方法

=========

HystrixCommand的queue()方法以异步非阻塞方式执行run()方法,该方法直接返回一个Future对象。可通过Future.get()拿到run()的返回结果,但Future.get()是阻塞执行的。

HystrixCommand的queue()方法的使用示例程序如下:

package com.crazymaker.demo.hystrix;

@Slf4j

public class HystryxCommandExcecuteDemo

{

@Test

public void testQueue() throws Exception {

/**

*使用统一配置

*/

HystrixCommand.Setter setter = getSetter(

“group-1”,

“testCommand”,

“testThreadPool”);

List<Future> flist = new LinkedList<>();

/**

*同时发起5个异步的请求

*/

for (int i = 0; i < COUNT; i++) {

Future future = new HttpGetterCommand(TEST_URL, setter).queue();

flist.add(future);

}

/**

*统一获取异步请求的结果

*/

Iterator<Future> it = flist.iterator();

int count = 1;

while (it.hasNext()) {

Future future = it.next();

String result = future.get(10, TimeUnit.SECONDS);

log.info(“第{}次请求的结果:{}”, count++, result);

}

Thread.sleep(Integer.MAX_VALUE);

}

}

运行这个示例程序前需要启动demo-provider实例,确保它的REST接口/api/demo/hello/v1可以正常访问。执行这个示例程序,主要的输出结果如下:

08:30:54.618 [hystrix-testThreadPool-2] INFO c.c.d.h.HttpGetterCommand - 第3次请求-> begin…

08:30:54.618 [hystrix-testThreadPool-1] INFO c.c.d.h.HttpGetterCommand - 第4次请求-> begin…

08:30:54.618 [hystrix-testThreadPool-4] INFO c.c.d.h.HttpGetterCommand - 第5次请求-> begin…

08:30:54.618 [hystrix-testThreadPool-3] INFO c.c.d.h.HttpGetterCommand - 第2次请求-> begin…

08:30:54.618 [hystrix-testThreadPool-5] INFO c.c.d.h.HttpGetterCommand - 第1次请求-> begin…

08:30:58.358 [hystrix-testThreadPool-2] INFO c.c.d.h.HttpGetterCommand - 第3次请求-> end!

08:30:58.358 [hystrix-testThreadPool-3] INFO c.c.d.h.HttpGetterCommand - 第2次请求-> end!

08:30:58.358 [hystrix-testThreadPool-1] INFO c.c.d.h.HttpGetterCommand - 第4次请求-> end!

08:30:58.358 [hystrix-testThreadPool-4] INFO c.c.d.h.HttpGetterCommand - 第5次请求-> end!

08:30:58.358 [hystrix-testThreadPool-5] INFO c.c.d.h.HttpGetterCommand - 第1次请求-> end!

08:30:58.364 [main] INFO c.c.d.h.CommandTester - 第1次请求的结果:{“status”:200,“msg”:“操作成功”,“data”:{“hello”:“world”}}

08:30:58.365 [main] INFO c.c.d.h.CommandTester - 第2次请求的结果:{“status”:200,“msg”:“操作成功”,“data”:{“hello”:“world”}}

08:30:58.365 [main] INFO c.c.d.h.CommandTester - 第3次请求的结果:{“status”:200,“msg”:“操作成功”,“data”:{“hello”:“world”}}

08:30:58.365 [main] INFO c.c.d.h.CommandTester - 第4次请求的结果:{“status”:200,“msg”:“操作成功”,“data”:{“hello”:“world”}}

08:30:58.365 [main] INFO c.c.d.h.CommandTester - 第5次请求的结果:{“status”:200,“msg”:“操作成功”,“data”:{“hello”:“world”}}

实际上,前面介绍的HystrixCommand的execute()方法是在内部使用queue().get()的方式完成同步调用的。

observe()方法

===========

HystrixCommand的observe()方法会返回一个响应式编程Observable主题,可以为该主题对象注册上Subscriber观察者回调实例,或者注册上Action1不完全回调实例来响应式处理命令的执行结

必看视频!获取2024年最新Java开发全套学习资料 备注Java

果。

HystrixCommand的observe()方法的使用示例程序如下:

package com.crazymaker.demo.hystrix;

@Slf4j

public class HystryxCommandExcecuteDemo

{

@Test

public void testObserve() throws Exception

{

/**

*使用统一配置类

*/

HystrixCommand.Setter setter = SetterDemo.buildSetter(

“group-1”,

“testCommand”,

“testThreadPool”);

Observable observe = new HttpGetterCommand(HELLO_TEST_URL, setter).observe();

Thread.sleep(1000);

log.info(“订阅尚未开始!”);

//订阅3次

observe.subscribe(result -> log.info(“onNext result={}”, result),

error -> log.error(“onError error={}”, error));

observe.subscribe(result -> log.info(“onNext result ={}”, result),

error -> log.error(“onError error={}”, error));

observe.subscribe(

result -> log.info(“onNext result={}”, result),

error -> log.error(“onError error ={}”, error),

() -> log.info(“onCompleted called”));

Thread.sleep(Integer.MAX_VALUE);

}

}

运行这个示例程序前需要启动demo-provider实例,确保其REST接口/api/demo/hello/v1可以正常访问。执行这个示例程序,主要的输出结果如下:

[hystrix-testThreadPool-1] INFO c.c.d.h.HttpGetterCommand - req1 begin…

[main] INFO c.c.d.h.HystryxCommandExcecuteDemo - 订阅尚未开始!

[hystrix-testThreadPool-1] INFO c.c.d.h.HttpGetterCommand - req1 end: {“respCode”:0,“respMsg”:“操作成功”,“datas”:{“hello”:"wor

[hystrix-testThreadPool-1] INFO c.c.d.h.HystryxCommandExcecuteDemo - onNext result=req1:{“respCode”:0,“respMsg”:“操作成功”,"dat

[hystrix-testThreadPool-1] INFO c.c.d.h.HystryxCommandExcecuteDemo - onNext result =req1:{“respCode”:0,“respMsg”:“操作成功”,"da

[hystrix-testThreadPool-1] INFO c.c.d.h.HystryxCommandExcecuteDemo - onNext result=req1:{“respCode”:0,“respMsg”:“操作成功”,"dat

[hystrix-testThreadPool-1] INFO c.c.d.h.HystryxCommandExcecuteDemo - onCompleted called

通过执行结果可以看出,如果HystrixCommand的run()方法执行成功,就会触发订阅者的onNext()和onCompleted()回调方法,如果执行异常,就会触发订阅者的onError()回调方法。

调用HystrixCommand的observe()方法会返回一个热主题(Hot Observable)。什么是热主题呢?就是无论主题是否存在观察者订阅,都会自动触发执行它的run()方法。另外还有一点,observe()方法所返回的主题可以重复订阅。

toObservable()方法

=================

HystrixCommand的toObservable()方法会返回一个响应式编程Observable主题。同样可以为该主题对象注册上Subscriber观察者回调实例,或者注册上Action1不完全回调实例,来响应式处理命令的执行结果。不过,与observe()返回的主题不同,Observable主题返回的是冷主题,并且只能被订阅一次。

HystrixCommand的toObservable()方法的使用示例程序如下:

package com.crazymaker.demo.hystrix;

@Slf4j

public class HystryxCommandExcecuteDemo

{

@Test

public void testToObservable() throws Exception

{

最后

小编精心为大家准备了一手资料

以上Java高级架构资料、源码、笔记、视频。Dubbo、Redis、设计模式、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术

【附】架构书籍

  1. BAT面试的20道高频数据库问题解析
  2. Java面试宝典
  3. Netty实战
  4. 算法

BATJ面试要点及Java架构师进阶资料

stToObservable() throws Exception

{

最后

小编精心为大家准备了一手资料

[外链图片转存中…(img-tnnCX7At-1716443382002)]

[外链图片转存中…(img-nkaWlmrp-1716443382003)]

以上Java高级架构资料、源码、笔记、视频。Dubbo、Redis、设计模式、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术

【附】架构书籍

  1. BAT面试的20道高频数据库问题解析
  2. Java面试宝典
  3. Netty实战
  4. 算法

[外链图片转存中…(img-hffrftsE-1716443382003)]

BATJ面试要点及Java架构师进阶资料

[外链图片转存中…(img-uQeD2aNV-1716443382004)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值