> On Jun 24, 2019, at 22:42, Dk Jack <dnj0...@gmail.com> wrote:
> 
> Perhaps. I think we are talking two different things. I was trying to say, 
> it’s a bad idea to stall a client connection when multiple clients are 
> getting multiplexed on the same connection (between cdn and ats). From that 
> perspective, the result is the same on the client side of ats. Stalling one 
> client will cause problems for other client on that connection 


Hmm, does that happen? When a client makes a request, an origin connection is 
allocated from the pools. I don’t think two client connections can share a 
server connection at the same time; They can be reused between multiple client 
connections though.

— Leif 
> 
> Dk. 
> 
>> On Jun 24, 2019, at 9:01 PM, Sudheer Vinukonda 
>> <sudheervinuko...@yahoo.com.INVALID> wrote:
>> 
>> 
>> 
>>> On Jun 24, 2019, at 8:33 PM, Dk Jack <dnj0...@gmail.com> wrote:
>>> 
>>> I suspect connection pools would be using the http pipeline feature to
>>> multiplex multiple client connections on to the pool connections towards
>>> ATS.
>> 
>> Right. But, you can turn off the pipelining support on ATS, if there isn’t a 
>> clear benefit (particularly, true if your client is a CDN which can already 
>> leverage connection pools).
>> 
>>> In my case, rate-limiting was implemented as a security feature i.e
>>> rate-limiting malicious IPs etc. Moreover, we don't have control over it at
>>> the entry point... since most of the time we have to look at the requests
>>> at the http level (sometimes even into the bodies) to figure if we should
>>> apply rate-limiting or not...
>>> 
>>> On Mon, Jun 24, 2019 at 7:28 PM Sudheer Vinukonda
>>> <sudheervinuko...@yahoo.com.invalid> wrote:
>>> 
>>>> Interesting setup - But, wouldn’t the CDN have connection pools to ATS
>>>> already? Curious to know if enabling HTTP pipelining provides benefits
>>>> beyond what connection pools can give.
>>>> 
>>>> That said, I don’t think it makes a lot of sense to implement rate
>>>> limiting for _end clients_ in this sort of a setup. Typically, you’d want
>>>> to rate limit at the entry point of the user traffic, which means the rate
>>>> limiting for end users would be done at the CDN in this setup. You could
>>>> still add rate limiting for the CDN itself but yes in that case it makes
>>>> sense to just reject the requests and let the CDN retry.
>>>> 
>>>> @Weixi Li,
>>>> 
>>>> The more I read about your use case, it seems like you could probably
>>>> directly leverage the rate limiting that ATS core already supports (unless
>>>> you’ve other custom requirements). You can configure the below settings per
>>>> origin service in your remap config, and you should get the behavior your
>>>> use case described.
>>>> 
>>>> 
>>>> proxy.config.http.per_server.connection.max
>>>> Scope
>>>> CONFIG
>>>> Type
>>>> INT
>>>> Default
>>>> 0
>>>> Reloadable
>>>> Yes
>>>> Overridable
>>>> Yes
>>>> Set a limit for the number of concurrent connections to an upstream server
>>>> group. A value of 0 disables checking. If a transaction attempts to connect
>>>> to a group which already has the maximum number of concurrent connections
>>>> the transaction either rechecks after a delay or a 503
>>>> (HTTP_STATUS_SERVICE_UNAVAILABLE) error response is sent to the user agent.
>>>> To configure
>>>> 
>>>> Number of transactions that can be delayed concurrently
>>>> See proxy.config.http.per_server.connection.queue_size.
>>>> 
>>>> How long to delay before rechecking
>>>> See proxy.config.http.per_server.connection.queue_delay.
>>>> 
>>>> Upstream server group definition
>>>> 
>>>> 
>>>> 
>>>>> On Jun 24, 2019, at 6:58 PM, Dk Jack <dnj0...@gmail.com> wrote:
>>>>> 
>>>>> Leif,
>>>>> I was talking about the case where ATS is deployed after CDN.
>>>>> 
>>>>> client --> CDN Network -------> ATS --> Origin-Server
>>>>> 
>>>>> In most such deployments, the connection between the CDN and ATS is HTTP
>>>>> 1.1. and it is pipelined. In that case, you cannot stall the clients
>>>>> because you could run into head-of-line blocking situation.
>>>>> 
>>>>> 
>>>>>> On Mon, Jun 24, 2019 at 4:07 PM Leif Hedstrom <zw...@apache.org> wrote:
>>>>>> 
>>>>>> You definitely would not want to stall the client after you’ve made an
>>>>>> origin connection. I.e. you only want to stall the UA.
>>>>>> 
>>>>>> — Leif
>>>>>> 
>>>>>>> On Jun 24, 2019, at 14:42, Dk Jack <dnj0...@gmail.com> wrote:
>>>>>>> 
>>>>>>> Also, stalling will not be good, if you have CDN upstream from you that
>>>>>> is pipelining requests on the same connection for multiple clients. In
>>>> our
>>>>>> plugin we tried delay request, but we couldn’t solve http 1.1 pipeline
>>>>>> issue. Hence ended up going with the simple approach of deny.
>>>>>>> 
>>>>>>> Dk.
>>>>>>> 
>>>>>>>> On Jun 24, 2019, at 1:12 PM, Leif Hedstrom <zw...@apache.org> wrote:
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>>> On Jun 24, 2019, at 13:12, Weixi Li (BLOOMBERG/ PRINCETON) <
>>>>>> wli...@bloomberg.net> wrote:
>>>>>>>>> 
>>>>>>>>> Hi Dk,
>>>>>>>>> 
>>>>>>>>> Thanks a lot for the example. It is really inspiring. I have a
>>>>>> question though: in case of "bucket->consume()" returning false, the
>>>> code
>>>>>> would return a 429 response. In our use-case, we don't want to deny the
>>>>>> client with a 429 (but want to queue the request instead). How to handle
>>>>>> the false case then? Should addPlugin() add the plugin itself? (That's
>>>> why
>>>>>> I was asking about queue and async timer).
>>>>>>>> 
>>>>>>>> Oh do you want to stall the client, not deny? Depending on the plugin
>>>>>> and the hook, you can probably just reschedule the HttpSM to come back
>>>> on
>>>>>> say 500ms and try again, rather than let it continue like you normally
>>>>>> would. Have to make sure they don’t stall fore ever though, and perhaps
>>>>>> have a priority such that older clients are given tokens before new
>>>> ones.
>>>>>>>> 
>>>>>>>> Should be doable, but definitely more complex.
>>>>>>>> 
>>>>>>>> — Leif
>>>>>>>>> 
>>>>>>>>> Thanks,
>>>>>>>>> Weixi
>>>>>>>>> 
>>>>>>>>> From: dev@trafficserver.apache.org At: 06/24/19 01:28:40To:  Weixi
>>>> Li
>>>>>> (BLOOMBERG/ PRINCETON ) ,  dev@trafficserver.apache.org
>>>>>>>>> Subject: Re: Implementing Rate-limiting in forward proxy mode
>>>>>>>>> 
>>>>>>>>> Not sure you need queues. Here's a sample implementation based on
>>>>>>>>> TokenBucket which should do what you want...
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> void
>>>>>>>>> handleReadRequestHeadersPreRemap(Transaction& transaction)
>>>>>>>>> {
>>>>>>>>> std::string host;
>>>>>>>>> Headers& headers = transaction.getClientRequest().getHeaders();
>>>>>>>>> Headers::iterator ii = headers.find("Host");
>>>>>>>>> 
>>>>>>>>> if (ii != headers.end()) {
>>>>>>>>> host = (*ii).values();
>>>>>>>>> }
>>>>>>>>> 
>>>>>>>>> if (!host.empty()) {
>>>>>>>>> auto bucket = map.find(host);   // assumes u created a token bucket
>>>>>> per
>>>>>>>>> site.
>>>>>>>>>                              // std::map<std::string,
>>>>>>>>> std::shared_ptr<TokenBucket>>
>>>>>>>>>                              // map.emplace("www.cnn.com",
>>>>>>>>>                              //             std::make_shred<
>>>>>>>>> TokenBucket>(rate, burst));
>>>>>>>>>                              // rate is number of req.s/min.
>>>>>>>>>                              // burst can be same as rate.
>>>>>>>>> 
>>>>>>>>> if (bucket->consume(1)) {       // you are requesting 1 token.
>>>>>>>>> transaction.resume();
>>>>>>>>> } else {
>>>>>>>>> // see CustomResponseTransactionPlugin in atscppapi examples.
>>>>>>>>> transaction.addPlugin(new
>>>>>>>>> CustomResponseTransactionPlugin(transaction, 429,
>>>>>>>>>                      "Too Many Requests", "Too Many Requests"));
>>>>>>>>> return;
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>> 
>>>>>>>>> transaction.resume();
>>>>>>>>> }
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> On Sun, Jun 23, 2019 at 8:04 PM Weixi Li (BLOOMBERG/ PRINCETON) <
>>>>>>>>> wli...@bloomberg.net> wrote:
>>>>>>>>> 
>>>>>>>>>> Hi Dk/Eric/Leif,
>>>>>>>>>> 
>>>>>>>>>> Thanks for the advice. Our use-case simply requires sending out the
>>>>>> queued
>>>>>>>>>> requests at a fixed rate (although variable by site). My plan was
>>>>>> simply
>>>>>>>>>> put all incoming transactions in separate queues by site, and then
>>>>>> invoke
>>>>>>>>>> "transaction.resume()" at fixed interval via a timer for each queue.
>>>>>> Would
>>>>>>>>>> the delay (calling "transaction.resume()" asynchronously) disrupt
>>>> the
>>>>>> ATS
>>>>>>>>>> event processing? If yes, what's correct way to avoid that? If no,
>>>> is
>>>>>> there
>>>>>>>>>> any example plugin implementing such a timer (was thinking about
>>>>>> AsyncTimer
>>>>>>>>>> in atscppapi)?
>>>>>>>>>> 
>>>>>>>>>> The TokenBucket is a very interesting data structure, but I've not
>>>>>> figured
>>>>>>>>>> out how to apply it yet. Will look into it a bit more.
>>>>>>>>>> 
>>>>>>>>>> Thanks to Eric's point, TS_HTTP_SEND_REQUEST_HDR_HOOK will indeed be
>>>>>> too
>>>>>>>>>> late. But for this use-case the "rate-limit" only applies to
>>>>>> cache-misses
>>>>>>>>>> and revalidations (fresh cache-hits should be served as fast as
>>>>>> possible).
>>>>>>>>>> Therefore the hook probably should be
>>>>>> TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK.
>>>>>>>>>> The plugin then lets the transaction resume immediately if the cache
>>>>>> hit is
>>>>>>>>>> fresh, or queue the transaction otherwise.
>>>>>>>>>> 
>>>>>>>>>> Still learning ATS, let me know if I'm wrong. Thanks!
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> From: dev@trafficserver.apache.org At: 06/21/19 23:11:03To:  Weixi
>>>> Li
>>>>>>>>>> (BLOOMBERG/ PRINCETON ) ,  dev@trafficserver.apache.org
>>>>>>>>>> Subject: Re: Implementing Rate-limiting in forward proxy mode
>>>>>>>>>> 
>>>>>>>>>> Uhm! why async timers? You'd want to implement a leaky/token bucket
>>>>>> per
>>>>>>>>>> site. Check out...
>>>>>>>>>> 
>>>>>>>>>> https://github.com/rigtorp/TokenBucket
>>>>>>>>>> 
>>>>>>>>>> It's single header file lock free implementation for token bucket
>>>> and
>>>>>> it
>>>>>>>>>> works very well...
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> On Fri, Jun 21, 2019 at 7:38 PM Weixi Li (BLOOMBERG/ PRINCETON) <
>>>>>>>>>> wli...@bloomberg.net> wrote:
>>>>>>>>>> 
>>>>>>>>>>> What a great community! So many good tips in such a short time!
>>>>>>>>>>> 
>>>>>>>>>>> Especially the atscppai, I would've never noticed it. the async
>>>>>> examples
>>>>>>>>>>> look very promising.
>>>>>>>>>>> 
>>>>>>>>>>> It looks like the following might be necessary (let me know if I'm
>>>>>>>>>> wrong):
>>>>>>>>>>> * A hook to TS_HTTP_SEND_REQUEST_HDR_HOOK
>>>>>>>>>>> * A map of queues (one queue per rate-limited site)
>>>>>>>>>>> * A map of async timers (one timer per queue)
>>>>>>>>>>> 
>>>>>>>>>>> I will study the ATS code more to understand the event and
>>>> threading
>>>>>>>>>> model
>>>>>>>>>>> better.
>>>>>>>>>>> 
>>>>>>>>>>> Thank you all.
>>>>>>>>>>> 
>>>>>>>>>>> From: dev@trafficserver.apache.org At: 06/21/19 19:52:44To:
>>>>>>>>>>> dev@trafficserver.apache.org
>>>>>>>>>>> Subject: Re: Implementing Rate-limiting in forward proxy mode
>>>>>>>>>>> 
>>>>>>>>>>> I have implemented rate-limit in my plugin using atscppapi. We are
>>>>>> using
>>>>>>>>>>> ats in
>>>>>>>>>>> security context for mitigation. If the request matches certain
>>>>>> criteria
>>>>>>>>>>> (ip,
>>>>>>>>>>> method, host, uri and header values) then we apply rate-limit to
>>>>>> that ip.
>>>>>>>>>>> 
>>>>>>>>>>> Dk.
>>>>>>>>>>> 
>>>>>>>>>>>> On Jun 21, 2019, at 3:15 PM, Leif Hedstrom <zw...@apache.org>
>>>>>> wrote:
>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>>> On Jun 21, 2019, at 16:09, Weixi Li (BLOOMBERG/ PRINCETON)
>>>>>>>>>>> <wli...@bloomberg.net> wrote:
>>>>>>>>>>>>> 
>>>>>>>>>>>>> Hi team,
>>>>>>>>>>>>> 
>>>>>>>>>>>>> We are experimenting with ATS in *forward* proxy mode. Our
>>>> use-case
>>>>>>>>>>> requires
>>>>>>>>>>> a rate-limiting component that enforces rules based on the
>>>>>> destination.
>>>>>>>>>>>>> 
>>>>>>>>>>>>> For example:
>>>>>>>>>>>>> 
>>>>>>>>>>>>> For all incoming requests targeting "www.cnn.com", we want to
>>>>>> limit
>>>>>>>>>>> the
>>>>>>>>>>> outgoing rate to be 10 requests per minute; for "www.reddit.com",
>>>> we
>>>>>>>>>> want
>>>>>>>>>>> the
>>>>>>>>>>> rate to be 20 requests per minute; and so on. If there were more
>>>>>> requests
>>>>>>>>>>> than
>>>>>>>>>>> the limit specified, the requests must be queued before they could
>>>> go
>>>>>>>>>> out.
>>>>>>>>>>>> 
>>>>>>>>>>>> Seems very straight forward to implement as a plugin. For example
>>>>>> the
>>>>>>>>>>> geo_acl
>>>>>>>>>>> plugin might be a good start, since it limits access based on
>>>> source
>>>>>> IP.
>>>>>>>>>>>> 
>>>>>>>>>>>> Would be interesting to hear more about your use case too, it’s
>>>>>> always
>>>>>>>>>>> exciting to hear about different solutions that people use ATS for.
>>>>>> Maybe
>>>>>>>>>>> at
>>>>>>>>>>> the next ATS summit? :-)
>>>>>>>>>>>> 
>>>>>>>>>>>> Cheers,
>>>>>>>>>>>> 
>>>>>>>>>>>> — Leif
>>>>>>>>>>>>> 
>>>>>>>>>>>>> Is it possible to implement this requirement using a plugin?
>>>>>>>>>>>>> 
>>>>>>>>>>>>> If not, we wouldn't mind forking the code and modifying whichever
>>>>>>>>>> parts
>>>>>>>>>>> that
>>>>>>>>>>> would be necessary. But which are the potentially relevant
>>>>>> components?
>>>>>>>>>>>>> 
>>>>>>>>>>>>> If any experts could give us some pointers on the design, that
>>>>>> would
>>>>>>>>>> be
>>>>>>>>>>> really appreciated.
>>>>>>>>>>>>> 
>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>> Weixi
>>>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>> 
>>>>>> 
>>>>>> 
>>>> 
>> 

Reply via email to