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