Skip to content

Conversation

zaharidichev
Copy link
Member

@zaharidichev zaharidichev commented Jul 18, 2019

This PR's purpose is to remove maxRequestKB maxResponseKB and rely on finagle's maximum allowed size for fixed size messages which is 2GB. The semantics now are:

  • Fixed size messages (Content-Length set) are allowed up to 2GB and will be streamed if they are above the threshold specified in streamAfterContentLengthKB. Note that id these messages are larger than 2GB or have their Content-Length set to a larger value they will be rejected.
  • Chunk encoded messages (Transfer-Encoding: chunked`) will always be streamed.
  • Streaming messages (Content-Length not set) will be streamed.

Fixes: #2196
Signed-off-by: Zahari Dichev zaharidichev@gmail.com

@koiuo
Copy link
Contributor

koiuo commented Jul 18, 2019

I think that we can deprecate maxRequestKB and maxResponseKB and just set them to the highest possible value that we can and not expose them to the user.

IMO, these may still be useful, but semantics must change.
One of the benefits of the service mesh is that it handles some common communication features for services and lets services be simpler. As a minimum service mesh offers service discovery and load balancing. In the case of linkerd this also includes retries, circuit breaking, etc.. Limiting request and response sizes fits here very well.

However to be useful maxRequestKB and maxResponseKB must work not only for non-chunked (in your terminology, thanks for describing this btw) messages but for the other 2 categories too. This will require some development, likely even a contribution to finagle.

Your idea to remove those is very pragmatic. But there may be existing linkerd users who rely on maxRequestKB and maxResponseKB as a protective measure for their services.

Alternatively we can try to submit a patch to finagle to allow lifting that 2GB threshold higher

+1 for this. I believe, there's no good reason to have 2GiB hard limit in finagle now after support for streaming of fixed-length messages is implemented.

Copy link
Contributor

@koiuo koiuo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it makes sense to also describe/illustrate with tests how all these settings (fixedLengthStreamedAfter, maxRequestKB, etc.) impact messages with huge headers?

It has been a long time since I looked into this code, and I apologize if the question is silly... But I have never managed to memorize, whether request size in this context refers to the length of the HTTP message body or to the whole HTTP message including headers.

@zaharidichev
Copy link
Member Author

@edio Thanks for your comments. To be completely frank, all of this terminology is quite confusing and not documented very well at all, so it was quite the can of warms to look through that stuff. I agree with you about most what you said and will probably investigate the headers bit as well. I think the relationship will be somewhat similar to what it is between fixedLengthStreamedAfter and maxRequestKB

With respect to making maxRequestKB work with all sorts of messages, I am not sure whether this is easy/possible at all. If you think about it in order to classify a message as being over the size limit you either need to have Content-Length header or buffer it entirely, which makes it a not streamed message... Nevertheless will discuss more with the rest of the team and let you know :)

@koiuo
Copy link
Contributor

koiuo commented Jul 18, 2019

With respect to making maxRequestKB work with all sorts of messages, I am not sure whether this is easy/possible at all. If you think about it in order to classify a message as being over the size limit you either need to have Content-Length header or buffer it entirely, which makes it a not streamed message... Nevertheless will discuss more with the rest of the team and let you know :)

I may be very off here (and can't check right now), but IIRC this is technically feasible with netty: a handler has a counter which we increment with every frame transferred by the size of the frame. Once the counter reaches the limit we abort the transmission and return 413. Obviously there may be something special about how the handler is added to netty pipeline or how the counter is declared so we count only our own message... I do not recall technicall details, but I do believe this is possible.

I will try to look into it later today.

@zaharidichev
Copy link
Member Author

@edio Yes, you are right, thinking about it it is quite possible to do that in such a way. I am not too familiar with the finagle/netty codebase but sounds like its possible. Will investigate what we can do (and when)

@adleong
Copy link
Member

adleong commented Jul 18, 2019

Thanks to @zaharidichev and @edio for all of the investigation you have done on this. It's great to finally get some clarity on the behavior of these parameters.

If I understand correctly, the only time the maxRequestKB parameter has any effect is for non-chunked requests with a Content-Length which is larger than maxRequestKB but smaller than streamAfterContentLengthKB. Is that correct?

If so, that's pretty niche and I agree with @zaharidichev's original suggestion of removing maxRequestKB and maxResponseKB.

The original purpose of these parameters was to protect Linkerd from excessive buffering and memory pressure from large messages. I think the streamAfterContentLengthKB accomplishes this in a much more graceful way.

It is true that having the functionality of having the service mesh limit message sizes could be useful. But that's not functionality we have today (because the maxRequestKB don't limit chucked messages) so I think we should decouple the work of clarifying our existing functionality from the work of adding new functionality.

@edio: if you think limiting message size is a useful feature, would you mind opening an issue with details about how you think it should work?

@koiuo
Copy link
Contributor

koiuo commented Jul 18, 2019

@adleong at NCBI we do not use this feature of linkerd, it was just my assumption, that some developers may use it; my only concern was breaking a feature some potentially may be using.
I do not have any incentive to push for this feature, that's why I personally would be fine with maxRequestKB and maxResponseKB gone.

Sorry for confusion.

@zaharidichev
Copy link
Member Author

zaharidichev commented Jul 18, 2019

@adleong

If I understand correctly, the only time the maxRequestKB parameter has any effect is for non-chunked requests with a Content-Length which is larger than maxRequestKB but smaller than streamAfterContentLengthKB. Is that correct?

Not exactly... (ammended my code comments to reflect things better)This is where it gets merky. So if there is Content-Length set and it is larger than maxRequestKB (or than 2GB which is the default set in Finagle), the request will not be processed... To me this behavior is not correct, as it means that you can not have in practice a request with known content length that is larger than 2GB, simply because this is hardecoded in finagle. This is the bit we might want changed in finagle. We can drop our maxRequestKB but until finagle changes to always stream after the fixedLengthStreamedAfter we cannot process fixed size messages larger than 2GB.

My suggestion is do get rid of maxRequestKB and maxResponseKB and rely on finagle's hard bounds and fixedLengthStreamedAfter and submit an issue to finagle that will allow for fixed sized messages to ALWAYS be streamed after the threshold of fixedLengthStreamedAfter. I think this is the best course of action. Alternatively we can leave things as they are. At least now we know what is what. Nevertheless it is worth submitting an issue to finagle just to get more clarity and to verify our understanding (will do that).

@zaharidichev zaharidichev force-pushed the zd/streamFixedAfter-clarification branch from 18d3b0e to 84b0784 Compare July 18, 2019 19:48
@adleong
Copy link
Member

adleong commented Jul 18, 2019

Sounds good to me!

Signed-off-by: Zahari Dichev <zaharidichev@gmail.com>
@zaharidichev
Copy link
Member Author

@adleong Added a commit to proceed as discussed. Also submitted this issue to finagle to clarify things further

@zaharidichev zaharidichev force-pushed the zd/streamFixedAfter-clarification branch 3 times, most recently from 1462494 to eaff078 Compare July 19, 2019 10:49
Signed-off-by: Zahari Dichev <zaharidichev@gmail.com>
@zaharidichev zaharidichev force-pushed the zd/streamFixedAfter-clarification branch from eaff078 to f517a6e Compare July 19, 2019 11:55
Copy link
Member

@adleong adleong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice

@adleong
Copy link
Member

adleong commented Jul 19, 2019

Would you mind updating the PR title and description to match the changes?

@zaharidichev zaharidichev changed the title [DNM] Clarify the behaviour of maxRequestKB and maxResponseKB Remove maxRequestKB maxResponseKB and set finagle's maxRequestSize and maxResponseSize to max allowed(2GB) Jul 21, 2019
@adleong adleong merged commit 9026195 into linkerd:master Jul 24, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Revise maxRequestKB and maxResponseKB meaning after #2189
3 participants