mirror of
https://github.com/haproxy/haproxy.git
synced 2026-04-04 00:25:08 -04:00
MEDIUM: tcpcheck/server: Add healthcheck server keyword
Thanks to this patch, it is now possible to specify an healthcheck section on the server line. In that case, the server will use the tcpcheck as defined in the correspoding healthcheck section instead of the proxy's one.
This commit is contained in:
parent
89da4e7d6e
commit
b49200ca31
5 changed files with 168 additions and 1 deletions
|
|
@ -18561,6 +18561,18 @@ hash-key <key>
|
|||
uses "hash-type consistent", and the quality of the distribution will depend
|
||||
on the quality of the keys.
|
||||
|
||||
healthchec <name>
|
||||
May be used in the following contexts: tcp, http
|
||||
|
||||
Specify the health-check sectino to use to perform check on the server.
|
||||
|
||||
Argument :
|
||||
<name> is the health-check section name.
|
||||
|
||||
Thanks to this option, it is possible to use a pre-server health-check
|
||||
configuration instead of using the proxy configuration. See also "healthcheck
|
||||
section".
|
||||
|
||||
id <value>
|
||||
May be used in the following contexts: tcp, http, log
|
||||
|
||||
|
|
@ -32251,6 +32263,81 @@ Example:
|
|||
map virt@acme
|
||||
|
||||
|
||||
12.9. Healthchecks
|
||||
------------------
|
||||
|
||||
It is possible to globally declare several health-checks that could be used by
|
||||
servers across all the configuration, overriding the local proxy configuration.
|
||||
|
||||
healthcheck <name>
|
||||
Created a new healthcheck with name <name>. This name must be unique. It
|
||||
should be used on server line to reference a specific health-check section.
|
||||
|
||||
type <type>
|
||||
Defines the health-check type. This parameter is mandatory. Following types
|
||||
of health-check are supported:
|
||||
|
||||
* tcp-check
|
||||
* httpchk
|
||||
* ssl-hello-chk
|
||||
* smtpchk
|
||||
* pgsql-check
|
||||
* redis-check
|
||||
* mysql-check
|
||||
* ldap-check
|
||||
* spop-check
|
||||
|
||||
Each type uses the same parameters, if any, than the corresponding proxy's
|
||||
option. For instance, the method, the uri... may be speficied for the
|
||||
"httpchk" type:
|
||||
|
||||
Examples :
|
||||
healthcheck my-http-check
|
||||
type httpchk GET /health HTTP/1.1 %[srv_name]
|
||||
|
||||
See also : "option tcp-check", "option httpchk", "option ssl-hello-chk",
|
||||
"option smtpchk", "option mysql-check", "option pgsql-check",
|
||||
"option redis-check", "option ldap-check and "option spop-check"
|
||||
|
||||
http-check comment <string>
|
||||
http-check connect [default] [port <expr>] [addr <ip>] [send-proxy]
|
||||
[via-socks4] [ssl] [sni <sni>] [alpn <alpn>] [linger]
|
||||
[proto <name>] [comment <msg>]
|
||||
http-check disable-on-404
|
||||
http-check expect [min-recv <int>] [comment <msg>]
|
||||
[ok-status <st>] [error-status <st>] [tout-status <st>]
|
||||
[on-success <fmt>] [on-error <fmt>] [status-code <expr>]
|
||||
[!] <match> <pattern>
|
||||
http-check send [meth <method>] [{ uri <uri> | uri-lf <fmt> }>] [ver <version>]
|
||||
[hdr <name> <fmt>]* [{ body <string> | body-lf <fmt> }]
|
||||
[comment <msg>]
|
||||
http-check send-state
|
||||
http-check set-var(<var-name>[,<cond>...]) <expr>
|
||||
http-check set-var-fmt(<var-name>[,<cond>...]) <fmt>
|
||||
http-check unset-var(<var-name>)
|
||||
Add a specific http-check rule for a "httpchk" healthcheck. The same syntax
|
||||
than the corresponding proxy's directives is used. See the corresponding proxy
|
||||
documentation for details.
|
||||
|
||||
tcp-check comment <string>
|
||||
tcp-check connect [default] [port <expr>] [addr <ip>] [send-proxy] [via-socks4]
|
||||
[ssl] [sni <sni>] [alpn <alpn>] [linger]
|
||||
[proto <name>] [comment <msg>]
|
||||
tcp-check expect [min-recv <int>] [comment <msg>]
|
||||
[ok-status <st>] [error-status <st>] [tout-status <st>]
|
||||
[on-success <fmt>] [on-error <fmt>] [status-code <expr>]
|
||||
[!] <match> <pattern>
|
||||
tcp-check send <data> [comment <msg>]
|
||||
tcp-check send-lf <fmt> [comment <msg>]
|
||||
tcp-check send-binary <hexstring> [comment <msg>]
|
||||
tcp-check send-binary-lf <hexfmt> [comment <msg>]
|
||||
tcp-check set-var(<var-name>[,<cond>...]) <expr>
|
||||
tcp-check set-var-fmt(<var-name>[,<cond>...]) <fmt>
|
||||
tcp-check unset-var(<var-name>)
|
||||
Add a specific tcp-check rule for a "tcp-check" healthcheck. The same syntax
|
||||
than the corresponding proxy's directives is used. See the corresponding proxy
|
||||
documentation for details.
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* fill-column: 79
|
||||
|
|
|
|||
|
|
@ -248,6 +248,7 @@ struct tcpcheck_ruleset {
|
|||
|
||||
struct tcpcheck {
|
||||
struct tcpcheck_ruleset *rs; /* The tcp-check ruleset to use */
|
||||
char *healthcheck; /* name of the healthcheck section (NULL if not used) */
|
||||
struct list preset_vars; /* The list of variable to preset before executing the ruleset */
|
||||
unsigned int flags; /* TCPCHECK_FL_* */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1552,8 +1552,9 @@ void free_check(struct check *check)
|
|||
* done for health-check : the proxy is the owner of the rules / vars
|
||||
* in this case.
|
||||
*/
|
||||
if (check->state & CHK_ST_AGENT) {
|
||||
if (check->state & CHK_ST_AGENT || check->tcpcheck->healthcheck) {
|
||||
free_tcpcheck_vars(&check->tcpcheck->preset_vars);
|
||||
ha_free(&check->tcpcheck->healthcheck);
|
||||
ha_free(&check->tcpcheck);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2537,6 +2537,10 @@ int proxy_finalize(struct proxy *px, int *err_code)
|
|||
|
||||
srv_minmax_conn_apply(newsrv);
|
||||
|
||||
*err_code |= check_server_tcpcheck(newsrv);
|
||||
if (*err_code & (ERR_ABORT|ERR_FATAL))
|
||||
goto out;
|
||||
|
||||
/* this will also properly set the transport layer for
|
||||
* prod and checks
|
||||
* if default-server have use_ssl, prerare ssl init
|
||||
|
|
|
|||
|
|
@ -4164,6 +4164,35 @@ static int check_proxy_tcpcheck(struct proxy *px)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int check_server_tcpcheck(struct server *srv)
|
||||
{
|
||||
struct tcpcheck_ruleset *rs;
|
||||
int err_code = 0;
|
||||
|
||||
if (srv->check.tcpcheck->healthcheck) {
|
||||
rs = find_tcpcheck_ruleset(srv->check.tcpcheck->healthcheck);
|
||||
if (!rs) {
|
||||
ha_alert("parsing [%s:%d]: healthcheck section '%s' not found for server '%s'.\n",
|
||||
srv->conf.file, srv->conf.line, srv->check.tcpcheck->healthcheck, srv->id);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
if (!dup_tcpcheck_vars(&srv->check.tcpcheck->preset_vars, &rs->conf.preset_vars)) {
|
||||
ha_alert("parsing [%s:%d]: unable to duplicate preset variables for server '%s'.\n",
|
||||
srv->conf.file, srv->conf.line, srv->id);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
srv->check.tcpcheck->rs = rs;
|
||||
srv->check.tcpcheck->flags = rs->conf.flags;
|
||||
|
||||
err_code = check_tcpcheck_ruleset(srv->proxy, rs);
|
||||
}
|
||||
|
||||
out:
|
||||
return err_code;
|
||||
}
|
||||
|
||||
void deinit_proxy_tcpcheck(struct proxy *px)
|
||||
{
|
||||
free_tcpcheck_vars(&px->tcpcheck.preset_vars);
|
||||
|
|
@ -5920,6 +5949,43 @@ int cfg_post_parse_healthchecks()
|
|||
return err_code;
|
||||
}
|
||||
|
||||
/* Parse the "healthcheck" server keyword */
|
||||
static int srv_parse_healthcheck(char **args, int *cur_arg, struct proxy *curpx, struct server *srv,
|
||||
char **errmsg)
|
||||
{
|
||||
int err_code = 0;
|
||||
|
||||
if (!*args[*cur_arg+1]) {
|
||||
memprintf(errmsg, "'%s' expects a healthcheck name as argument.", args[*cur_arg]);
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (srv->check.tcpcheck->healthcheck) {
|
||||
/* a healthcheck section was already defined. Replace it */
|
||||
ha_free(&srv->check.tcpcheck->healthcheck);
|
||||
}
|
||||
else {
|
||||
srv->check.tcpcheck = calloc(1, sizeof(*srv->check.tcpcheck));
|
||||
if (srv->check.tcpcheck == NULL) {
|
||||
memprintf(errmsg, "out of memory");
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
LIST_INIT(&srv->check.tcpcheck->preset_vars);
|
||||
}
|
||||
|
||||
if (!memprintf(&srv->check.tcpcheck->healthcheck, "*healthcheck-%s", args[*cur_arg+1])) {
|
||||
ha_free(&srv->check.tcpcheck);
|
||||
memprintf(errmsg, "out of memory");
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static struct cfg_kw_list cfg_kws = {ILH, {
|
||||
{ CFG_LISTEN, "http-check", proxy_parse_httpcheck },
|
||||
{ CFG_LISTEN, "tcp-check", proxy_parse_tcpcheck },
|
||||
|
|
@ -5932,3 +5998,11 @@ REGISTER_POST_DEINIT(deinit_tcpchecks);
|
|||
INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
|
||||
|
||||
REGISTER_CONFIG_SECTION("healthcheck", cfg_parse_healthchecks, cfg_post_parse_healthchecks);
|
||||
|
||||
/* register "server" line keywords */
|
||||
static struct srv_kw_list srv_kws = { "CHK", { }, {
|
||||
{ "healthcheck", srv_parse_healthcheck, 1, 1, 1 }, /* The healthcheck section to use */
|
||||
{ NULL, NULL, 0 },
|
||||
}};
|
||||
|
||||
INITCALL1(STG_REGISTER, srv_register_keywords, &srv_kws);
|
||||
|
|
|
|||
Loading…
Reference in a new issue