Uploaded image for project: 'Traffic Server'
  1. Traffic Server
  2. TS-3954

Latency with SPDY/HTTP/2 when chunking disabled (not default setting)

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 6.0.1, 6.1.0
    • Component/s: HTTP/2, SPDY
    • Labels:

      Description

      The last frame to tell the client it is the end of the data takes awhile to be sent.

      [bcall@homer ~]$ nghttp -v -H ':authority: s.yimg.com'  'https://l7.ycs.swp.yahoo.com/os/bossnext/0.1.187/js/40.69bc98cf2f62459d4ce9.min.js'
      [  0.050] Connected
      [  0.105][NPN] server offers:
                * h2
                * h2-14
                * spdy/3.1
                * spdy/3
                * http/1.1
                * http/1.0
      The negotiated protocol: h2
      [  0.163] send SETTINGS frame <length=12, flags=0x00, stream_id=0>
                (niv=2)
                [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
                [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
      [  0.163] send HEADERS frame <length=75, flags=0x05, stream_id=1>
                ; END_STREAM | END_HEADERS
                (padlen=0)
                ; Open new stream
                :method: GET
                :path: /os/bossnext/0.1.187/js/40.69bc98cf2f62459d4ce9.min.js
                :scheme: https
                :authority: s.yimg.com
                accept: */*
                accept-encoding: gzip, deflate
                user-agent: nghttp2/0.7.11-DEV
      [  0.163] recv SETTINGS frame <length=6, flags=0x00, stream_id=0>
                (niv=1)
                [SETTINGS_INITIAL_WINDOW_SIZE(0x04):1048576]
      [  0.163] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
                ; ACK
                (niv=0)
      [  0.163] recv WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=0>
                (window_size_increment=983041)
      [  0.213] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
                ; ACK
                (niv=0)
      [  0.264] recv (stream_id=1, sensitive) :status: 200
      [  0.264] recv (stream_id=1) accept-ranges: bytes
      [  0.264] recv (stream_id=1) cache-control: max-age=536112000
      [  0.264] recv (stream_id=1) content-encoding: gzip
      [  0.264] recv (stream_id=1) content-type: application/javascript
      [  0.264] recv (stream_id=1) date: Tue, 29 Sep 2015 22:16:54 GMT
      [  0.264] recv (stream_id=1) etag: "YM:1:bcf1abbc-31fc-42f2-aa31-37f6848c126700052082483e3025"
      [  0.264] recv (stream_id=1) expires: Fri, 24 Sep 2032 22:16:54 GMT
      [  0.264] recv (stream_id=1) last-modified: Thu, 24 Sep 2015 18:20:13 GMT
      [  0.264] recv (stream_id=1) server: ATS
      [  0.264] recv (stream_id=1) vary: Accept-Encoding
      [  0.264] recv (stream_id=1) via: HTTP/1.1 web4.usw45.mobstor.gq1.yahoo.com UserFiberFramework/1.0, https/1.1 l7.ycs.swp.yahoo.com (ApacheTrafficServer [cMsSfW])
      [  0.264] recv (stream_id=1) x-ysws-request-id: f67de7a0-ab76-4437-b73f-6c461a808f13
      [  0.264] recv (stream_id=1) x-ysws-visited-replicas: gops.usw45.mobstor.vip.gq1.yahoo.com
      [  0.264] recv (stream_id=1) age: 0
      [  0.264] recv HEADERS frame <length=606, flags=0x04, stream_id=1>
                ; END_HEADERS
                (padlen=0)
                ; First response header
      webpackJsonp([40],{565:function(e,t,n){"use strict";e.exports={controllerViews:{compAnswersContainer_WDC:n(604),compYahooAnswersContainer_WDC:n(605)},actions:{},stores:{}}},604:function(e,t,n){"use strict";var r,s=n(1),i=n(2),a=n(5),o=n(11),l=n(13),c=n(37),u=n(12);r=s.createClass({displayName:"CompAnswers",mixins:[i,u],shouldComponentUpdate:function(e,t){return!1},getProfileImgDimensions:function(e){return{width:24,height:24}},getColonSeparatedKeyValuePair:function(e){var t=e.split(":"),n=t[0],r=t[1];return{key:n,value:r}},render:function(){var e,t,n=this,r=this.context.getStore(a),i=r.getPageConfig(),u=[];return this.props&&this.props.config&&(t=this.props.config.items),t&&t.constructor===Array&&0!==t.length?(u=t.reduce(function(e,t,r){var i="AnswersIntl"+r,a={data:t.data,meta:t.meta&&t.meta.conf||{}};switch(t.type){case"compTitle":if(a.data&&a.data.constructor===Array&&a.data[0].text&&a.data[0].text.txt){var u=n.getColonSeparatedKeyValuePair(a.data[0].text.txt);"search.sc.sccs.answers.answers_dd.title"===u.key&&(a.data[0].text.txt=u.value+" - "+n.getIntlMessage("YAHOO_ANSWERS_RESULTS"))}e.push(s.createElement(o,{key:i,config:a,infoCls:"Txt C(#5f5f5f)! M(0px) Fw(400) D(ib)",divCls:"C(#5f5f5f)! Mt(10px) Fz(1.5rem)"}));break;case"compArticleList":e.push(s.createElement(c,{key:i,config:a,fnGetSubImageDimensions:n.getProfileImgDimensions,subImageWrapWidth:24,subImageWrapCls:"Fl(start) Pos(r) Bgc(#000)",linkCls:"",infoCls:"Fz(1.3rem) Fw(n) M(0px)",subTxtCls:"Mb(4px) Mt(0px) Pstart(12px) LineClamp(2)",listItemCls:"Ov(a) D(b) Mt(10px)",listCls:"M(0px)",contentCls:"Ov(h) Pstart(12px) Pos(r)",subTextTxtCls:"Pstart(12px) Ov(h) LineClamp(3)",subTextCiteCls:"C(#1e7d8e)! Pstart(12px) Ov(h)",contentNoImgCls:"Ov(h) Cl(start) Pos(r)",subImageCls:"Pos(r) Bgz(ct)",lblCls:"Pos(a) T(0px) End(0px)"}));break;case"compText":if(a.data&&a.data.constructor===Array&&a.data[0]&&a.data[0].text&&a.data[0].text.txt){var u=n.getColonSeparatedKeyValuePair(a.data[0].text.txt);"search.sc.sccs.answers.answers_dd.related_questions"===u.key&&(a.data[0].text.txt=u.value+" "+n.getIntlMessage("YAHOO_ANSWERS_RELATED_QUESTIONS_LBL"))}e.push(s.createElement(l,{key:i,config:a,textLinkCls:"txt Fz(1.3rem)",paragraphCls:"compText My(10px) Mend(8px)"}))}return e},[]),e="Mb-30",i.route.app.show_classes&&(e+=" "+n.props.className),s.createElement("div",{className:e},u)):!1}}),e.exports=r},605:function(e,t,n){"use strict";var r=n(1),s=n(2),i=n(5),a=n(11),o=n(13),l=n(37),c=n(12);e.exports=r.createClass({displayName:"exports",mixins:[s,c],render:function(){var e,t,n=this.context.getStore(i),s=n.getPageConfig(),c=[],u=this.props&&this.props.moduleType||"";return this.props&&this.props.config&&(t=this.props.config.items),t&&t.constructor===Array&&0!==t.length?(c=t.reduce(function(e,t,n){var s=u+n,i={data:t.data,meta:t.meta&&t.meta.conf||{}};switch(t.type){case"compTitle":e.push(r.createElement(a,{key:s,config:i,infoCls:"Txt C(#5f5f5f)! M(0px) D(ib) Fw(500)",divCls:"C(#5f5f5f)! Mt(10px) Fz(1.6rem)"}));break;case"compArticleList":e.push(r.createElement(l,{key:s,config:i,infoCls:"Fz(1.6rem) Fw(500) My(6px) C(#757575)",subTxtCls:"Fz(1.3rem) Mb(4px) Mt(0px) D(i)",triTxtCls:"Fz(1.3rem) D(i) Mstart(4px)",subTxtTruncate:385,listItemCls:"Ov(a) D(b) Mt(10px)",listCls:"M(0px)",contentCls:"Ov(h) Pstart(12px) Pos(r)"}));break;case"compText":e.push(r.createElement(o,{key:s,config:i,textCls:"cite Fw(500) Pb(10px) C(#1e7d83)! D(b)",textLinkCls:"txt Fz(1.3rem)",paragraphCls:"Pb(10px)"}))}return e},[]),e="Mb(30px) Mend(20px) ",s.route.app.show_classes&&(e+=" "+this.props.className),r.createElement("div",{className:e,style:{borderBottom:"1px solid #e2e2e6"}},c)):!1}})}});[  0.267] recv DATA frame <length=1370, flags=0x00, stream_id=1>
      [ 31.256] recv DATA frame <length=0, flags=0x01, stream_id=1>
                ; END_STREAM
      [ 31.256] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
                (last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[])
      

      The problem happens when the client is SPDY or HTTP/2, the setting proxy.config.http.chunking_enabled is disabled, and there is a cache miss.

      The code that handles the logic is in HttpTransact::handle_response_keep_alive_headers :

          if (s->client_info.http_version == HTTPVersion(1, 1) && s->txn_conf->chunking_enabled == 1 &&
              // if we're not sending a body, don't set a chunked header regardless of server response
              !is_response_body_precluded(s->hdr_info.client_response.status_get(), s->method) &&
              // we do not need chunked encoding for internal error messages
              // that are sent to the client if the server response is not valid.
              (((s->source == SOURCE_HTTP_ORIGIN_SERVER || s->source == SOURCE_TRANSFORM) && s->hdr_info.server_response.valid() &&
                // if we receive a 304, we will serve the client from the
                // cache and thus do not need chunked encoding.
                s->hdr_info.server_response.status_get() != HTTP_STATUS_NOT_MODIFIED &&
                (s->current.server->transfer_encoding == HttpTransact::CHUNKED_ENCODING ||
                 // we can use chunked encoding if we cannot trust the content
                 // length (e.g. no Content-Length and Connection:close in HTTP/1.1 responses)
                 s->hdr_info.trust_response_cl == false)) ||
               // handle serve from cache (read-while-write) case
               (s->source == SOURCE_CACHE && s->hdr_info.trust_response_cl == false) ||
               // any transform will potentially alter the content length. try chunking if possible
               (s->source == SOURCE_TRANSFORM && s->hdr_info.trust_response_cl == false))) {
            s->client_info.receive_chunked_response = true;
            heads->value_append(MIME_FIELD_TRANSFER_ENCODING, MIME_LEN_TRANSFER_ENCODING, HTTP_VALUE_CHUNKED, HTTP_LEN_CHUNKED, true);
      

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                bcall Bryan Call
                Reporter:
                bcall Bryan Call
              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: