Det initiala användningsmönstret är en "sandwich"-liknande struktur, där vår applikation befinner sig mellan de två HAProxy-lagren. All inkommande trafik går genom HAProxy, vilket ger skydd, SSL-terminering och loggning, medan min app inte exponeras för omvärlden (den lyssnar vanligtvis bara på localhost/loopback). Utöver det går all utgående (serverinitierad) trafik också genom HAProxy (databasmaterial, Redis/Memcached, anslutning till andra HTTP-tjänster, loggning).
global log stderr local0 debug log 127.0.0.1:514 len 8192 format rfc5424 local1 debug ... defaults log global mode http option httplog clf option dontlognull option forwardfor # healthchecks option httpchk default-server check inter 1s fall 5 downinter 2s rise 5 # timeouts timeout connect 5s timeout client 10s timeout server 10s timeout http-request 1s listen myapp http-check send meth GET uri /health bind :80 bind :443 ssl crt /path/to/dir/with/certs/ alpn h2,http/1.1 server myapp01 127.0.0.1:8080 check maxconn 32 listen myservice bind 127.0.0.1:8081 server myservice01 1.2.3.4:443 ssl verify required ca-file CA_chain.pemHAProxy erbjuder en mycket omfattande uppsättning alternativ för HTTP-serverövervakning. Du kan konfigurera regelbundna kontrollintervall, ändra kontrollintervall när tjänsten är i övergång eller nere, skriva dina egna kontroller med binär nyttolast eller använda Lua API för att skriva komplicerade kontroller.
Vi har också konfigurerat HTTP-åtkomstloggar i Common Log Format (tänk på Apache och Nginx), tillgängliga utan prestandakostnader eller behovet av att skapa HTTP-loggar från din applikation.
Den kan också ge skydd direkt från olika typer av attacker som Slowloris (bara genom att den kan framtvinga olika timeouts). Eller så kan den förhindra överbelastning av din tjänst genom att hålla koll på antalet samtidiga anslutningar ( maxconn ).
Vi har också lagt till en fiktiv tjänst, som vi kan ansluta till lokalt via vanlig HTTP, och HAProxy konverterar den till korrekt HTTPS, med certifikatkontroll (ofta använder man självsignerade certifikat för interna tjänster, och det är svårt att få det att fungera med applikationskod).
Även när man arbetar med en enda PostgreSQL-server är det skönt att inte behöva oroa sig för databasens plats ur appens synvinkel, vi vill låtsas att databasen alltid finns på localhost . Att lägga till lite motståndskraft med HAProxy är också väldigt enkelt, lägg bara till en annan (backup)server.
listen pgsql mode tcp option pgsql-check postgres_user bind 127.0.0.1:5432 server primary 10.0.0.1:5432 check server secondary 10.0.0.2:5432 check backupSom du kan se kan HAProxy direkt kontrollera PostgreSQL-tillgänglighet, vilket är bättre än att bara testa TCP-porttillgänglighet. Om något händer med den första servern kommer den att försöka dirigera trafik till den andra "backup"-servern. Utan att ändra en enda kodrad i din applikation har du ökat tillförlitligheten och tillgängligheten!
Vi kommer inte att gå in på alltför många detaljer om hur man konfigurerar PostgreSQL-replikering här go . Men vi kan varmt rekommendera att använda kombinationenreprmgrochbarman(ellerpgBackRestför stora databaser). Det säger väl allt.
När man ska köra flera PostgreSQL-servrar för redundans , vill man ofta använda replikservrar för skrivskyddade frågor (dvs. "läsrepliker"), eftersom en stor andel av frågorna bara är enkla val (t.ex. 75 %/25 % för läsning/skrivning). Om man kan ordna sin applikationskod så att den använder två anslutningar (eller två uppsättningar autentiseringsuppgifter) för läsning/skrivning, kan HAProxy ta hand om detaljerna, routing, redundans etc.
lyssna pgsql_ro mode tcp balance leastconn # om du tillåter läsanslutning till master # använd bara standard: option pgsql-check postgres_user option external-check external-check command /path/to/check_pg_in_recovery.sh default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions bind 127.0.0.1:6432 server pg1 10.0.0.1:5432 check maxconn 100 server pg2 10.0.0.2:5432 check maxconn 100 server pg3 10.0.0.3:5432 check maxconn 100 server pg4 10.0.0.4:5432 check maxconn 100 listen pgsql_rw mode tcp option external-check external-check command** /path/to/check_pg_not_in_recovery.sh default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions bind 127.0.0.1:7432 server pg1 10.0.0.1:5432 check maxconn 100 server pg2 10.0.0.2:5432 check maxconn 100 server pg3 10.0.0.3:5432 check maxconn 100 server pg4 10.0.0.4:5432 check maxconn 100Detta är redan en kraftfull konfiguration som använder en pool med fyra servrar. En av servrarna är "primär", medan andra är "i återställning" (dvs. spelar upp Write Ahead-loggen och tillämpar databastransaktioner från huvudservern). De kan fortfarande hantera skrivskyddade förfrågningar från servern.
Vi använder ett externt kontrollskript för att köra det enkla SQL-uttrycket: "SELECT pg_is_in_recovery()". HAProxy tillhandahåller nödvändiga miljövariabler för att rikta in sig på rätt server. Det finns andra sätt att köra kontrollen, HAProxy använder binärkod för kontroller , så du kan (miss)använda det till din fördel. Även om du inte känner till PostgreSQL-protokollet kan du spela in detta utbyte med tcpdump och översätta det till HAProxy-konfigurationen. Bara för skojs skull har vi implementerat något liknande med Lua (TBD).
En enkel check_pg_in_recovery.sh kan se ut så här (använd .pgpass fil för användarnamn/lösenord):
#!/bin/sh HOST="$3" PORT="$4" DATABASE="checkdb" IN_RECOVERY="$( /usr/bin/psql -t -h $HOST -p $PORT -d $DATABASE -c 'select pg_is_in_recovery();' )" if [ "$VALUE" = " t" ]; then exit 0 else exit 1 fiEtt sista steg för denna HAProxy-installation är att lära vår applikationskod att kommunicera med databasen via två anslutningar, eller simulera en anslutning till två databaser, som den här implementeringen av multidatabase-idén för Django. pg_bouncer är ett utmärkt verktyg som hjälper dig med detta. pg_bouncer känner också till många coola PostgreSQL-knep, som PAUSE-kommandot, där du kan utföra transparent serveromstart eller redundansövergång, utan driftstopp.
Sist men inte minst finns det en intressant pg_bouncer-fork från AWS, som kan användas för att dirigera frågor enligt anpassade regler (t.ex. när du inte kan ändra din app, men vill dela upp läsningar och skrivningar).
Uppsatsen Club Sandwich + Double PostgreSQL är en del av en serie "recept" som utforskar sätt att bygga pålitliga applikationer med (HA)Proxy.
PS. Om du har några frågor om någon av ovanstående tankar, dela dem gärna i kommentarsfältet.
Klicka här för att läsa del 2. : TLS Calzone + Wrap Crispy JWT — Autentisering på gränsen