]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MINOR] check: add redis check support
authorHervé COMMOWICK <vr@exosec.fr>
Fri, 5 Aug 2011 14:23:48 +0000 (16:23 +0200)
committerWilly Tarreau <w@1wt.eu>
Sat, 6 Aug 2011 13:52:47 +0000 (15:52 +0200)
This patch provides a new "option redis-check" statement to enable server health checks based on redis PING request (http://www.redis.io/commands/ping).

doc/configuration.txt
include/common/defaults.h
include/types/proxy.h
src/cfgparse.c
src/checks.c

index d2f75a7ab3e09447b495109a57c2d883eecc4b09..f4c1692e524db7f9e908e1ec593b9f72e4b8ce20 100644 (file)
@@ -1003,6 +1003,7 @@ option nolinger                      (*)  X          X         X         X
 option originalto                         X          X         X         X
 option persist                       (*)  X          -         X         X
 option redispatch                    (*)  X          -         X         X
+option redis-check                        X          -         X         X
 option smtpchk                            X          -         X         X
 option socket-stats                  (*)  X          X         X         -
 option splice-auto                   (*)  X          X         X         X
@@ -3754,6 +3755,23 @@ no option redispatch
   See also : "redispatch", "retries", "force-persist"
 
 
+option redis-check
+  Use redis health checks for server testing
+  May be used in sections :   defaults | frontend | listen | backend
+                                 yes   |    no    |   yes  |   yes
+  Arguments : none
+
+  It is possible to test that the server correctly talks REDIS protocol instead
+  of just testing that it accepts the TCP connection. When this option is set,
+  a PING redis command is sent to the server, and the response is analyzed to
+  find the "+PONG" response message.
+
+  Example :
+        option redis-check
+
+  See also : "option httpchk"
+
+
 option smtpchk
 option smtpchk <hello> <domain>
   Use SMTP health checks for server testing
index 96e0f61b4e3a7eefdbd1858e8452cd8928a65f30..0a4f42068f7f739e204918e0a94bafe12cb6e49a 100644 (file)
 #define DEF_CHECK_REQ   "OPTIONS / HTTP/1.0\r\n"
 #define DEF_SMTP_CHECK_REQ   "HELO localhost\r\n"
 #define DEF_LDAP_CHECK_REQ   "\x30\x0c\x02\x01\x01\x60\x07\x02\x01\x03\x04\x00\x80\x00"
+#define DEF_REDIS_CHECK_REQ  "*1\r\n$4\r\nPING\r\n"
 
 #define DEF_HANA_ONERR         HANA_ONERR_FAILCHK
 #define DEF_HANA_ERRLIMIT      10
index 82c345821aebed09e796ad95d8f1dd95f6d92fce..b4385a9854012fac23b59141690a75a16c0c7cea 100644 (file)
@@ -155,6 +155,7 @@ enum {
 #define PR_O2_PGSQL_CHK 0x10000000      /* use PGSQL check for server health */
 #define PR_O2_DISPATCH  0x20000000      /* use dispatch mode */
 #define PR_O2_NODELAY   0x40000000      /* fully interactive mode, never delay outgoing data */
+#define PR_O2_REDIS_CHK 0x80000000      /* use LDAP check for server health */
 /* end of proxy->options2 */
 
 /* bits for sticking rules */
index 04373acf6e77c9f79aceb425cd8777557b49bce9..44fc1dabd96e20e40224de786deb98494a4b1e33 100644 (file)
@@ -3260,6 +3260,7 @@ stats_error_parsing:
                        curproxy->options2 &= ~PR_O2_MYSQL_CHK;
                        curproxy->options2 &= ~PR_O2_PGSQL_CHK;
                        curproxy->options2 &= ~PR_O2_LDAP_CHK;
+                       curproxy->options2 &= ~PR_O2_REDIS_CHK;
                        curproxy->options |= PR_O_HTTP_CHK;
                        if (!*args[2]) { /* no argument */
                                curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
@@ -3293,6 +3294,7 @@ stats_error_parsing:
                        curproxy->options2 &= ~PR_O2_MYSQL_CHK;
                        curproxy->options2 &= ~PR_O2_PGSQL_CHK;
                        curproxy->options2 &= ~PR_O2_LDAP_CHK;
+                       curproxy->options2 &= ~PR_O2_REDIS_CHK;
                        curproxy->options2 |= PR_O2_SSL3_CHK;
                }
                else if (!strcmp(args[1], "smtpchk")) {
@@ -3304,6 +3306,7 @@ stats_error_parsing:
                        curproxy->options2 &= ~PR_O2_MYSQL_CHK;
                        curproxy->options2 &= ~PR_O2_PGSQL_CHK;
                        curproxy->options2 &= ~PR_O2_LDAP_CHK;
+                       curproxy->options2 &= ~PR_O2_REDIS_CHK;
                        curproxy->options |= PR_O_SMTP_CHK;
 
                        if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
@@ -3334,6 +3337,7 @@ stats_error_parsing:
                        curproxy->options &= ~PR_O_SMTP_CHK;
                        curproxy->options2 &= ~PR_O2_SSL3_CHK;
                        curproxy->options2 &= ~PR_O2_LDAP_CHK;
+                       curproxy->options2 &= ~PR_O2_REDIS_CHK;
                        curproxy->options2 &= ~PR_O2_MYSQL_CHK;
                        curproxy->options2 |= PR_O2_PGSQL_CHK;
 
@@ -3386,6 +3390,26 @@ stats_error_parsing:
                        }
                }
 
+               else if (!strcmp(args[1], "redis-check")) {
+                       /* use REDIS PING request to check servers' health */
+                       if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
+                               err_code |= ERR_WARN;
+
+                       free(curproxy->check_req);
+                       curproxy->check_req = NULL;
+                       curproxy->options &= ~PR_O_HTTP_CHK;
+                       curproxy->options &= ~PR_O_SMTP_CHK;
+                       curproxy->options2 &= ~PR_O2_SSL3_CHK;
+                       curproxy->options2 &= ~PR_O2_MYSQL_CHK;
+                       curproxy->options2 &= ~PR_O2_PGSQL_CHK;
+                       curproxy->options2 &= ~PR_O2_LDAP_CHK;
+                       curproxy->options2 |= PR_O2_REDIS_CHK;
+
+                       curproxy->check_req = (char *) malloc(sizeof(DEF_REDIS_CHECK_REQ) - 1);
+                       memcpy(curproxy->check_req, DEF_REDIS_CHECK_REQ, sizeof(DEF_REDIS_CHECK_REQ) - 1);
+                       curproxy->check_len = sizeof(DEF_REDIS_CHECK_REQ) - 1;
+               }
+
                else if (!strcmp(args[1], "mysql-check")) {
                        /* use MYSQL request to check servers' health */
                        if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
@@ -3397,6 +3421,7 @@ stats_error_parsing:
                        curproxy->options &= ~PR_O_SMTP_CHK;
                        curproxy->options2 &= ~PR_O2_SSL3_CHK;
                        curproxy->options2 &= ~PR_O2_LDAP_CHK;
+                       curproxy->options2 &= ~PR_O2_REDIS_CHK;
                        curproxy->options2 &= ~PR_O2_PGSQL_CHK;
                        curproxy->options2 |= PR_O2_MYSQL_CHK;
 
@@ -3469,6 +3494,7 @@ stats_error_parsing:
                        curproxy->options2 &= ~PR_O2_SSL3_CHK;
                        curproxy->options2 &= ~PR_O2_MYSQL_CHK;
                        curproxy->options2 &= ~PR_O2_PGSQL_CHK;
+                       curproxy->options2 &= ~PR_O2_REDIS_CHK;
                        curproxy->options2 |= PR_O2_LDAP_CHK;
 
                        curproxy->check_req = (char *) malloc(sizeof(DEF_LDAP_CHECK_REQ) - 1);
index 5bcf47c5d4666329ac7f203ec26ea7b8724e3271..50fe2a2048daf487b5e7647fba3b8719040bcfdb 100644 (file)
@@ -773,6 +773,7 @@ static int event_srv_chk_w(int fd)
                    (s->proxy->options2 & PR_O2_SSL3_CHK) ||
                    (s->proxy->options2 & PR_O2_MYSQL_CHK) ||
                    (s->proxy->options2 & PR_O2_PGSQL_CHK) ||
+                   (s->proxy->options2 & PR_O2_REDIS_CHK) ||
                    (s->proxy->options2 & PR_O2_LDAP_CHK)) {
                        int ret;
                        const char *check_req = s->proxy->check_req;
@@ -1047,6 +1048,17 @@ static int event_srv_chk_r(int fd)
                        set_server_check_status(s, HCHK_STATUS_L7STS, desc);
                }
        }
+       else if (s->proxy->options2 & PR_O2_REDIS_CHK) {
+               if (!done && s->check_data_len < 7)
+                       goto wait_more_data;
+
+               if (strcmp(s->check_data, "+PONG\r\n") == 0) {
+                       set_server_check_status(s, HCHK_STATUS_L7OKD, "Redis server is ok");
+               }
+               else {
+                       set_server_check_status(s, HCHK_STATUS_L7STS, s->check_data);
+               }
+       }
        else if (s->proxy->options2 & PR_O2_MYSQL_CHK) {
                if (!done && s->check_data_len < 5)
                        goto wait_more_data;