hystrix 请求合并

hystrix支持N个请求自动合并为一个请求,这个功能在有网络交互的场景下尤其有用,比如每个请求都要网络访问远程资源,如果把请求合并为一个,将使多次网络交互变成一次,极大节省开销。重要一点,两个请求能自动合并的前提是两者足够“近”,即两者启动执行的间隔时长要足够小,默认为10ms,即超过10ms将不自动合并。

请求合并使多个请求可以批量化成单个HystrixCommand实例执行。
合并器可以使用批量大小和自批次创建以来的经过时间作为执行批处理的触发器。
Hystrix支持2种请求折叠方式:请求范围和全局范围。这是在collapser构造中配置的,默认为请求范围。
一个请求范围的collapser收集每个HystrixRequestContext的一个批次,而一个全局范围的collapser收集一个批次跨多个HystrixRequestContexts。因此,如果您的下游依赖关系在单个命令调用中无法处理多个HystrixRequestContexts,则请求范围的折叠是正确的选择。

测试代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/**
  * hystrix支持N个请求自动合并为一个请求,这个功能在有网络交互的场景下尤其有用
  * 比如每个请求都要网络访问远程资源,如果把请求合并为一个,将使多次网络交互变成一次,极大节省开销
  * 重要一点,两个请求能自动合并的前提是两者足够“近”,即两者启动执行的间隔时长要足够小,默认为10ms,即超过10ms将不自动合并
  * @author liucongcong 2017年10月17日
  *
  */
public  class  HystrixCollapser  extends  com.netflix.hystrix.HystrixCollapser<List<String>, String, Integer>{
 
     private  final  Integer key;
 
     public  HystrixCollapser(Integer key) {
         this .key = key;
     }
 
     @Override
     public  Integer getRequestArgument() {
         return  key;
     }
 
     @Override
     protected  HystrixCommand<List<String>> createCommand( final  Collection<CollapsedRequest<String, Integer>> requests) {
         return  new  BatchCommand(requests);
     }
 
     @Override
     protected  void  mapResponseToRequests(List<String> batchResponse, Collection<CollapsedRequest<String, Integer>> requests) {
         int  count =  0 ;
         for  (CollapsedRequest<String, Integer> request : requests) {
             request.setResponse(batchResponse.get(count++));
         }
     }
     
     private  static  final  class  BatchCommand  extends  HystrixCommand<List<String>> {
         private  final  Collection<CollapsedRequest<String, Integer>> requests;
 
         private  BatchCommand(Collection<CollapsedRequest<String, Integer>> requests) {
                 super (Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey( "ExampleGroup" ))
                     .andCommandKey(HystrixCommandKey.Factory.asKey( "GetValueForKey" )));
             this .requests = requests;
         }
 
         @Override
         protected  List<String> run() {
             ArrayList<String> response =  new  ArrayList<String>();
             for  (CollapsedRequest<String, Integer> request : requests) {
                 // 批量收到的每个参数的响应
                 response.add( "collapser: "  + request.getArgument());
             }
             return  response;
         }
     }
     
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public  class  TestCollapser {
 
     @Test
     public  void  testCollapser()  throws  Exception {
         HystrixRequestContext context = HystrixRequestContext.initializeContext();
         try  {
             Future<String> f1 =  new  HystrixCollapser( 1 ).queue();
             //Thread.sleep(100);
             Future<String> f2 =  new  HystrixCollapser( 2 ).queue();
             Future<String> f3 =  new  HystrixCollapser( 3 ).queue();
             Future<String> f4 =  new  HystrixCollapser( 4 ).queue();
 
             assertEquals( "collapser: 1" , f1.get());
             assertEquals( "collapser: 2" , f2.get());
             assertEquals( "collapser: 3" , f3.get());
             assertEquals( "collapser: 4" , f4.get());
 
             // 当前的请求数        自动合并请求 总共发送一次请求
             assertEquals( 1 , HystrixRequestLog.getCurrentRequest().getExecutedCommands().size());
             
             HystrixCommand<?> command = HystrixRequestLog.getCurrentRequest().getExecutedCommands().toArray( new  HystrixCommand<?>[ 1 ])[ 0 ];
             // assert the command is the one we're expecting
             assertEquals( "GetValueForKey" , command.getCommandKey().name());
             // confirm that it was a COLLAPSED command execution
             assertTrue(command.getExecutionEvents().contains(HystrixEventType.COLLAPSED));
             // and that it was successful
             assertTrue(command.getExecutionEvents().contains(HystrixEventType.SUCCESS));
         finally  {
             context.shutdown();
         }
     }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值