{"id":32563,"date":"2014-11-11T07:00:10","date_gmt":"2014-11-11T05:00:10","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=32563"},"modified":"2014-11-10T07:07:27","modified_gmt":"2014-11-10T05:07:27","slug":"batching-collapsing-requests-in-hystrix","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html","title":{"rendered":"Batching (collapsing) requests in Hystrix"},"content":{"rendered":"<p><a href=\"https:\/\/github.com\/Netflix\/Hystrix\">Hystrix<\/a> has an advanced feature of <a href=\"https:\/\/github.com\/Netflix\/Hystrix\/wiki\/How-To-Use#Collapsing\">collapsing (or batching)<\/a> requests. If two or more commands run similar request at the same time, Hystrix can combine them together, run one batched request and dispatch split results back to all commands. Let&#8217;s first see how Hystrix works without collapsing. Imagine we have a service that looks up <code>StockPrice<\/code>of a given <code>Ticker<\/code>:<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<\/p>\n<pre class=\"brush: groovy\">import lombok.Value;\r\nimport java.math.BigDecimal;\r\nimport java.time.Instant;\r\n\r\n@Value\r\nclass Ticker {\r\n    String symbol;\r\n}\r\n\r\n@Value\r\nclass StockPrice {\r\n    BigDecimal price;\r\n    Instant effectiveTime;\r\n}\r\n\r\ninterface StockPriceGateway {\r\n\r\n    default StockPrice load(Ticker stock) {\r\n        final Set&lt;Ticker&gt; oneTicker = Collections.singleton(stock);\r\n        return loadAll(oneTicker).get(stock);\r\n    }\r\n\r\n    ImmutableMap&lt;Ticker, StockPrice&gt; loadAll(Set&lt;Ticker&gt; tickers);\r\n}\r\n<\/pre>\n<p>Core implementation of <code>StockPriceGateway<\/code> must provide <code>loadAll()<\/code> batch method while <code>load()<\/code> method is implemented for our convenience. So our gateway is capable of loading multiple prices in one batch (e.g. to reduce latency or network protocol overhead), but at the moment we are not using this feature, always loading price of one stock at a time:<\/p>\n<pre class=\"brush: groovy\">class StockPriceCommand extends HystrixCommand&lt;StockPrice&gt; {\r\n\r\n    private final StockPriceGateway gateway;\r\n    private final Ticker stock;\r\n\r\n    StockPriceCommand(StockPriceGateway gateway, Ticker stock) {\r\n        super(HystrixCommandGroupKey.Factory.asKey(\"Stock\"));\r\n        this.gateway = gateway;\r\n        this.stock = stock;\r\n    }\r\n\r\n    @Override\r\n    protected StockPrice run() throws Exception {\r\n        return gateway.load(stock);\r\n    }\r\n}\r\n<\/pre>\n<p>Such command will always call <code>StockPriceGateway.load()<\/code> for each and every <code>Ticker<\/code>, as illustrated by the following tests:<\/p>\n<pre class=\"brush: groovy\">class StockPriceCommandTest extends Specification {\r\n\r\n    def gateway = Mock(StockPriceGateway)\r\n\r\n    def 'should fetch price from external service'() {\r\n        given:\r\n            gateway.load(TickerExamples.any()) &gt;&gt; StockPriceExamples.any()\r\n            def command = new StockPriceCommand(gateway, TickerExamples.any())\r\n\r\n        when:\r\n            def price = command.execute()\r\n\r\n        then:\r\n            price == StockPriceExamples.any()\r\n    }\r\n\r\n    def 'should call gateway exactly once when running Hystrix command'() {\r\n        given:\r\n            def command = new StockPriceCommand(gateway, TickerExamples.any())\r\n\r\n        when:\r\n            command.execute()\r\n\r\n        then:\r\n            1 * gateway.load(TickerExamples.any())\r\n    }\r\n\r\n    def 'should call gateway twice when command executed two times'() {\r\n        given:\r\n            def commandOne = new StockPriceCommand(gateway, TickerExamples.any())\r\n            def commandTwo = new StockPriceCommand(gateway, TickerExamples.any())\r\n\r\n        when:\r\n            commandOne.execute()\r\n            commandTwo.execute()\r\n\r\n        then:\r\n            2 * gateway.load(TickerExamples.any())\r\n    }\r\n\r\n    def 'should call gateway twice even when executed in parallel'() {\r\n        given:\r\n            def commandOne = new StockPriceCommand(gateway, TickerExamples.any())\r\n            def commandTwo = new StockPriceCommand(gateway, TickerExamples.any())\r\n\r\n        when:\r\n            Future&lt;StockPrice&gt; futureOne = commandOne.queue()\r\n            Future&lt;StockPrice&gt; futureTwo = commandTwo.queue()\r\n\r\n        and:\r\n            futureOne.get()\r\n            futureTwo.get()\r\n\r\n        then:\r\n            2 * gateway.load(TickerExamples.any())\r\n    }\r\n\r\n}\r\n<\/pre>\n<p>If you don&#8217;t know Hystrix, by wrapping an external call in a command you gain a lot of features like timeouts, circuit breakers, etc. But this is not the focus of this article. Look at last two tests: when asking for price of arbitrary ticker twice, sequentially or in parallel (<code>queue()<\/code>), our external <code>gateway<\/code> is also called twice. Last test is especially interesting &#8211; we ask for the same ticker at almost the same time, but Hystrix can&#8217;t figure that out. These two commands are fully independent, will be executed in different threads and don&#8217;t know anything about each other &#8211; even though they run at almost the same time.<\/p>\n<p>Collapsing is all about finding such similar requests and combining them. Batching (I will use this term interchangeably with <em>collapsing<\/em>) doesn&#8217;t happen automatically and requires a bit of coding. But first let&#8217;s see how it behaves:<\/p>\n<pre class=\"brush: groovy\">def 'should collapse two commands executed concurrently for the same stock ticker'() {\r\n    given:\r\n        def anyTicker = TickerExamples.any()\r\n        def tickers = [anyTicker] as Set\r\n\r\n    and:\r\n        def commandOne = new StockTickerPriceCollapsedCommand(gateway, anyTicker)\r\n        def commandTwo = new StockTickerPriceCollapsedCommand(gateway, anyTicker)\r\n\r\n    when:\r\n        Future&lt;StockPrice&gt; futureOne = commandOne.queue()\r\n        Future&lt;StockPrice&gt; futureTwo = commandTwo.queue()\r\n\r\n    and:\r\n        futureOne.get()\r\n        futureTwo.get()\r\n\r\n    then:\r\n        0 * gateway.load(_)\r\n        1 * gateway.loadAll(tickers) &gt;&gt; ImmutableMap.of(anyTicker, StockPriceExamples.any())\r\n}\r\n\r\ndef 'should collapse two commands executed concurrently for the different stock tickers'() {\r\n    given:\r\n        def anyTicker = TickerExamples.any()\r\n        def otherTicker = TickerExamples.other()\r\n        def tickers = [anyTicker, otherTicker] as Set\r\n\r\n    and:\r\n        def commandOne = new StockTickerPriceCollapsedCommand(gateway, anyTicker)\r\n        def commandTwo = new StockTickerPriceCollapsedCommand(gateway, otherTicker)\r\n\r\n    when:\r\n        Future&lt;StockPrice&gt; futureOne = commandOne.queue()\r\n        Future&lt;StockPrice&gt; futureTwo = commandTwo.queue()\r\n\r\n    and:\r\n        futureOne.get()\r\n        futureTwo.get()\r\n\r\n    then:\r\n        1 * gateway.loadAll(tickers) &gt;&gt; ImmutableMap.of(\r\n                anyTicker, StockPriceExamples.any(),\r\n                otherTicker, StockPriceExamples.other())\r\n}\r\n\r\ndef 'should correctly map collapsed response into individual requests'() {\r\n    given:\r\n        def anyTicker = TickerExamples.any()\r\n        def otherTicker = TickerExamples.other()\r\n        def tickers = [anyTicker, otherTicker] as Set\r\n        gateway.loadAll(tickers) &gt;&gt; ImmutableMap.of(\r\n                anyTicker, StockPriceExamples.any(),\r\n                otherTicker, StockPriceExamples.other())\r\n\r\n    and:\r\n        def commandOne = new StockTickerPriceCollapsedCommand(gateway, anyTicker)\r\n        def commandTwo = new StockTickerPriceCollapsedCommand(gateway, otherTicker)\r\n\r\n    when:\r\n        Future&lt;StockPrice&gt; futureOne = commandOne.queue()\r\n        Future&lt;StockPrice&gt; futureTwo = commandTwo.queue()\r\n\r\n    and:\r\n        def anyPrice = futureOne.get()\r\n        def otherPrice = futureTwo.get()\r\n\r\n    then:\r\n        anyPrice == StockPriceExamples.any()\r\n        otherPrice == StockPriceExamples.other()\r\n}\r\n<\/pre>\n<p>First test proves that instead of calling <code>load()<\/code> twice we barely called <code>loadAll()<\/code> once. Also notice that since we asked for the same <code>Ticker<\/code> (from two different threads), <code>loadAll()<\/code> asks for only one ticker. Second test shows two concurrent requests for two different tickers being collapsed into one batch call. Third test makes sure we still get proper responses to each individual request. Instead of extending <code>HystrixCommand<\/code> we must extend more complex<code>HystrixCollapser<\/code>. Now it&#8217;s time to see <code>StockTickerPriceCollapsedCommand<\/code> implementation, that seamlessly replaced <code>StockPriceCommand<\/code>:<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<pre class=\"brush: groovy;wrap-lines:false\">class StockTickerPriceCollapsedCommand extends HystrixCollapser&lt;ImmutableMap&lt;Ticker, StockPrice&gt;, StockPrice, Ticker&gt; {\r\n\r\n    private final StockPriceGateway gateway;\r\n    private final Ticker stock;\r\n\r\n    StockTickerPriceCollapsedCommand(StockPriceGateway gateway, Ticker stock) {\r\n        super(HystrixCollapser.Setter.withCollapserKey(HystrixCollapserKey.Factory.asKey(\"Stock\"))\r\n                .andCollapserPropertiesDefaults(HystrixCollapserProperties.Setter().withTimerDelayInMilliseconds(100)));\r\n        this.gateway = gateway;\r\n        this.stock = stock;\r\n    }\r\n\r\n    @Override\r\n    public Ticker getRequestArgument() {\r\n        return stock;\r\n    }\r\n\r\n    @Override\r\n    protected HystrixCommand&lt;ImmutableMap&lt;Ticker, StockPrice&gt;&gt; createCommand(Collection&lt;CollapsedRequest&lt;StockPrice, Ticker&gt;&gt; collapsedRequests) {\r\n        final Set&lt;Ticker&gt; stocks = collapsedRequests.stream()\r\n                .map(CollapsedRequest::getArgument)\r\n                .collect(toSet());\r\n        return new StockPricesBatchCommand(gateway, stocks);\r\n    }\r\n\r\n    @Override\r\n    protected void mapResponseToRequests(ImmutableMap&lt;Ticker, StockPrice&gt; batchResponse, Collection&lt;CollapsedRequest&lt;StockPrice, Ticker&gt;&gt; collapsedRequests) {\r\n        collapsedRequests.forEach(request -&gt; {\r\n            final Ticker ticker = request.getArgument();\r\n            final StockPrice price = batchResponse.get(ticker);\r\n            request.setResponse(price);\r\n        });\r\n    }\r\n\r\n}\r\n<\/pre>\n<p>A lot is going on here, so let&#8217;s review <code>StockTickerPriceCollapsedCommand<\/code> step by step. First three generic types:<\/p>\n<ul>\n<li><code>BatchReturnType<\/code> (<code>ImmutableMap&lt;Ticker, StockPrice&gt;<\/code> in our example) is the type of batched command response. As you will see later, collapser turns multiple small commands into a batch command. This is the type of that batch command&#8217;s response. Notice that it&#8217;s the same as <code>StockPriceGateway.loadAll()<\/code> type).<\/li>\n<li><code>ResponseType<\/code> (<code>StockPrice<\/code>) is the type of each individual command being collapsed. In our case we are collapsing <code>HystrixCommand&lt;StockPrice&gt;<\/code>. Later we will split value of <code>BatchReturnType<\/code> into multiple <code>StockPrice<\/code>.<\/li>\n<li><code>RequestArgumentType<\/code> (<code>Ticker<\/code>) is the input of each individual command we are about to collapse (batch). When multiple commands are batched together, we are eventually replacing all of them with one batched command. This command should receive all individual requests in order to perform one batch request.<\/li>\n<\/ul>\n<p><code>withTimerDelayInMilliseconds(100)<\/code> will be explained soon. <code>createCommand()<\/code> creates a <em>batch<\/em> command. This command should replace all individual commands and perform batched logic. In our case instead of multiple individual<code>load()<\/code> calls we just make one:<\/p>\n<pre class=\"brush: groovy\">class StockPricesBatchCommand extends HystrixCommand&lt;ImmutableMap&lt;Ticker, StockPrice&gt;&gt; {\r\n\r\n    private final StockPriceGateway gateway;\r\n    private final Set&lt;Ticker&gt; stocks;\r\n\r\n    StockPricesBatchCommand(StockPriceGateway gateway, Set&lt;Ticker&gt; stocks) {\r\n        super(HystrixCommandGroupKey.Factory.asKey(\"Stock\"));\r\n        this.gateway = gateway;\r\n        this.stocks = stocks;\r\n    }\r\n\r\n    @Override\r\n    protected ImmutableMap&lt;Ticker, StockPrice&gt; run() throws Exception {\r\n        return gateway.loadAll(stocks);\r\n    }\r\n}\r\n<\/pre>\n<p>The only difference between this class and <code>StockPriceCommand<\/code> is that it takes a bunch of <code>Ticker<\/code>s and returns prices for all of them. Hystrix will collect a few instances of <code>StockTickerPriceCollapsedCommand<\/code> and once it has <em>enough<\/em>(more on that later) it will create single <code>StockPriceCommand<\/code>. Hope this is clear, because <code>mapResponseToRequests()<\/code>is slightly more involved. Once our collapsed <code>StockPricesBatchCommand<\/code> finishes, we must somehow split batch response and communicate replies back to individual commands, unaware of collapsing. From that perspective<code>mapResponseToRequests()<\/code> implementation is fairly straightforward: we receive batch response and a collection of wrapped <code>CollapsedRequest&lt;StockPrice, Ticker&gt;<\/code>. We must now iterate over all awaiting individual requests and complete them (<code>setResponse()<\/code>). If we don&#8217;t complete some of the requests, they will hang infinitely and eventually time out.<\/p>\n<h2>How it works<\/h2>\n<p>This is the right moment to describe how collapsing is implemented. I said before that collapsing happens when two requests occur at the same time. There is no such thing as <em>the same time<\/em>. In reality when first collapsible request comes in, Hystrix starts a timer. In our examples we set it to 100 milliseconds. During that period our command is suspended, waiting for other commands to join. After this configurable period Hystrix will call <code>createCommand()<\/code>, gathering all request keys (by calling <code>getRequestArgument()<\/code>) and run it. When batched command finishes, it will let us dispatch results to all awaiting individual commands. It is also possible to limit the number of collapsed requests if we are afraid of creating humongous batch &#8211; on the other hand how many concurrent requests can fit within this short time slot?<\/p>\n<h2>Use cases and drawbacks<\/h2>\n<p>Request collapsing should be used in systems with extreme load &#8211; high frequency of requests. If you get just one request per collapsing time window (100 milliseconds in examples), collapsing will just add overhead. That&#8217;s because every time you call collapsible command, it must wait just in case some other command wants to join and form batch. This makes sense only when at least couple of commands are collapsed. Time wasted for waiting is balanced by savings in network latency and\/or better utilization of resources in our collaborator (very often batch requests are much faster compared to individual calls). But keep in mind collapsing is a double edged sword, useful in specific cases.<\/p>\n<p>Last thing to remember &#8211; in order to use request collapsing you need<code>HystrixRequestContext.initializeContext()<\/code> and <code>shutdown()<\/code> in <code>try-finally<\/code> block:<\/p>\n<pre class=\"brush: groovy\">HystrixRequestContext context = HystrixRequestContext.initializeContext();\r\ntry {\r\n    \/\/...\r\n} finally {\r\n    context.shutdown();\r\n}\r\n<\/pre>\n<h2>Collapsing vs. caching<\/h2>\n<p>You might think that collapsing can be replaced with proper caching. This is not true. You use cache when:<\/p>\n<ol>\n<li>resource is likely to be accessed multiple times<\/li>\n<li>we can safely use previous value, it will remain valid for some period of time <strong>or<\/strong> we know precisely how to invalidate it<\/li>\n<li>we can afford concurrent requests for the same resource to compute it multiple times<\/li>\n<\/ol>\n<p>On the other hand collapsing does not enforce locality of data (1), it always hits the real service and never returns stale data (2). And finally if we ask for the same resource from multiple threads, we will only call backing service once (3). In case of caching, unless your cache is really smart, two threads will independently discover absence of given resource in cache and ask backing service twice. However collapsing can work <em>together<\/em> with caching &#8211; by consulting cache before running collapsible command.<\/p>\n<h2>Summary<\/h2>\n<p>Request collapsing is a useful tool, but with very limited use cases. It can significantly improve throughput in our system as well as limit load in external service. Collapsing can magically flatten peaks in traffic, rather than spreading it all over. Just make sure you are using it for commands running with extreme frequency.<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"http:\/\/www.nurkiewicz.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html\">Batching (collapsing) requests in Hystrix<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/jcg\/\">JCG partner<\/a> Tomasz Nurkiewicz at the <a href=\"http:\/\/www.nurkiewicz.com\/\">Java and neighbourhood<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Hystrix has an advanced feature of collapsing (or batching) requests. If two or more commands run similar request at the same time, Hystrix can combine them together, run one batched request and dispatch split results back to all commands. Let&#8217;s first see how Hystrix works without collapsing. Imagine we have a service that looks up &hellip;<\/p>\n","protected":false},"author":13,"featured_media":112,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[1002],"class_list":["post-32563","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-hystrix"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Batching (collapsing) requests in Hystrix<\/title>\n<meta name=\"description\" content=\"Hystrix has an advanced feature of collapsing (or batching) requests. If two or more commands run similar request at the same time, Hystrix can combine\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Batching (collapsing) requests in Hystrix\" \/>\n<meta property=\"og:description\" content=\"Hystrix has an advanced feature of collapsing (or batching) requests. If two or more commands run similar request at the same time, Hystrix can combine\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2014-11-11T05:00:10+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Tomasz Nurkiewicz\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/tnurkiewicz\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Tomasz Nurkiewicz\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/11\\\/batching-collapsing-requests-in-hystrix.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/11\\\/batching-collapsing-requests-in-hystrix.html\"},\"author\":{\"name\":\"Tomasz Nurkiewicz\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/fb1be85725c10e8361e641fa851e79e1\"},\"headline\":\"Batching (collapsing) requests in Hystrix\",\"datePublished\":\"2014-11-11T05:00:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/11\\\/batching-collapsing-requests-in-hystrix.html\"},\"wordCount\":1130,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/11\\\/batching-collapsing-requests-in-hystrix.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"keywords\":[\"Hystrix\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/11\\\/batching-collapsing-requests-in-hystrix.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/11\\\/batching-collapsing-requests-in-hystrix.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/11\\\/batching-collapsing-requests-in-hystrix.html\",\"name\":\"Batching (collapsing) requests in Hystrix\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/11\\\/batching-collapsing-requests-in-hystrix.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/11\\\/batching-collapsing-requests-in-hystrix.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"datePublished\":\"2014-11-11T05:00:10+00:00\",\"description\":\"Hystrix has an advanced feature of collapsing (or batching) requests. If two or more commands run similar request at the same time, Hystrix can combine\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/11\\\/batching-collapsing-requests-in-hystrix.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/11\\\/batching-collapsing-requests-in-hystrix.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/11\\\/batching-collapsing-requests-in-hystrix.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"java-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/11\\\/batching-collapsing-requests-in-hystrix.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Batching (collapsing) requests in Hystrix\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/fb1be85725c10e8361e641fa851e79e1\",\"name\":\"Tomasz Nurkiewicz\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g\",\"caption\":\"Tomasz Nurkiewicz\"},\"description\":\"Java EE developer, Scala enthusiast. Enjoying data analysis and visualization. Strongly believes in the power of testing and automation.\",\"sameAs\":[\"http:\\\/\\\/nurkiewicz.blogspot.com\\\/\",\"https:\\\/\\\/x.com\\\/https:\\\/\\\/twitter.com\\\/tnurkiewicz\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/tomasz-nurkiewicz\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Batching (collapsing) requests in Hystrix","description":"Hystrix has an advanced feature of collapsing (or batching) requests. If two or more commands run similar request at the same time, Hystrix can combine","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html","og_locale":"en_US","og_type":"article","og_title":"Batching (collapsing) requests in Hystrix","og_description":"Hystrix has an advanced feature of collapsing (or batching) requests. If two or more commands run similar request at the same time, Hystrix can combine","og_url":"https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2014-11-11T05:00:10+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","type":"image\/jpeg"}],"author":"Tomasz Nurkiewicz","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/tnurkiewicz","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Tomasz Nurkiewicz","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html"},"author":{"name":"Tomasz Nurkiewicz","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/fb1be85725c10e8361e641fa851e79e1"},"headline":"Batching (collapsing) requests in Hystrix","datePublished":"2014-11-11T05:00:10+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html"},"wordCount":1130,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","keywords":["Hystrix"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html","url":"https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html","name":"Batching (collapsing) requests in Hystrix","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","datePublished":"2014-11-11T05:00:10+00:00","description":"Hystrix has an advanced feature of collapsing (or batching) requests. If two or more commands run similar request at the same time, Hystrix can combine","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","width":150,"height":150,"caption":"java-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2014\/11\/batching-collapsing-requests-in-hystrix.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Batching (collapsing) requests in Hystrix"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/fb1be85725c10e8361e641fa851e79e1","name":"Tomasz Nurkiewicz","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g","caption":"Tomasz Nurkiewicz"},"description":"Java EE developer, Scala enthusiast. Enjoying data analysis and visualization. Strongly believes in the power of testing and automation.","sameAs":["http:\/\/nurkiewicz.blogspot.com\/","https:\/\/x.com\/https:\/\/twitter.com\/tnurkiewicz"],"url":"https:\/\/www.javacodegeeks.com\/author\/tomasz-nurkiewicz"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/32563","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=32563"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/32563\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/112"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=32563"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=32563"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=32563"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}