使用haproxy,我想要:
现在我有一个后端,“主”服务器有一个荒谬的高权重,它“工作”。
acl use_backend + connslots是沿着正确的路线,但没有在我自己的答案补丁是不完美的。
奖金点不需要修改haproxy二进制。
正确的方法是在前端添加一个ACL来检查服务器上的连接数量,然后根据这个数据做出决定。
下面的configuration将检查“monitor_conns”前端,如果有500个或更多的连接,它们将被发送到“备份”后端,否则将进入“常规”后端。
这是一个未经testing的例子:
frontend monitor_conns bind *:80 acl too_many_conns fe_conn 500 use_backend backups if too_many_conns default_backend regular backend backups ... your config server backupsrv 192.168.0.101:80 check port 80 maxconn 1000 inter 1s rise 1 fall 1 backend regular ... your config server regularsrv 192.168.0.100:80 check port 80 maxconn 500 inter 1s rise 1 fall 1
这只是一个例子,但它应该给你一个如何进行的想法。
老问题,但我面临同样的问题,这里是我的解决scheme:
您可以使用acl检查前端conn,并使用具有额外服务器的后端,即指您的备份服务器
所以configuration看起来像这样
frontend frontend1 127.0.0.1:9200 mode tcp acl max_conn_reached fe_conn gt 15 acl production_almost_dead nbsrv(prod1) lt 2 default_backend prod1 use_backend prod1_and_prod2 if max_conn_reached OR production_almost_dead backend prod1 mode tcp balance leastconn server se_prod1 127.0.0.1:8001 check maxconn 10 server se_prod2 127.0.0.1:8002 check maxconn 10 backend prod1_and_prod2 mode tcp balance leastconn server se_prod1 127.0.0.1:8001 check maxconn 10 server se_prod2 127.0.0.1:8002 check maxconn 10 server se_backup1 127.0.0.1:8003 check maxconn 10 server se_backup2 127.0.0.1:8004 check maxconn 10
如果前端连接大于15或后端1上的一个服务closures,则前端将使用备份服务器(与生产服务器一起)
以下似乎为我工作,但它已经需要修补haproxy-1.4.15 / src / backend.c:
# diff haproxy-1.4.15/src/backend.c backend.c 1298a1299,1333 > /* set test->i to the number of enabled servers on the proxy */ > static int > acl_fetch_connfree(struct proxy *px, struct session *l4, void *l7, int dir, > struct acl_expr *expr, struct acl_test *test) > { > struct server *iterator; > test->flags = ACL_TEST_F_VOL_TEST; > if (expr->arg_len) { > /* another proxy was designated, we must look for it */ > for (px = proxy; px; px = px->next) > if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->arg.str)) > break; > } > if (!px) > return 0; > > test->i = 0; > iterator = px->srv; > while (iterator) { > if ((iterator->state & SRV_RUNNING) == 0) { > iterator = iterator->next; > continue; > } > if (iterator->maxconn == 0) { > test->i = -1; > return 1; > } > > test->i += (iterator->maxconn - (iterator->cur_sess + iterator->nbpend)); > iterator = iterator->next; > } > > return 1; > } > 1461a1497 > { "connfree", acl_parse_int, acl_fetch_connfree, acl_match_int, ACL_USE_NOTHING },
然后我可以在我的acl中使用connfree :
frontend frontend1 bind *:12345 acl main_full connfree(main) eq 0 use_backend backup if main_full default_backend main backend main balance leastconn default-server maxconn 1 maxqueue 1 server main2 10.0.0.1:12345 check server main1 10.0.0.2:12345 check backend backup balance leastconn default-server maxconn 1 maxqueue 1 server backup1 10.0.1.1:12345 check server backup2 10.0.1.2:12345 check
希望将acl_fetch_connfree()与acl_fetch_connslots()进行比较将会使更改变得明显:
旧=(maxconn – 当前conns)+(maxqueue – 等待conns)
new = maxconn – (当前conns +等待conns)
在后端部分使用“备份”参数
frontend my-frontend *:9091 #arbitrary name for the frontend maxconn 500 default_backend my-backend backend my-backend mode http option httpchk server solr-1 10.30.3.100:9091 weight 1 maxconn 500 check server solr-2 10.30.3.101:9091 weight 1 maxconn 500 check backup
如果solr-1失败了httpchk,solr-2就会接pipe。