From ec032d63a68582cb16055c9bb589b3dc50bf144b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20COMMOWICK?= Date: Fri, 5 Aug 2011 16:23:48 +0200 Subject: [PATCH] [MINOR] check: add redis check support 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 | 18 ++++++++++++++++++ include/common/defaults.h | 1 + include/types/proxy.h | 1 + src/cfgparse.c | 26 ++++++++++++++++++++++++++ src/checks.c | 12 ++++++++++++ 5 files changed, 58 insertions(+) diff --git a/doc/configuration.txt b/doc/configuration.txt index d2f75a7ab..f4c1692e5 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -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 Use SMTP health checks for server testing diff --git a/include/common/defaults.h b/include/common/defaults.h index 96e0f61b4..0a4f42068 100644 --- a/include/common/defaults.h +++ b/include/common/defaults.h @@ -131,6 +131,7 @@ #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 diff --git a/include/types/proxy.h b/include/types/proxy.h index 82c345821..b4385a985 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -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 */ diff --git a/src/cfgparse.c b/src/cfgparse.c index 04373acf6..44fc1dabd 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -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); diff --git a/src/checks.c b/src/checks.c index 5bcf47c5d..50fe2a204 100644 --- a/src/checks.c +++ b/src/checks.c @@ -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;