hystrix总结之请求批量执行
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总结之请求批量执行的更多相关文章
- postman批量执行 要给请求加断言,批量执行的时候才会去统计,成功和失败的条数
1.设置请求断言后保存 2.点击runner去批量执行 3.有断言的请求就会统计
- SpringCloud实战-Hystrix线程隔离&请求缓存&请求合并
接着上一篇的Hystrix进行进一步了解. 当系统用户不断增长时,每个微服务需要承受的并发压力也越来越大,在分布式环境中,通常压力来自对依赖服务的调用,因为亲戚依赖服务的资源需要通过通信来实现,这样的 ...
- 关于postman各功能的说明及用法以及批量执行
这玩意功能还不错,可以学学,在测试接口或者配合写代码测接口时是有帮助作用的.今天也去打听了一下,一下我就做了一下记录. 首先,主界面: 分开记录,写的详细一些. 左侧菜单栏: 主菜单(请求部分); 输 ...
- postman系列之批量执行接口测试用例
postman如何批量执行接口测试用例~其实很简单,但是会给我们的工作带来很多方便~ 比如我们写了几十个测试用例,请求都是同一个服务器IP,一旦服务器IP地址从测试环境搬到线上环境,需要修改所有的服务 ...
- Spring Cloud(Dalston.SR5)--Hystrix 断路器-合并请求
在 Spring Cloud 中可以使用注解的方式来支持 Hystrix 的合并请求,缓存与合并请求功能需要先初始化请求上下文才能实现,因此,必须实现 javax.servlet.Filter 用于创 ...
- 批量执行(Linux命令,上传/下载文件)
前言: 每个公司的网络环境大都划分 办公网络.线上网络,之所以划分的主要原因是为了保证线上操作安全: 对于外部用户而言也只能访问线上网络的特定开放端口,那么是什么控制了用户访问线上网络的呢? 防火墙过 ...
- postman—创建collection,执行collection和批量执行
接口测试中,可以在 Postman 逐个创建请求.但当请求逐渐增多时,如果我们不采取任何措施管理,散乱的请求维护起来就比较麻烦了.这个时候我们可以创建测试集 Collection 来对这些请求进行管理 ...
- 使用python进行接口自动化测试,批量执行测试用例
工作中,使用python的requests库进行接口自动化测试是一个比较不错的选择,今天就以某网站的免费接口为例,展示以get请求进行批量执行测试用例.话不多说直接开讲 分析一下接口信息, 请求地址: ...
- 03-Collection用例管理及批量执行
当我们对一个或多个系统中的很多用例进行维护时,首先想到的就是对用例进行分类管理,同时还希望对这批用例做回归测试 .在postman也提供了这样一个功能,就是Collection .通过这个Collec ...
随机推荐
- C++开发时字符编码的选择
最近看了很多有关字符编码的讨论帖子, 自己也做了很多尝试, 针对linux和windows上字符编码的选择做了个简单整理, 在此做个记录 首先是基础编码知识, 下面我列出的4个编码方式或字符集是我们应 ...
- Linux下mv命令高级用法
mv 也是 Linux 下一个使用频率非常高的命令,但除了一些基本用法,你还知道它的哪些高级用法呢? 1. 基本用法 移动一个/多个文件: 移动一个/多个目录: 重命名文件/目录. 这些都是很基本的用 ...
- /usr/bin/ld: cannot find -lxxx 问题
linux下编译应用程序常常会出现如下错误: /usr/bin/ld: cannot find -lxxx 意思是编译过程找不到对应库文件.其中,-lxxx表示链接库文件 libxxx.so. 注:有 ...
- promise的常用情况
因为js是单线程的,所以一旦代码中有报错,就不会执行下面的了,如下333就未打印 console.log(111)throw Error(222)console.log(333) 好像与promise ...
- Elementor如何隐藏页面上的标题(2种办法)
原文首发于:https://loyseo.com/how-to-hide-page-title-in-elementor/ 本文介绍两种隐藏Elementor页面默认标题的方法,一种是单个隐藏,一种是 ...
- 图数据库对比:Neo4j vs Nebula Graph vs HugeGraph
本文系腾讯云安全团队李航宇.邓昶博撰写 图数据库在挖掘黑灰团伙以及建立安全知识图谱等安全领域有着天然的优势.为了能更好的服务业务,选择一款高效并且贴合业务发展的图数据库就变得尤为关键.本文挑选了几款业 ...
- 【原创】探索云计算容器底层之Cgroup
一.什么是Cgroup,使用场景? 容器本质上是进程,既然是进程就会消耗掉系统资源,比如:CPU.内存.磁盘.网络带宽等,如果不加以限制,容器在某些情况下就会无限制地吃掉宿主机的系统资源,显然这不是我 ...
- 【小白学PyTorch】1 搭建一个超简单的网络
文章目录: 目录 1 任务 2 实现思路 3 实现过程 3.1 引入必要库 3.2 创建训练集 3.3 搭建网络 3.4 设置优化器 3.5 训练网络 3.6 测试 1 任务 首先说下我们要搭建的网络 ...
- Android开发之Toast吐司的一个封装好的工具类。带有源代码java文件,
import android.content.Context; import android.widget.Toast; //Toast统一管理类 public class T { private T ...
- Bitmap转ImageSource
bitmap to bytes Bitmap b = new Bitmap( "test.bmp "); MemoryStream ms = new MemoryStream(); ...