hystrix可以将同一个命令的多次执行合并到一起执行。

public class HelloWorldCommandCollapser extends HystrixCollapser<List<String>,String,String> {
private String name;
public HelloWorldCommandCollapser(String name){
this.name = name;
}
@Override
public String getRequestArgument() {
return name;
}
@Override
protected HystrixCommand<List<String>> createCommand(Collection<CollapsedRequest<String, String>> collapsedRequests) {
return new BatchHystrixCommand(collapsedRequests);
}
@Override
protected void mapResponseToRequests(List<String> batchResponse, Collection<CollapsedRequest<String, String>> collapsedRequests) {
int i =0;
for(CollapsedRequest collapsedRequest:collapsedRequests){
collapsedRequest.setResponse(batchResponse.get(i));
i++;
}
}
private class BatchHystrixCommand extends HystrixCommand{
private Collection<CollapsedRequest<String, String>> collapsedRequests;
public BatchHystrixCommand(Collection<CollapsedRequest<String, String>> collapsedRequests){
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.collapsedRequests =collapsedRequests;
}
@Override
protected Object run() throws Exception {
List<String> result = new ArrayList<String>();
for(CollapsedRequest collapsedRequest:collapsedRequests){
result.add("helloworld:"+collapsedRequest.getArgument());
}
return result;
}
}

  方法调用

HystrixRequestContext context = HystrixRequestContext.initializeContext();
try{
String result1 = new HelloWorldCommandCollapser("one").execute();
String result2 = new HelloWorldCommandCollapser("two").execute();
String result3 = new HelloWorldCommandCollapser("three").execute();
String result4 = new HelloWorldCommandCollapser("four").execute();
String result5 = new HelloWorldCommandCollapser("five").execute();
String result6 = new HelloWorldCommandCollapser("six").execute();
System.out.println(result1);
System.out.println(result2);
System.out.println(result3);
System.out.println(result4);
System.out.println(result5);
System.out.println(result6);
}finally {
context.shutdown();
}

  继承HystrixCollapser的命令,命令将会被集合到一起,当数量或时间到达设定的触发点时,统一执行。

  getRequestArgument 获取请求参数,命令执行时,实际是将该方法的参数设置到批量执行对象中。

  createCommand 批量执行对象通过该方法获得实际执行批量的命令,并返回结果。

  mapResponseToRequests 批量执行对象获得执行结果后,将结果与请求进行匹配。

  本质原理如下:

  当执行继承HystrixCollapser方法时,命令不会被实际执行,会获取getRequestArgument获得执行参数,添加到批量执行的对象中去。

public Observable<ResponseType> toObservable(Scheduler observeOn) {
return Observable.defer(new Func0<Observable<ResponseType>>() {
@Override
public Observable<ResponseType> call() {
...
RequestCollapser<BatchReturnType, ResponseType, RequestArgumentType> requestCollapser = collapserFactory.getRequestCollapser(collapserInstanceWrapper);
Observable<ResponseType> response = requestCollapser.submitRequest(getRequestArgument());
...
return response;
}
});
}

  RequestCollapser是批量执行的对象,它有两种作用域,一个是全局范围,一个是一个请求范围内。全局范围通过今天变量实现,一个请求范围通过HystrixRequestVariableHolder实现。  

  当向RequestCollapser添加参数时,当参数到达一定数量时,就会执行批量。

public Observable<ResponseType> submitRequest(final RequestArgumentType arg) {
...
while (true) {
final RequestBatch<BatchReturnType, ResponseType, RequestArgumentType> b = batch.get();
...final Observable<ResponseType> response;
if (arg != null) {
response = b.offer(arg);
} else {
response = b.offer( (RequestArgumentType) NULL_SENTINEL);
}
//如果到达一定数量,respose返回null
if (response != null) {
return response;
} else {
//执行批量
createNewBatchAndExecutePreviousIfNeeded(b);
}
}
}

  RequestCollapser内部有一个定时器,每个一定时间就会批量执行并返回结果。  

private class CollapsedTask implements TimerListener {
final Callable<Void> callableWithContextOfParent;
CollapsedTask() {
callableWithContextOfParent = new HystrixContextCallable<Void>(concurrencyStrategy, new Callable<Void>() {
@Override
public Void call() throws Exception {
...
            RequestBatch<BatchReturnType, ResponseType, RequestArgumentType> currentBatch = batch.get();
            if (currentBatch != null && currentBatch.getSize() > 0) {
              createNewBatchAndExecutePreviousIfNeeded(currentBatch);
            }
            ...
} });
}
@Override
public void tick() {
...
        callableWithContextOfParent.call();
       ...
}
@Override
public int getIntervalTimeInMilliseconds() {
return properties.timerDelayInMilliseconds().get();
}
}

  批量执行

public void executeBatchIfNotAlreadyStarted() {
...
try {
Collection<Collection<CollapsedRequest<ResponseType, RequestArgumentType>>> shards = commandCollapser.shardRequests(argumentMap.values());
for (final Collection<CollapsedRequest<ResponseType, RequestArgumentType>> shardRequests : shards) {
try {
Observable<BatchReturnType> o = commandCollapser.createObservableCommand(shardRequests);//获取批量执行结果
              //批量执行结果映射到执行请求中
commandCollapser.mapResponseToRequests(o, shardRequests).doOnError(new Action1<Throwable>() {
               ...
}).doOnCompleted(new Action0() {
               ...
}).subscribe(); } catch (Exception e) {
...
}
} } catch (Exception e) {
...
} finally {
batchLock.writeLock().unlock();
}
}
}

hystrix总结之请求批量执行的更多相关文章

  1. postman批量执行 要给请求加断言,批量执行的时候才会去统计,成功和失败的条数

    1.设置请求断言后保存 2.点击runner去批量执行 3.有断言的请求就会统计

  2. SpringCloud实战-Hystrix线程隔离&请求缓存&请求合并

    接着上一篇的Hystrix进行进一步了解. 当系统用户不断增长时,每个微服务需要承受的并发压力也越来越大,在分布式环境中,通常压力来自对依赖服务的调用,因为亲戚依赖服务的资源需要通过通信来实现,这样的 ...

  3. 关于postman各功能的说明及用法以及批量执行

    这玩意功能还不错,可以学学,在测试接口或者配合写代码测接口时是有帮助作用的.今天也去打听了一下,一下我就做了一下记录. 首先,主界面: 分开记录,写的详细一些. 左侧菜单栏: 主菜单(请求部分); 输 ...

  4. postman系列之批量执行接口测试用例

    postman如何批量执行接口测试用例~其实很简单,但是会给我们的工作带来很多方便~ 比如我们写了几十个测试用例,请求都是同一个服务器IP,一旦服务器IP地址从测试环境搬到线上环境,需要修改所有的服务 ...

  5. Spring Cloud(Dalston.SR5)--Hystrix 断路器-合并请求

    在 Spring Cloud 中可以使用注解的方式来支持 Hystrix 的合并请求,缓存与合并请求功能需要先初始化请求上下文才能实现,因此,必须实现 javax.servlet.Filter 用于创 ...

  6. 批量执行(Linux命令,上传/下载文件)

    前言: 每个公司的网络环境大都划分 办公网络.线上网络,之所以划分的主要原因是为了保证线上操作安全: 对于外部用户而言也只能访问线上网络的特定开放端口,那么是什么控制了用户访问线上网络的呢? 防火墙过 ...

  7. postman—创建collection,执行collection和批量执行

    接口测试中,可以在 Postman 逐个创建请求.但当请求逐渐增多时,如果我们不采取任何措施管理,散乱的请求维护起来就比较麻烦了.这个时候我们可以创建测试集 Collection 来对这些请求进行管理 ...

  8. 使用python进行接口自动化测试,批量执行测试用例

    工作中,使用python的requests库进行接口自动化测试是一个比较不错的选择,今天就以某网站的免费接口为例,展示以get请求进行批量执行测试用例.话不多说直接开讲 分析一下接口信息, 请求地址: ...

  9. 03-Collection用例管理及批量执行

    当我们对一个或多个系统中的很多用例进行维护时,首先想到的就是对用例进行分类管理,同时还希望对这批用例做回归测试 .在postman也提供了这样一个功能,就是Collection .通过这个Collec ...

随机推荐

  1. 手把手教你使用VUE+SpringMVC+Spring+Mybatis+Maven构建属于你自己的电商系统之vue后台前端框架搭建——猿实战01

            猿实战是一个原创系列文章,通过实战的方式,采用前后端分离的技术结合SpringMVC Spring Mybatis,手把手教你撸一个完整的电商系统,跟着教程走下来,变身猿人找到工作不是 ...

  2. 「完整案例」基于Socket开发TCP传输客户端

    ​1 程序界面设计 TCP客户端在上位机开发中应用很广,大多数情况下,上位机软件都是作为一个TCP客户端来与PLC或其他服务器进行通信的.TCP客户端的主要功能就是连接服务器.发送数据.接收数据.断开 ...

  3. 容器生态.png

    https://www.cnblogs.com/CloudMan6/p/6706546.html

  4. You are using pip version 10.0.1, however version 20.2.2 is available.

    在安装第三方库时,出现如下提示: You are using pip version 10.0.1, however version 20.2.2 is available.You should co ...

  5. 区块链入门到实战(29)之Solidity – 环境搭建

    在线开发环境Remix(推荐) 学习Solidity推荐使用在线开发环境Remix,本教程的例子将使用Remix开发运行. 安装本地编译器 安装 nodejs / npm node官方网站下载node ...

  6. Windows servers 2008 环境下, DHCP的搭建。

    日常上网,客户端的主机都是使用DHCP动态分配的,家用的路由器就是内置了一个DHCP服务,所以每次分到的IP地址基本的都是192.168.x.x/24 网段的.不过家用的路由器最多只能连十台左右.那么 ...

  7. C#-接口(Interface)详解

    定义 在 C# 语言中,类之间的继承关系仅支持单重继承,而接口是为了实现多重继承关系设计的.一个类能同时实现多个接口,还能在实现接口的同时再继承其他类,并且接口之间也可以继承.无论是表示类之间的继承还 ...

  8. h5c3

    HTML5 第一天 一.什么是 HTML5 HTML5 的概念与定义 定义:HTML5 定义了 HTML 标准的最新版本,是对 HTML 的第五次重大修改,号称下一代的 HTML 两个概念: 是一个新 ...

  9. SpringBoot2搭建基础架构——开源软件诞生4

    技术框架篇--第4篇 用日志记录“开源软件”的诞生 赤龙ERP开源地址: 点亮星标,感谢支持,加微信与开发者交流 kzca2000 码云:https://gitee.com/redragon/redr ...

  10. vue + vant 上传图片之压缩图片

    <van-uploader v-model="fileList" multiple :after-read="afterRead" :max-count= ...