Helathcheck on multiple backends with virtual hostnames

I have 2 backends which are running on two different virtual host names and need to perform healthchecks on them to loadbalance the traffic.

issue is : only the last healthcheck (prd03) works , not prd02. How I can do healthcheck against 2 virtual hostnames?

here is my config:
backend xxxx.searchCustomer
mode http
balance roundrobin
option httpchk GET /env HTTP/1.1\r\nHost:\ customerlookup.xxx.px-prd02.cf.xxxx.com:443\r\n
option httpchk GET /env HTTP/1.1\r\nHost:\ customerlookup.xxx.px-prd03.cf.xxxx.com:443\r\n
http-check expect rstatus ^200
option httplog
timeout server 60s
default-server inter 10s fall 3 rise 2
server s_CustomerLookupService.searchCustomer2 customerlookup.xxx.px-prd02.cf.xxxx.com:443 check resolvers dns ssl verify none
server s_CustomerLookupService.searchCustomer3 customerlookup.xxx.px-prd03.cf.xxxx.com:443 check resolvers dns ssl verify none

any help please? or point in right direction? basically , I should be able to pass the different hostnames in HK calls

Are you sure “:443” can be part of a hostname?

Yes- we have this working when i have one server in backend server list- but when we added one more server, we are unable to do healthcheck.

In my case I have multiple backends (Tomcats) all configured with the same virtual hosts and:

backend app1
option http
…
option httpchk GET /rest/util/setting HTTP/1.0\r\nHost:\ app1.virtualhosttomcat.local:8080\r\n
…
server talaiaclu01-app1 192.168.211.13:8080 cookie server1 maxconn 1000 check inter 5000
server talaiaclu02-app1 192.168.211.14:8080 cookie server2 maxconn 1000 check inter 5000

Behaviour seems to send this check with same header to each server. So in my scenario, different than yours, it’s working. Maybe you can achieve this approache in your scenario.

Reards,

It’s a strange requirement to use different Host headers for the backend servers, when they are serving in the same backend and the same services.

How does your customer connect to the backend application, when your backend server requires different Host header and haproxy load-balances?

You could probably workaround this by not health checking in the actual backend but outsource the healthcheck to dedicated backends (with the track directive).

My Backend servers are deployed in cloudfoundry and as per cloudfoundry- only way to route traffic to an app is using the virtual hostname:

In Cloud Foundry, a hostname is the label that indicates a subdomain of the domain associated with the route. Given a domain shared-domain.example.com, a developer can create the route myapp.shared-domain.example.com in space my-space by specifying the hostname myapp with the cf create-route command as shown in this example:

$ cf create-route my-space shared-domain.example.com --hostname myapp
Creating route myapp.shared-domain.example.com for org my-org / space my-space as username@example.com…
OK
This command instructs Cloud Foundry to only route requests to apps mapped to this route for the following URLs:

http://myapp.shared-domain.example.com
https://myapp.shared-domain.example.com
Any path under either of the above URLs, such as http://myapp.shared-domain.example.com/bar

@lukastribus- I didn’t understand how to outsource the HK to dedicated backend. would appreciate if you can share a sample.

Thanks in advance.

I think this thread could help my requirement- trying to understand it :slight_smile:

https://www.mail-archive.com/haproxy@formilux.org/msg17321.html

Perhaps there can only be one healthcheck per backend, and HAProxy is using the last one you defined. I wonder why, if you have two backends, you don’t define two backends, iso. one backend with two servers.

If I create two backends- all my request goto first backend- because I’m routing based on SOAP Action in acl.

Is it really a strange requirement? pivotal Cloudfoundry routes traffic based on virtual hostname and this is a big issue we are facing in production.

I’m routing based on SOAP Action in acl.

Show that part of your config.

That I understood. What I do not understand is how you expect your customers host header to be different for one server as opposed to another when haproxy is load balancing to different servers?

More specifically, how is the browser/app-client/customer supposed to send customerlookup.xxx.px-prd02.cf.xxxx.com:443 for one server and customerlookup.xxx.px-prd03.cf.xxxx.com:443 for the other?

I’m sure you have a valid use-case, I just not understand it yet.

It would look like this for example:

backend check_customerlookup.xxx.px-prd02.cf.xxxx.com
 option httpchk GET /env HTTP/1.1\r\nHost:\ customerlookup.xxx.px-prd02.cf.xxxx.com:443\r\n
 server prd02 192.168.211.13:8080 cookie server1 maxconn 1000 check inter 5000

backend check_customerlookup.xxx.px-prd03.cf.xxxx.com
 option httpchk GET /env HTTP/1.1\r\nHost:\ customerlookup.xxx.px-prd03.cf.xxxx.com:443\r\n
 server prd03 192.168.211.14:8080 cookie server1 maxconn 1000 check inter 5000

backend app1
 server talaiaclu01-app1 192.168.211.13:8080 cookie server1 maxconn 1000 track check_customerlookup.xxx.px-prd02.cf.xxxx.com/prd02
 server talaiaclu02-app1 192.168.211.14:8080 cookie server2 maxconn 1000 track check_customerlookup.xxx.px-prd03.cf.xxxx.com/prd03
1 Like

here is my config , when i have one server in backend.

Clients talk to https://:8003 and if SOAPAction is “searchCustomer”- it will be routed to searchCustomer backend and then routed to server “customerlookup.xxx.px-prd02.cf.xxxx.com:443”.

Notice, I’m doing healthcheck using virtual hostname. Now my requirement is to add another server to same backend (customerlookup.xxx.px-prd02.cf.xxxx.com:443).

listen http_frontend
mode http
option http-buffer-request
bind *:8003 ssl crt /var/prod/data/esp/HAProxy/xxx.pem

acl CustomerLookupService.searchCustomer hdr_sub(SOAPAction) “searchCustomer”
use_backend CustomerLookupService.searchCustomer if CustomerLookupService.searchCustomer

backend CustomerLookupService.searchCustomer
mode http
balance roundrobin
option httpchk GET /env HTTP/1.1\r\nHost:\ customerlookup-xxx.apps.px-prd02.cf.xxx.com:443\r\n
http-check expect rstatus ^200
default-server inter 1s fall 3 rise 1
http-request set-header Host customerlookup-xxx.apps.px-prd02.cf.xxx.com:443
server s_CustomerLookupService.searchCustomer2 customerlookup.xxx.px-prd02.cf.xxxx.com:443 check resolvers dns ssl verify none

You didn’t actually respond to my question, but the snippet I shared above already shows how you can achieve healthchecks in this way.

Thank You @lukastribus. Your solution is working for me. Thank you for all the help. here is the latest config, which solved the issue. but I do have a curious question (no complains though!). We can close this issue for now.

Thank you @lukastribus, @ghp and @txalamar for your insights.

  1. is there an opportunity to concise this configuration? now for each backend, I have to write two additional healthcheck backends ( and this might go up, if my infra adds another environment). ?

68 Opertaion: CustomerLookupService.searchCustomer

acl CustomerLookupService.searchCustomer hdr_sub(SOAPAction) "searchCustomer"
use_backend CustomerLookupService.searchCustomer if CustomerLookupService.searchCustomer

backend check_CustomerLookupService.searchCustomer_02
option httpchk GET /env HTTP/1.1\r\nHost:\ customerlookup-xxx.apps.px-prd02.cf.xxxx.com:443\r\n
http-check expect rstatus ^200
default-server inter 1s fall 3 rise 1
http-request set-header Host customerlookup-xxx.apps.px-prd02.cf.xxx.com:443
server prd02 customerlookup-xxx.apps.px-prd02.cf.xxxx.com:443 check ssl verify none

backend check_CustomerLookupService.searchCustomer_03
option httpchk GET /env HTTP/1.1\r\nHost:\ customerlookup-xxx.apps.px-prd03.cf.xxxx.com:443\r\n
http-check expect rstatus ^200
default-server inter 1s fall 3 rise 1
http-request set-header Host customerlookup-xxx.apps.px-prd03.cf.xxxx.com:443
server prd03 customerlookup-xxx.apps.px-prd03.cf.xxxx.com:443 check ssl verify none

backend CustomerLookupService.searchCustomer
mode http
balance roundrobin
default-server inter 1s fall 3 rise 1
option forwardfor
http-send-name-header Host
http-request set-uri /xxx/CustomerLookupService
server customerlookup-xxx.apps.px-prd02.cf.xxxx.com customerlookup-xxx.apps.px-prd02.cf.xxxx.com:443 track check_CustomerLookupService.searchCustomer_02/prd02 ssl verify none
server customerlookup-xxx.apps.px-prd03.cf.xxxx.com customerlookup-xxx.apps.px-prd03.cf.xxxx.com:443 track check_CustomerLookupService.searchCustomer_03/prd03 ssl verify none