Hey all,

I wanted to enforce an SLA on certain http requests to apache.
Essentially provide a the external client users an guarantee that a
valid response will be given within XXms and all errors are
suppressed.  This is for an ReST API that returns JSON or XML data.

Ronald Park attempted to do something similar for Apache 2.0 in Feb
2008 here: http://bit.ly/HglyS

The issues with making apache do this are as follows:

    * ProxyTimeout is global or scoped to the particular vhost
    * ErrorDocuments still return the error code (503, 404, etc)
    * No way to tie ErrorDocuments and ProxyTimeouts to particular requests.

I followed Ronald's lead and reimplemented in apache 2.2 with a few
new additions.
The below example is a rewrite rule that makes no changes to the URL
itself for a JS API presumably returning data in JSON.

RewriteRule ^/api/(.*).js\?*(.*)$ http://backendproxy/api/$1.js?$2
[P,QSA,E=proxy-timeout:900ms,E=error-suppress:true,E=error-headers:/errorapi.js.HTTP,E=error-document:/errorapi.js]

With the SLA enforcement modifications enabled, the URL will return
data from the backend system within 900ms or a timeout occurs. At this
point apache will stop waiting for the backend response and serve back
the static files /errorapi.js.HTTP as HTTP headers and /errorapi.js as
contents.

$cat /var/www/html/errorapi.js.HTTP
Status: 204
Content-type: application/javascript

$cat /var/www/html/errorapi.js
var xxx_api_data={data:[]}; /* ERR */

There are four environment variables the SLA hack looks for:

    * proxy-timeout: - time in seconds or milliseconds to wait until timing out
    * error-suppress: - true/false switch on suppressing all non 2xx
errors from the backend.
    * error-headers: - file of syntax correct HTTP headers to return
to the client
    * error-document: - file of content body to be returned to the client

Leaving off the proxy-timeout will only suppress errors from the
backend after the global timeout occurs. Leaving off
error-suppress:true will ensure that the 5xx timeout error from
mod_proxy_http is returned intact to the client.

Code here: http://github.com/nealrichter/mod_proxy_http_sla/tree
Diff here: http://bit.ly/UdAHB
Blog Post: 
http://aicoder.blogspot.com/2009/07/hacking-apaches-modproxyhttp-to-enforce.html

Please examine and comment.. it's on production servers handling
approx of 50Million API hits per day.. no issues thus far.  I'd like
some feedback if I'm resetting the timeout back to the previous one on
the socket correctly and if there is a better way to do this in the
code.   I essentially used Ronald's code plus some stuff from
mod_asis.

Thanks - Neal Richter

Reply via email to