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. 手机APP无法抓包(无法连接服务器)

    一. 把证书放到系统信任区 前提:手机已root 详细步骤 计算证书名 openssl x509 -subject_hash_old -in charles-ssl-proxying-certific ...

  2. python 计算文件md5值

    md5是一种常见不可逆加密算法,使用简单,计算速度快,在很多场景下都会用到,比如:给用户上传的文件命名,数据库中保存的用户密码,下载文件后检验文件是否正确等.下面讲解在python中如何使用md5算法 ...

  3. js实现将时分秒转化成毫秒,将秒转化成时分秒

    // 时间转为毫秒 timeToSec(time) { var hour = time.split('[0] var min = time.split('[1] var sec = time.spli ...

  4. PowerDesigner 使用笔记

    1.将mysql数据结构导入到PowerDesigner https://blog.csdn.net/guochanof/article/details/81905616 2.设计数据库过程 http ...

  5. Protocol buffers--python 实践 简介以及安装与使用

    简介: Protocol Buffers以下简称pb,是google开发的一个可以序列化 反序列化object的数据交换格式,类似于xml,但是比xml 更轻,更快,更简单.而且以上的重点突出一个跨平 ...

  6. 使用log4j将数据流入flume

    最近做了一个log抽取的项目,采用log4j+flume实现,在此分享记录一下. 准备 什么是flume? flume是一个提供高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统. flume ...

  7. double与Double

    1. double是基本数据类型,Double是原始数据类型(Java 类) 2. double创建引用,Double创建对象 3. double不可以为NULL,Double是类所以其对象是可以为N ...

  8. 位运算处理字符大小写转换 - 关联Leetcode 709. 转成小写字母

    大写变小写.小写变大写 : 字符 ^= 32; 大写变小写.小写变小写 : 字符 |= 32; 小写变大写.大写变大写 : 字符 &= -33; 题目 实现函数 ToLowerCase(),该 ...

  9. ARouter使用

    1. androidstudio3.0配置 javaCompileOptions { annotationProcessorOptions { arguments = [AROUTER_MODULE_ ...

  10. unity3d android动态更新dll

    基本是参考这篇文章:http://blog.sina.com.cn/s/blog_9e5d42ee0102vvtg.html,进行了增删一波. 大略说一下基本步骤:1.下载mono源码,修改源码,编译 ...