This might help:
If you want to display your own page instead of the default error page provided by DotCloud, you have to use a few tricks.
First, note that this will only work for stacks that embed a Nginx server. For other stacks, DotCloud load balancers will be the only layer between your user and your app, and for now, it can only serve a default error page.
You need to tell Nginx to do all those things:
use a custom static page for 502 and 504 errors;
remap the error code to e.g. 500 (else, the DotCloud load balancers will serve the default 502 and 504 pages);
intercept the errors sent by the uwsgi/fastcgi (else, our custom static page won’t be used);
reduce the default timeout, so your timeout handler will kick in before the platform-wide timeout handler.
Assuming your error pages are in /static/502.html and /static/504.html, you can use the following nginx.conf snippets:
PHP:
fastcgi_read_timeout 10;
fastcgi_intercept_errors on;
error_page 502 =500 /static/502.html;
error_page 504 =500 /static/504.html;
Perl/Phython:
uwsgi_read_timeout 10;
uwsgi_intercept_errors on;
error_page 502 =500 /static/502.html;
error_page 504 =500 /static/504.html;
Ruby:
For Ruby applications, since Passenger will use error code 500, no rewriting is needed. The default Nginx configuration already provides a handler for that (errorpage 500 /static/500.html). Also, since Passenger does not expose a configuration variable to change the timeout, you cannot provide a custom 504 page.
Once you enable intercept_errors in Nginx, you can no longer generate your
own error pages for e.g. HTTP codes 500, 403, etc. You have to define static
pages for those errors in Nginx as well. This limitation will be lifted in a
future version of the services.
Source: http://docs.dotcloud.com/guides/5xx/
Otherwise, Check out this page on http://wiki.nginx.org/NginxVariableTutorialCn06 that provides a decent tutorial on it. [Although I recommend translating the page via google chrome...]
Your config is perfect, except for one little thing. You haven't specified that the health check should actually fetch the page it's requesting, and as a result the contents will be blank.
According to the HAProxy docs, option httpchk
by default uses the OPTIONS
method, which doesn't get the body of the page.
option httpchk <uri>
option httpchk <method> <uri>
option httpchk <method> <uri> <version>
Enable HTTP protocol to check on the servers health
<method>
is the optional HTTP method used with the requests. When not set, the "OPTIONS" method is used, as it generally requires low server processing and is easy to filter out from the logs. Any method may be used, though it is not recommended to invent non-standard ones.
<uri>
is the URI referenced in the HTTP requests. It defaults to " / " which is accessible by default on almost any server, but may be changed to any other URI. Query strings are permitted.
<version>
is the optional HTTP version string. It defaults to "HTTP/1.0" but some servers might behave incorrectly in HTTP 1.0, so turning it to HTTP/1.1 may sometimes help. Note that the Host field is mandatory in HTTP/1.1, and as a trick, it is possible to pass it after "\r\n" following the version string.
You have a couple of options to solve this.
You can change your method to GET
:
backend mt-http
balance roundrobin
mode http
option httpchk GET /check.aspx?appserver=dev-cluster.xxxx.com&databaseserver=test.xxxx.com&database=######dev
http-check expect string 200\ OK
server WebLB-test2 xx.xx.xx.xx:80 check
server WebLB-test1 xx.xx.xx.xx:80 check
I've tried this on my test load-balancer and it works as expected.
You can change check.aspx
to emit something other than a 200 OK
HTTP status when the checks fail.
I had once had a need to check whether a particular service was running, because IIS would always return 200 OK
even if the actual application was down on a backend. So I wrote a simple C# script to do just that:
<%@ Page Language="C#"%>
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.ServiceProcess" %>
<%@ Import Namespace="System.Net" %>
<%
ServiceController sc = new ServiceController(Request.QueryString["service"]);
switch (sc.Status)
{
case ServiceControllerStatus.Running:
Response.StatusCode = (int)HttpStatusCode.OK;
Response.ContentType = "text/plain";
Response.Write("Running");
break;
default:
Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
Response.ContentType = "text/plain";
Response.Write("Failed");
break;
}
%>
You'd use it thusly:
backend FooBar
balance roundrobin
mode http
option httpchk GET /ServiceCheck/check.aspx?service=ServiceName
http-check expect status 200
server WebLB-test2 xx.xx.xx.xx:80 check
server WebLB-test1 xx.xx.xx.xx:80 check
Best Answer
At least for apache (both 1.x and 2.x) you can try out https://github.com/kitech/mod_authnz_external. It runs an external script to handle user's credentials. This script in turn may query an external service over HTTP[s], in this case it would work similarly (not considering performance issues) to ngx_http_auth_request_module