My modification is based on version 1.4.16.

===============================================in struct server add 
following===============================================
char vgroup_name[100];
struct proxy *vgroup; //if not NULL, means this is a Virtual GROUP

===============================================in function process_chk() add at 
line 1198===============================================
if (s->vgroup) {
if ((s->vgroup->lbprm.tot_weight > 0) && !(s->state & SRV_RUNNING)) {
s->health = s->rise;
set_server_check_status(s, HCHK_STATUS_L4OK, "vgroup ok");
set_server_up(s);
} else if (!(s->vgroup->lbprm.tot_weight > 0) && (s->state & SRV_RUNNING)) {
s->health = s->rise;
set_server_check_status(s, HCHK_STATUS_HANA, "vgroup has no available server");
set_server_down(s);
}

if (s->state & SRV_RUNNING) {
s->health = s->rise + s->fall - 1;
set_server_check_status(s, HCHK_STATUS_L4OK, "vgroup ok");
}

while (tick_is_expired(t->expire, now_ms))
t->expire = tick_add(t->expire, MS_TO_TICKS(s->inter));
return t;
}

===============================================in function assign_server() add 
at line 622===============================================
if (s->srv->vgroup) {
struct proxy *old = s->be;
s->be = s->srv->vgroup;
int ret = assign_server(s);
s->be = old;
return ret;
}

===============================================in function cfg_parse_listen() 
add at line 3949===============================================
else if (!defsrv && !strcmp(args[cur_arg], "vgroup")) {
if (!args[cur_arg + 1]) {
Alert("parsing [%s:%d] : '%s' : missing virtual_group name.\n",
file, linenum, newsrv->id);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
if (newsrv->addr.sin_addr.s_addr) {
//for easy indicate
Alert("parsing [%s:%d] : '%s' : virtual_group requires the server address as 
0.0.0.0\n",
file, linenum, newsrv->id);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
newsrv->check_port = 1;
strlcpy2(newsrv->vgroup_name, args[cur_arg + 1], sizeof(newsrv->vgroup_name));
cur_arg += 2;
}

===============================================in function 
check_config_validdity() add at line 
5680================================================
/*
 * set vgroup if necessary
 */
newsrv = curproxy->srv;
while (newsrv != NULL) {
if (newsrv->vgroup_name[0] != '\0') {
struct proxy *px = findproxy(newsrv->vgroup_name, PR_CAP_BE);
if (px == NULL) {
Alert("[%s][%s] : vgroup '%s' not exist.\n", curproxy->id, newsrv->id, 
newsrv->vgroup_name);
err_code |= ERR_ALERT | ERR_FATAL;
break;
}
newsrv->vgroup = px;
}
newsrv = newsrv->next;
}

======================================================================================

and some minor changes in function stats_dump_proxy() that not important.

======================================================================================

sample config file looks like:

backend internallighttpd
    option httpchk /monitor/ok.htm
    server wsqa 0.0.0.0 vgroup subproxy1 weight 32 check inter 4000 rise 3 fall 
3
    server wsqb 0.0.0.0 vgroup subproxy2 weight 32 check inter 4000 rise 3 fall 
3
    balance uri
    hash-type consistent
    option redispatch
    retries 3

backend subproxy1
    option httpchk /monitor/ok.htm
    server wsq01 1.1.1.1:8001 weight 32 check inter 4000 rise 3 fall 3
    server wsq02 1.1.1.2:8001 weight 32 check inter 4000 rise 3 fall 3
    balance roundrobin
    option redispatch
    retries 3

backend subproxy2
    option httpchk /monitor/ok.htm
    server wsq03 1.1.1.1:8002 weight 32 check inter 4000 rise 3 fall 3
    server wsq04 1.1.1.2:8002 weight 32 check inter 4000 rise 3 fall 3
    balance roundrobin
    option redispatch
    retries 3

======================================================================================

Sorry I can't provide a clean patch, because vgroup is just one of several 
changes.
I did not consider the rewrite rules at that time. Maybe we can add a function 
call before calling assigen_server()?


From: Willy Tarreau
Date: 2011-11-30 01:47
To: wsq003
CC: Rerngvit Yanggratoke; haproxy; Baptiste
Subject: Re: Re: hashing + roundrobin algorithm
On Tue, Nov 29, 2011 at 02:56:49PM +0800, wsq003 wrote:
> 
> Backend proxies may be multiple layers, then every layer can have its own LB 
> param.
> Logically this is a tree-like structure, every real server is a leaf. Every 
> none-leaf node is a backend proxy and may have LB param.

I clearly understand what it looks like from the outside. It's still not very
clear how you *concretely* implemented it. Maybe you basically did what I've
been planning for a long time (the internal server) and then your code could
save us some time.

A feature I found important there was to be able to apply backend rewrite rules
again when selecting a new backend as a server. This is the only way I found to
be able to perform outgoing rewrites.

> When a HTTP request arrives, it go through the tree-like structure to find a 
> proper real server.
> 
> It would be better if official version can provide this feature.

Care to post your code so that we can comment on something real ? :-)

Cheers,
Willy

Reply via email to