HAProxy检查不检查IIS上的内容

我是HAproxy的新手,我已经阅读了Googlesearch的每一个可能的短语,但我不能让haproxy阅读我的testing页返回的内容。

这里的设置:单臂configuration – 1x CentOS 7 haproxy 1.5.14 – 2个Windows Server 2012r2 IIS 8.5

后端服务器configuration:

backend mt-http balance roundrobin mode http option httpchk /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 

check.aspx通过指定的应用程序服务器集群连接到特定的数据库,以确认从Web服务器到数据库的端到端连接。 如果testing成功,则检查在网页中以文本forms返回200 OK。 如果其中一个组件不可用,check.aspx会返回一个500错误。 成功:

  <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title> Mediatools Check </title></head> <body id="bodyID">200 OK</body> </html> 

失败:

  <html xmlns="http://www.w3.org/1999/xhtml"> <head><title> Mediatools Check </title></head> <body id="bodyID">500 Internal Server Error</body> </html> 

当我使用选项“http-check expect string 200 \ OK”(我已经尝试过,并且没有string中的“\”转义字符),服务器显示出来,错误是“Layer 7 Invalid Response:http content check发现空响应的身体。“

当我使用选项“http-check expect status 200 OK”时,无论状态文本是否为200,返回页面都是成功的(因为我认为即使返回500代码,check.aspx的返回也是成功的)。

任何帮助将不胜感激。

这是curl -v的输出:看起来也许我的请求太长了?

  curl -v xx.xx.xx.xx/yourDB/check.aspx?appserver=dev-cluster.yourdomain.com&databaserver=test.yourdomain.com&database=yourDBdev [1] 16077 [2] 16078 [root@dev-cluster log]# * About to connect() to xx.xx.xx.xx port 80 (#0) * Trying xx.xx.xx.xx... * Connected to xx.xx.xx.xx (xx.xx.xx.xx) port 80 (#0) > GET /customer/check.aspx?appserver=dev-cluster.yourdomain.com HTTP/1.1 > User-Agent: curl/7.29.0 > Host: xx.xx.xx.xx > Accept: */* > < HTTP/1.1 500 Internal Server Error < Cache-Control: private < Content-Type: text/html; charset=utf-8 < Server: Microsoft-IIS/8.5 < X-AspNet-Version: 4.0.30319 < X-UA-Compatible: IE=EmulateIE7 < Date: Wed, 17 Feb 2016 22:16:59 GMT < Content-Length: 3428 < <!DOCTYPE html> <html> <head> <title>Runtime Error</title> <meta name="viewport" content="width=device-width" /> <style> body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;} p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px} b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px} H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red } H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon } pre {font-family:"Consolas","Lucida Console",Monospace;font-size:11pt;margin:0;padding:0.5em;line-height:14pt} .marker {font-weight: bold; color: black;text-decoration: none;} .version {color: gray;} .error {margin-bottom: 10px;} .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; } @media screen and (max-width: 639px) { pre { width: 440px; overflow: auto; white-space: pre-wrap; word-wrap: break-word; } } @media screen and (max-width: 479px) { pre { width: 280px; } } </style> </head> <body bgcolor="white"> <span><H1>Server Error in '/customer' Application.<hr width=100% size=1 color=silver></H1> <h2> <i>Runtime Error</i> </h2></span> <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif "> <b> Description: </b>An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine. <br><br> <b>Details:</b> To enable the details of this specific error message to be viewable on remote machines, please create a &lt;customErrors&gt; tag within a &quot;web.config&quot; configuration file located in the root directory of the current web application. This &lt;customErrors&gt; tag should then have its &quot;mode&quot; attribute set to &quot;Off&quot;.<br><br> <table width=100% bgcolor="#ffffcc"> <tr> <td> <code><pre> &lt;!-- Web.Config Configuration File --&gt; &lt;configuration&gt; &lt;system.web&gt; &lt;customErrors mode=&quot;Off&quot;/&gt; &lt;/system.web&gt; &lt;/configuration&gt;</pre></code> </td> </tr> </table> <br> <b>Notes:</b> The current error page you are seeing can be replaced by a custom error page by modifying the &quot;defaultRedirect&quot; attribute of the application's &lt;customErrors&gt; configuration tag to point to a custom error page URL.<br><br> <table width=100% bgcolor="#ffffcc"> <tr> <td> <code><pre> &lt;!-- Web.Config Configuration File --&gt; &lt;configuration&gt; &lt;system.web&gt; &lt;customErrors mode=&quot;RemoteOnly&quot; defaultRedirect=&quot;mycustompage.htm&quot;/&gt; &lt;/system.web&gt; &lt;/configuration&gt;</pre></code> </td> </tr> </table> <br> </body> </html> * Connection #0 to host xx.xx.xx.xx left intact [1]- Done curl -v xx.xx.xx.xx/customer/check.aspx?appserver=dev-cluster.yourdomain.com [2]+ Done databaserver=test.yourdomain.com 

好的,再来一次! 我让Web开发人员从web.config中取出appserver,databaseserver和database参数,而不是将它们发送到check.aspx

新的configuration如下所示:

  backend mt-http balance roundrobin mode http option httpchk GET /customer/check.aspx http-check expect status 200 OK server WebLB-test2 xx.xx.xx.xx:80 check server WebLB-test1 xx.xx.xx.xx:80 check 

Curl新的回报:

  curl -v xx.xx.xx.xx/pgglobal/check.aspx * About to connect() to xx.xx.xx.xx port 80 (#0) * Trying xx.xx.xx.xx... * Connected to xx.xx.xx.xx (xx.xx.xx.xx) port 80 (#0) > GET /customer/check.aspx HTTP/1.1 > User-Agent: curl/7.29.0 > Host: xx.xx.xx.xx > Accept: */* > < HTTP/1.1 200 OK < Cache-Control: private < Content-Type: text/html; charset=utf-8 < Server: Microsoft-IIS/8.5 < Set-Cookie: ASP.NET_SessionId=whvmaboyg03lsl3rd1gcsbxl; path=/; secure; HttpOnly < X-AspNet-Version: 4.0.30319 < X-UA-Compatible: IE=EmulateIE7 < Date: Wed, 17 Feb 2016 23:00:07 GMT < Content-Length: 162 < <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title> Happiness Check </title></head> <body id="bodyID">Success</body> </html> * Connection #0 to host xx.xx.xx.xx left intact 

haproxy仍然报告“第7层错误状态:HTTP状态检查返回<500>”

这是一个失败的check.aspx上的curl输出(其中一个选中的组件被closures以强制错误页面)。

  curl -v xx.xx.xx.xx/Customer/check.aspx * About to connect() to xx.xx.xx.xx port 80 (#0) * Trying xx.xx.xx.xx... * Connected to xx.xx.xx.xx (xx.xx.xx.xx) port 80 (#0) > GET /Customer/check.aspx HTTP/1.1 > User-Agent: curl/7.29.0 > Host: xx.xx.xx.xx > Accept: */* > < HTTP/1.1 500 Internal Server Error < Cache-Control: private < Content-Type: text/html; charset=utf-8 < Server: Microsoft-IIS/8.5 < X-AspNet-Version: 4.0.30319 < X-UA-Compatible: IE=EmulateIE7 < Date: Thu, 18 Feb 2016 17:17:01 GMT < Content-Length: 3428 < <!DOCTYPE html> <html> <head> <title>Runtime Error</title> <meta name="viewport" content="width=device-width" /> <style> body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;} p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px} b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px} H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red } H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon } pre {font-family:"Consolas","Lucida Console",Monospace;font-size:11pt;margin:0;padding:0.5em;line-height:14pt} .marker {font-weight: bold; color: black;text-decoration: none;} .version {color: gray;} .error {margin-bottom: 10px;} .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; } @media screen and (max-width: 639px) { pre { width: 440px; overflow: auto; white-space: pre-wrap; word-wrap: break-word; } } @media screen and (max-width: 479px) { pre { width: 280px; } } </style> </head> <body bgcolor="white"> <span><H1>Server Error in '/Customer' Application.<hr width=100% size=1 color=silver></H1> <h2> <i>Runtime Error</i> </h2></span> <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif "> <b> Description: </b>An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine. <br><br> <b>Details:</b> To enable the details of this specific error message to be viewable on remote machines, please create a &lt;customErrors&gt; tag within a &quot;web.config&quot; configuration file located in the root directory of the current web application. This &lt;customErrors&gt; tag should then have its &quot;mode&quot; attribute set to &quot;Off&quot;.<br><br> <table width=100% bgcolor="#ffffcc"> <tr> <td> <code><pre> &lt;!-- Web.Config Configuration File --&gt; &lt;configuration&gt; &lt;system.web&gt; &lt;customErrors mode=&quot;Off&quot;/&gt; &lt;/system.web&gt; &lt;/configuration&gt;</pre></code> </td> </tr> </table> <br> <b>Notes:</b> The current error page you are seeing can be replaced by a custom error page by modifying the &quot;defaultRedirect&quot; attribute of the application's &lt;customErrors&gt; configuration tag to point to a custom error page URL.<br><br> <table width=100% bgcolor="#ffffcc"> <tr> <td> <code><pre> &lt;!-- Web.Config Configuration File --&gt; &lt;configuration&gt; &lt;system.web&gt; &lt;customErrors mode=&quot;RemoteOnly&quot; defaultRedirect=&quot;mycustompage.htm&quot;/&gt; &lt;/system.web&gt; &lt;/configuration&gt;</pre></code> </td> </tr> </table> <br> </body> </html> * Connection #0 to host xx.xx.xx.xx left intact 

你的configuration是完美的,除了一件小事。 您尚未指定运行状况检查实际上应该获取正在请求的页面,因此内容将为空白。

根据HAProxy 文档 , option httpchk默认使用OPTIONS方法,该方法不会获得页面的主体。

选项httpchk <uri>
选项httpchk <method> <uri>
选项httpchk <方法> <uri> <version>

启用HTTP协议来检查服务器的运行状况

<方法>
是与请求一起使用的可选HTTP方法。 未设置时,使用“OPTIONS”方法,因为它通常需要较低的服务器处理,并且很容易从日志中筛选出来。 任何方法都可以使用,但不build议发明非标准方法。

<URI>
是HTTP请求中引用的URI。 它默认为“/”,几乎在任何服务器上默认都可以访问,但是可以改成任何其他的URI。 查询string是允许的。

<版本>
是可选的HTTP版本string。 它默认为“HTTP / 1.0”,但有些服务器可能在HTTP 1.0中的行为不正确,因此将其转换为HTTP / 1.1有时可能有所帮助。 请注意,Host字段在HTTP / 1.1中是必需的,作为一个技巧,可以在版本string后面的“\ r \ n”之后传递它。

你有几个select来解决这个问题。

  1. 您可以将您的方法更改为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 

    我已经在我的testing负载平衡器上尝试过了,它按预期工作。

  2. 当检查失败时,您可以更改check.aspx以发出除了200 OK HTTP状态之外的其他内容。
    我曾经有一次需要检查一个特定的服务是否正在运行,因为即使实际的应用程序停在后端,IIS总是会返回200 OK 。 所以我写了一个简单的C#脚本来做到这一点:

     <%@ 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; } %> 

    你会这样使用它:

     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