]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: checks: Add agent health check
authorSimon Horman <horms@verge.net.au>
Tue, 12 Feb 2013 01:45:54 +0000 (10:45 +0900)
committerWilly Tarreau <w@1wt.eu>
Wed, 13 Feb 2013 10:03:28 +0000 (11:03 +0100)
Support a agent health check performed by opening a TCP socket to a
pre-defined port and reading an ASCII string. The string should have one of
the following forms:

* An ASCII representation of an positive integer percentage.
  e.g. "75%"

  Values in this format will set the weight proportional to the initial
  weight of a server as configured when haproxy starts.

* The string "drain".

  This will cause the weight of a server to be set to 0, and thus it will
  not accept any new connections other than those that are accepted via
  persistence.

* The string "down", optionally followed by a description string.

  Mark the server as down and log the description string as the reason.

* The string "stopped", optionally followed by a description string.

  This currently has the same behaviour as down (iii).

* The string "fail", optionally followed by a description string.

  This currently has the same behaviour as down (iii).

A agent health check may be configured using "option lb-agent-chk".
The use of an alternate check-port, used to obtain agent heath check
information described above as opposed to the port of the service,
may be useful in conjunction with this option.

e.g.

    option  lb-agent-chk
    server  http1_1 10.0.0.10:80 check port 10000 weight 100

Signed-off-by: Simon Horman <horms@verge.net.au>
doc/configuration.txt
include/types/peers.h
include/types/proxy.h
src/cfgparse.c
src/checks.c

index df8e70c8af3a840ae55959bda3246fd1ac708f14..b6bc4207ff2123be5e40086b45ba918b46d42553 100644 (file)
@@ -1141,6 +1141,7 @@ option httpclose                     (*)  X          X         X         X
 option httplog                            X          X         X         X
 option http_proxy                    (*)  X          X         X         X
 option independent-streams           (*)  X          X         X         X
+option lb-agent-chk                       X          -         X         X
 option ldap-check                         X          -         X         X
 option log-health-checks             (*)  X          -         X         X
 option log-separate-errors           (*)  X          X         X         -
@@ -3592,9 +3593,9 @@ option httpchk <method> <uri> <version>
           option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
           server apache1 192.168.1.1:443 check port 80
 
-  See also : "option ssl-hello-chk", "option smtpchk", "option mysql-check",
-             "option pgsql-check", "http-check" and the "check", "port" and
-             "inter" server options.
+  See also : "option lb-agent-chk", "option ssl-hello-chk", "option smtpchk",
+             "option mysql-check", "option pgsql-check", "http-check" and
+             the "check", "port" and "inter" server options.
 
 
 option httpclose
@@ -3731,6 +3732,45 @@ no option independent-streams
   See also : "timeout client", "timeout server" and "timeout tunnel"
 
 
+option lb-agent-chk
+  Use a TCP connection to obtain a metric of server health
+  May be used in sections :   defaults | frontend | listen | backend
+                                 yes   |     no   |   yes  |   yes
+  Arguments : none
+
+  This alters health checking behaviour by connecting making a TCP
+  connection and reading an ASCII string. The string should have one of
+  the following forms:
+
+  * An ASCII representation of an positive integer percentage.
+     e.g. "75%"
+
+     Values in this format will set the weight proportional to the initial
+     weight of a server as configured when haproxy starts.
+
+  * The string "drain".
+
+    This will cause the weight of a server to be set to 0, and thus it will
+    not accept any new connections other than those that are accepted via
+    persistence.
+
+  * The string "down", optionally followed by a description string.
+
+    Mark the server as down and log the description string as the reason.
+
+  * The string "stopped", optionally followed by a description string.
+
+    This currently has the same behaviour as down (iii).
+
+  * The string "fail", optionally followed by a description string.
+
+    This currently has the same behaviour as down (iii).
+
+  The use of an alternate check-port, used to obtain agent heath check
+  information described above as opposed to the port of the service, may be
+  useful in conjunction with this option.
+
+
 option ldap-check
   Use LDAPv3 health checks for server testing
   May be used in sections :   defaults | frontend | listen | backend
@@ -7359,9 +7399,10 @@ check
   backend. It is possible to change the address using the "addr" parameter, the
   port using the "port" parameter, the source address using the "source"
   address, and the interval and timers using the "inter", "rise" and "fall"
-  parameters. The request method is define in the backend using the "httpchk",
-  "smtpchk", "mysql-check", "pgsql-check" and "ssl-hello-chk" options. Please
-  refer to those options and parameters for more information.
+  parameters. The request method is define in the backend using the
+  "httpchk", "lb-agent-chk", "smtpchk", "mysql-check", "pgsql-check" and
+  "ssl-hello-chk" options. Please refer to those options and parameters for
+  more information.
 
   Supported in default-server: No
 
index d52dc8c41929c1f1f8454becb82aca880f63f604..41a1cce5bfaa7495d470a5c51ecf0f5507407393 100644 (file)
@@ -72,6 +72,7 @@ struct peer {
                int line;         /* line where the section appears */
        } conf;                   /* config information */
        time_t last_change;
+       time_t last_slowstart_change;
        struct sockaddr_storage addr;  /* peer address */
        struct protocol *proto;        /* peer address protocol */
        struct xprt_ops *xprt;         /* peer socket operations at transport layer */
index ceb14d1fdcaffcece73b5f987b09c839f6f5a954..87e90ee90ea09ea27cd629fe043af007eb2636e5 100644 (file)
@@ -151,7 +151,8 @@ enum {
 #define PR_O2_MYSQL_CHK 0x50000000      /* use MYSQL check for server health */
 #define PR_O2_LDAP_CHK  0x60000000      /* use LDAP check for server health */
 #define PR_O2_SSL3_CHK  0x70000000      /* use SSLv3 CLIENT_HELLO packets for server health */
-/* unused: 0x80000000 to 0xF000000, reserved for health checks */
+#define PR_O2_LB_AGENT_CHK 0x80000000   /* use a TCP connection to obtain a metric of server health */
+/* unused: 0x90000000 to 0xF000000, reserved for health checks */
 #define PR_O2_CHK_ANY   0xF0000000      /* Mask to cover any check */
 /* end of proxy->options2 */
 
index 315e5ed3d9505c4765efd3843d3bc62babc04c85..a440301bcc303ac7fec1a235a49c7cc194c067e9 100644 (file)
@@ -3459,6 +3459,13 @@ stats_error_parsing:
                                }
                        }
                }
+               else if (!strcmp(args[1], "lb-agent-chk")) {
+                       /* use dynmaic health check */
+                       free(curproxy->check_req);
+                       curproxy->check_req = NULL;
+                       curproxy->options2 &= ~PR_O2_CHK_ANY;
+                       curproxy->options2 |= PR_O2_LB_AGENT_CHK;
+               }
                else if (!strcmp(args[1], "pgsql-check")) {
                        /* use PostgreSQL request to check servers' health */
                        if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
index 820a8c2b0d3fc9de98de73120133268aebbdb996..1a53669170b3d91998ceca726151b703327946e3 100644 (file)
@@ -25,6 +25,7 @@
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <arpa/inet.h>
+#include <stdbool.h>
 
 #include <common/chunk.h>
 #include <common/compat.h>
@@ -37,6 +38,7 @@
 
 #include <proto/backend.h>
 #include <proto/checks.h>
+#include <proto/dumpstats.h>
 #include <proto/fd.h>
 #include <proto/log.h>
 #include <proto/queue.h>
@@ -966,6 +968,55 @@ static void event_srv_chk_r(struct connection *conn)
                        set_server_check_status(s, HCHK_STATUS_L7STS, desc);
                break;
 
+       case PR_O2_LB_AGENT_CHK: {
+               short status = HCHK_STATUS_L7RSP;
+               const char *desc = "Unknown feedback string";
+               const char *down_cmd = NULL;
+
+               if (!done)
+                       goto wait_more_data;
+
+               cut_crlf(s->check.bi->data);
+
+               if (strchr(s->check.bi->data, '%')) {
+                       desc = server_parse_weight_change_request(s, s->check.bi->data);
+                       if (!desc) {
+                               status = HCHK_STATUS_L7OKD;
+                               desc = s->check.bi->data;
+                       }
+               } else if (!strcasecmp(s->check.bi->data, "drain")) {
+                       desc = server_parse_weight_change_request(s, "0%");
+                       if (!desc) {
+                               desc = "drain";
+                               status = HCHK_STATUS_L7OKD;
+                       }
+               } else if (!strncasecmp(s->check.bi->data, "down", strlen("down"))) {
+                       down_cmd = "down";
+               } else if (!strncasecmp(s->check.bi->data, "stopped", strlen("stopped"))) {
+                       down_cmd = "stopped";
+               } else if (!strncasecmp(s->check.bi->data, "fail", strlen("fail"))) {
+                       down_cmd = "fail";
+               }
+
+               if (down_cmd) {
+                       const char *end = s->check.bi->data + strlen(down_cmd);
+                       /*
+                        * The command keyword must terminated the string or
+                        * be followed by a blank.
+                        */
+                       if (end[0] == '\0' || isblank(end[0])) {
+                               status = HCHK_STATUS_L7STS;
+                               /* Skip over leading blanks */
+                               while (end[0] != '\0' && isblank(end[0]))
+                                       end++;
+                               desc = end;
+                       }
+               }
+
+               set_server_check_status(s, status, desc);
+               break;
+       }
+
        case PR_O2_PGSQL_CHK:
                if (!done && s->check.bi->i < 9)
                        goto wait_more_data;