Use backups se não estiver disponível (não apenas abaixo)

6

Usando o haproxy, eu quero:

  • Um pool de servidores 'principais' e servidores de 'backup', embora eles não precisem necessariamente estar em pools separados.
  • Cada backend tem um 'maxconn' baixo (neste caso 1)
  • Os clientes não devem esperar em uma fila. Se não houver servidores imediatamente disponíveis no pool 'principal', eles devem ser desviados para o pool de 'backup' sem demora.

Agora eu tenho um backend, servidores 'principais' têm um peso absurdamente alto e 'funciona'.

acl use_backend + connslots está nas linhas certas, mas sem o patch na minha própria resposta não é perfeito.

Pontos de bônus por não requerer um binário haproxy modificado.

    
por PriceChild 05.07.2011 / 16:38

4 respostas

1

O seguinte parece funcionar para mim, mas foi necessário corrigir o 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 },

Posso usar connfree na minha acl:

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

Espero que a comparação de acl_fetch_connfree() a acl_fetch_connslots() torne óbvia a mudança:

old = (maxconn - conns atuais) + (maxqueue - conns pendentes)

new = maxconn - (conns atuais + conns pendentes)

    
por 08.07.2011 / 13:00
7

A maneira correta é adicionar uma ACL no frontend que verifica a quantidade de conexões no servidor e, em seguida, toma uma decisão com base nisso.

A configuração abaixo irá verificar o front-end "monitor_conns" e se houver 500 ou mais conexões, elas serão enviadas para o back-end "backups", caso contrário elas irão para o backend "normal".

Veja um exemplo não testado :

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

É apenas um exemplo, mas deve dar uma ideia de como proceder.

    
por 07.07.2011 / 01:33
5

Pergunta antiga, mas enfrento o mesmo problema e eis a minha solução:

Você pode verificar o front end conn usando acl e usar back-end que tenha um servidor extra para isso servidor extra Quero dizer seu servidor de backup

Assim, a configuração ficará assim

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

O front end usará o servidor de backup (junto com o servidor de produção) se a conexão no frontend for maior que 15 ou um serviço no backend1 está inativo

    
por 27.07.2012 / 19:11
-1

use o parâmetro "backup" na seção de back-end

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

se o solr-1 falhar o httpchk, o solr-2 assumirá.

    
por 06.07.2011 / 23:10

Tags