hystrix 請求合並(6)


hystrix支持N個請求自動合並為一個請求,這個功能在有網絡交互的場景下尤其有用,比如每個請求都要網絡訪問遠程資源,如果把請求合並為一個,將使多次網絡交互變成一次,極大節省開銷。重要一點,兩個請求能自動合並的前提是兩者足夠“近”,即兩者啟動執行的間隔時長要足夠小,默認為10ms,即超過10ms將不自動合並。

請求合並使多個請求可以批量化成單個HystrixCommand實例執行。
合並器可以使用批量大小和自批次創建以來的經過時間作為執行批處理的觸發器。
Hystrix支持2種請求折疊方式:請求范圍和全局范圍。這是在collapser構造中配置的,默認為請求范圍。
一個請求范圍的collapser收集每個HystrixRequestContext的一個批次,而一個全局范圍的collapser收集一個批次跨多個HystrixRequestContexts。因此,如果您的下游依賴關系在單個命令調用中無法處理多個HystrixRequestContexts,則請求范圍的折疊是正確的選擇。

測試代碼如下:

/**
 * 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;
        }
    }
	
}

 

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();
	    }
	}
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM