Abnormal behavior in apache load balancing - apache

I have a apache mod proxy load balancer with the following configuration
NameVirtualHost *:5555
<VirtualHost *:5555>
ServerName localhost
ProxyPass / balancer://dgraphs/
ProxyPassReverse / balancer://dgraphs/
<Proxy balancer://dgraphs>
BalancerMember http://172.16.23.232:15000 loadfactor=1
BalancerMember http://172.16.27.87:15011 loadfactor=1
</Proxy>
</VirtualHost>
<Location /balancer-manager>
SetHandler balancer-manager
</Location>
I am getting an abnormal behavior in how apache load balancer is forwarding the query request to the balancer-members. Each Time I send a request to apache, it is sending 3 requests to the balancer members, one to one server and two to the other. On successive request this gets reversed, I mean to say it then sends Two request to the first server and one to the second. Heres' the snapshot of the balancer-member handler.
Request 1
Request 2
and this behaiviour repeats(+2+1, +1+2)
Am I doning something wrong in the configuration or is there some kind of a delay because of which apache failsover and send request to second server and again to first server everytime?
Please HElP!

It seems you maybe missing some configuration details of the Virtual Host with Load Balancer setup, below is a sample configuration that works:
<VirtualHost *:80>
ProxyRequests off
ServerName servername.local
<Proxy balancer://mycluster>
# TomcatA
BalancerMember http://172.20.20.101:8080 route=tomcatA
# TomcatB
BalancerMember http://172.20.20.102:8080 route=tomcatB
# TomcatC
BalancerMember http://172.20.20.103:8080 route=tomcatC
# Security – to determine who is allowed to access
# Currently all are allowed to access
Order Deny,Allow
Deny from none
Allow from all
# Load Balancer Settings
# We will be configuring a simple Round
# Robin style load balancer. This means
# that all nodes take an equal share of
# of the load.
ProxySet lbmethod=byrequests
</Proxy>
# balancer-manager
# This tool is built into the mod_proxy_balancer
# module and will allow you to do some simple
# modifications to the balanced group via a gui
# web interface.
<Location /balancer-manager>
SetHandler balancer-manager
# I recommend locking this one down to your
# administering location
Order deny,allow
Allow from all
</Location>
# Point of Balance
# This setting will allow to explicitly name the
# location in the site that we want to be
# balanced, in this example we will balance "/"
# or everything in the site.
ProxyPass /balancer-manager !
ProxyPass / balancer://mycluster/ stickysession=JSESSIONID|jsessionid nofailover=Off scolonpathdelim=On
If you require sharing sessions between the App Servers instances further configuration will be needed to be done on Apache to use AJP port instead of HTTP as well as configuring the app servers to share the sessions. You may get further details here:
Load Balancing: Apache versus Physical Appliance

Related

Apache : Proxy Balancer, Send certain requests on both channels

I am working on a Spring-MVC based application which is running behind an Apache instance with reverse proxy. Currently, the setup works good with database related operations, but there are certain URL's, which when called, I would like to send request to both the servers. Example : /onlinestatus/*. If the user is currently on server1, then with our current setup, he is unaware of user on server2. But this is not correct, as both users are using the same platform. How can I instruct apache to pass certain URL's to both the platforms. Thank you.
sites-enabled/000-default :
<VirtualHost *:443>
ServerName www.domain.de
ProxyRequests off
ProxyPreserveHost On
ProxyPass /nagios !
ProxyReceiveBufferSize 4096
ErrorDocument 503 /error/message.html
ProxyPass /error/ !
ProxyPass /error/message.html !
SSLEngine on
SSLProxyEngine on
SSLCertificateFile /etc/letsencrypt/live/www.domain.de-0002/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.domain.de-0002/private.key
SSLCertificateChainFile /etc/letsencrypt/live/www.domain.de-0002/chain.pem
SSLProxyVerify none
SSLProxyCheckPeerCN off
ProxyPass / https://localhost:8443/
ProxyPassReverse / https://localhost:8443/
<Location / >
SetEnvIf Origin ^(https?://.+\.DOMAIN\.de(?::\d{1,5})?)$ CORS_ALLOW_ORIGIN=$1
Header append Access-Control-Allow-Origin %{CORS_ALLOW_ORIGIN}e env=CORS_ALLOW_ORIGIN
Header merge Vary "Origin"
Order allow,deny
Allow from all
</Location>
ProxyPass / balancer://mycluster/ stickysession=JSESSIONID nofailover=On
<Proxy balancer://mycluster>
BalancerMember https://SERVER_1_IP:8443 route=server1
</Proxy>
ProxyPass /balancer-manager !
ProxyPass / balancer://mycluster/
</VirtualHost>
You can't proxy a request to two servers. What would you expect to get? Two HTML documents? (and what if your cluster grows: 20 HTML documents?) How would they display?
If your application works in a cluster, and it's vital that users are aware of others working on the cluster, you'll need to make that information available on the business layer (by keeping track on logged in users in the backend - this could be the database or a cluster communication channel)
If you "just" need this information for system administration purposes - e.g. to know when it's safe to take one of the cluster machines out of service - then just utilize your loadbalancer's status information page.

Apache load-balancer: direct to specific application based on URL

I have multiple applications deployed in Tomcat's webapps folder (app1.0, app1.1, app1.2 etc.). When I hit www.example.com:8080/app1.0, the corresponding application appears.
But how to do it on the load-balancing server? For instance, I have a website on which I can click a button (app1.0, app1.1, app1.2 etc.) and an URL pops up like: www.lb.com/app1.0/.../... How to direct to the app based on application version in URL? Use RewriteCond and regex and pass it to ProxyPass? I don't really how to script it, anyone could help? :)
Edit: This is what I done for the 2 apps for 1 Tomcat and 2 apps for 2 Tomcat, but I got 404 sometimes because the Tomcat that has another version has been chosen by the load-balancer.
<VirtualHost *:80>
#Add a http header to explicitly identify the node and be sticky
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
#Declare the http server pool
<Proxy "balancer://plf">
BalancerMember "http://worker1.com:8080" route=worker1
BalancerMember "http://worker2.com:8080" route=worker2
ProxySet stickysession=ROUTEID
ProxySet lbmethod=bybusyness
</Proxy>
#Common options
ProxyRequests Off
ProxyPreserveHost On
#Declare the redirection for the http requests
ProxyPassMatch "/app(.*)" "balancer://plf/app$1"
ProxyPassReverse "/app(.*)" "balancer://plf/app$1"
This is how I did it:
1) define a balancer proxy:
<Proxy balancer://portalcluster stickysession=JSESSIONID>
BalancerMember ajp://TOMCATSERVER1:8009 route=TOMCARSERVER1-0
BalancerMember ajp://TOMCATSERVER2:8009 route=TOMCATSERVER2-100
</Proxy>
2) proxy to it in your VirtualHost:
Listen 443
<Virtualhost *:443>
ServerName example.com
Alias /static /var/www/portalstatic
ProxyPass /static !
ProxyPass / balancer://portalcluster/
ProxyPassReverse / balancer://portalcluster/
</Virtualhost>
NB I removed a lot of configuration from these, that are not related to the question (logs, deny clauses, certificate directives, ...). This is just to illustrate the way I did the proxy.
NB2 I did leave the /static trick since this is usually something you will want to do. Static files must stay on the HTTP, and not send them from Tomcat all the time.

How to use an Apache load balancer with Bokeh, with HTTP and WS protocols?

I'm trying to get Apache to work with more than one Bokeh server. Everything works fine with one server behind a reverse-proxy, but when I try configuring a load balancer, I keep getting an internal server error. I know there is some information about load balancing in the Bokeh docs, but it's only explained for Nginx, and I'm having a hard time linking the dots.
I'm guessing it has something to do with the websocket protocol. I've read a bit about this, and I've seen examples for simple HTTP load balancers, but not for WS and HTTP load balancers.
Do I have to create 2 clusters, one for HTTP and one for WS? How can I work with WS and HTTP wihtin a load balancer?
I have included what I have for now in my Apache config. Please note that I have only one server per cluster for testing purposes.
<Proxy balancer://mycluster>
# Server 1
BalancerMember http://localhost:5100/foo
</Proxy>
<Proxy balancer://mycluster/ws>
# Server 1
BalancerMember ws://localhost:5100/foo/ws
</Proxy>
<VirtualHost *:80>
ServerName localhost
CustomLog "/var/log/apache2/access.log" combined
ErrorLog "/var/log/apache2/error.log"
ProxyPreserveHost On
<Location /foo>
ProxyPass balancer://mycluster
ProxyPassReverse balancer://mycluster
</Location>
<Location /foo/ws>
ProxyPass balancer://mycluster/ws
ProxyPassReverse balancer://mycluster/ws
</Location>
Alias /static /var/www/static
<Directory /var/www/static>
# directives to effect the static directory
Options +Indexes
</Directory>
</VirtualHost>

Load balancer with apache httpd and wildfly for rest web services with mod_proxy

I have an apache load balancer with mod_proxy and wildfly (apache 224 and wildfly 9).
I have 4 servers in domain in wildfly and the load balancer works fine with a "hello world" app, and in the balancer manager i can see how the requests are sent to each server.
The thing is, When I use the app that has some REST web services, i am sending the request with a GET method and some headers for authentication, and somehow, the application is responding with error when i access it through the load balancer, but if I send it directly to the server, it works correctly.
my cofiguration goes as follows
<VirtualHost *:80>
ProxyRequests Off
<Proxy balancer://mycluster>
BalancerMember http://localhost:8080/ loadfactor=25
BalancerMember http://localhost:8230/ loadfactor=25
BalancerMember http://localhost:8330/ loadfactor=25
BalancerMember http://localhost:8430/ loadfactor=25
</Proxy>
<Location /balancer-manager>
SetHandler balancer-manager
Order Deny,Allow
Allow from all
</Location>
<Location /test>
Order allow,deny
Allow from all
</Location>
ProxyPass /test balancer://mycluster stickysession=JSESSIONID
I am testing using postman and sending the requests with a get method and a header for authentication: basic {base64 code} as follows:
http://127.0.0.1/test/myproject.ws/myproject/get_list?key=T11108101191&page=1
and this results in error.
when i try this:
http://127.0.0.1:8080/myproject.ws/myproject/get_list?key=T11108101191&page=1
This goes ok
and when i try the above, but with a post method, it gets the same error as in the load balancer.
Any idea of what am i doing wrong?
PS: I've tried putting in the WEB-INF/web.xml of the project, but i still get the same error.
Thanks to Dusan Bajic, he saw the problem I had. In the balancer member i was finishing the route with "/" and when I used the ProxyPass, i was starting with "/", duplicating that character. Somehow, with the helloworld app it worked correctly, but when i pass parameters, it failed.
The new configuration goes as follows:
<VirtualHost *:80>
ProxyRequests Off
<Proxy balancer://mycluster>
BalancerMember http://localhost:8080 loadfactor=25
BalancerMember http://localhost:8230 loadfactor=25
BalancerMember http://localhost:8330 loadfactor=25
BalancerMember http://localhost:8430 loadfactor=25
</Proxy>
<Location /balancer-manager>
SetHandler balancer-manager
Order Deny,Allow
Allow from all
</Location>
<Location /test>
Order allow,deny
Allow from all
</Location>
ProxyPass /test balancer://mycluster stickysession=JSESSIONID
</VirtualHost>

Apache mod-proxy load balancer maintenance

I have mod-proxy and mod-proxy-balancer setup as a load balancing reverse proxy. Something like this:
<Proxy balancer://example>
BalancerMember http://hostname:8000 keepalive=on
BalancerMember http://hostname:8001 keepalive=on
</Proxy>
ProxyPass / balancer://example/
ProxyPassReverse / balancer://example/
ProxyPreserveHost on
ProxyRequests Off
Is there a simple way to set this up to show a static maintenance page when all members of the balancer group are down? I've done that with a hardware load balancer previously and it was very useful.
Maybe you can use a hot standby. The example below is from the ProxyPass Directive section where it says "Setting up a hot-standby, that will only be used if no other members are available"
ProxyPass / balancer://hotcluster/
<Proxy balancer://hotcluster>
BalancerMember http://1.2.3.4:8009 loadfactor=1
BalancerMember http://1.2.3.5:8009 loadfactor=2
# The below is the hot standby
BalancerMember http://1.2.3.6:8009 status=+H
ProxySet lbmethod=bytraffic </Proxy>
As an alternative to RewriteRule you can do the same thing with appropriate ErrorDocument directives. We do something like this in which the proxy server itself hosts static error pages and the "hot-standby" host is http://localhost/some-app/.
Since your proxy seems to be the only page (probably in a VirtualHost), you can simply override error pages. Apache produces a 503 error, so this would look like:
# Document root is required because error documents use relative paths
DocumentRoot /var/www/html/
# Allow access to document root directory
<Directory /var/www/html/>
Order allow,deny
allow from all
</Directory>
# Actual change: If service is unavailable (no member available), show this page
ErrorDocument 503 /maintenance.html
If you want to use images inside the maintenance html, please not that you have to use absolute paths (e.g. /image.jpg) will load /var/www/html/image.jpg.