How do I enable sticky load balancing based on session identifiers using apache mod_proxy_balancer - apache

Our proxy configuration (in httpd.conf) to send requests to 2 JBoss instances are given below is based on mod_proxy_balancer
<Proxy balancer://mycluster>
Allow from all
BalancerMember http://192.168.1.2:9080
BalancerMember http://192.168.1.2:8080
</Proxy>
ProxyPass /app balancer://mycluster/app
ProxyPassReverse /app http://192.168.1.2:9080/app
ProxyPassReverse /app http://192.168.1.2:8080/app
How do I enable sticky load balancing based on session identifiers. Am I supposed to set the following flag as part of the Proxy declaration? It doesn't seem to take any effect. How would I debug to see if this is working fine.
SetEnv BALANCER_SESSION_STICKY JSESSIONID

The PHP sticky sessions article was an interesting read, and that lead me to look for a JBoss specific solution. The key is having the route appended to the session value in the jsessionid param/cookie. JBoss (actually tomcat) has builtin support for this.
Add jvmRoute="" to the config in each server.xml. Then change <attribute name="UseJK">false</attribute>in jboss-service.xml to 'true'.
The whole setup is described in Using mod_proxy with JBoss.

Related

Apache load balancer dropping the HTTP request body

I have configured an Apache http server with mod_proxy to load balance between two jetty servers (sticky sessions).
Everything works fine and as expected while the two servers are up and running. But if I get one of the servers down and then attempt to make an http post to that server, the Apache balancer redirects the post to the running server but with an empty body, losing the original request.
After the request that triggered the redirect to the running server, all subsequent requests work fine.
Apache configuration:
<Proxy balancer://cluster>
BalancerMember http://localhost:9090 route=node1
BalancerMember http://localhost:9091 route=node2
ProxySet stickysession=JSESSIONID
</Proxy>
ProxyPreserveHost On
ProxyPass "/" "balancer://cluster/"
ProxyPassReverse "/" "balancer://cluster/"
I'm using Apache Server 2.4 and Jetty 9.4.22
Any ideas on why this is happening?
Thanks.
It looks like you hit the bug introduced as a regression in 2.4.41. You can check out the details here: https://bz.apache.org/bugzilla/show_bug.cgi?id=63891
To remedy, you will need to upgrade to 2.4.42 or greater.

new session after every request, tomcat backend, apache frontend

I develop a jsp website using tomcat as backend and apache as frontend redirecting with mod_proxy.
First my configs.
apache:
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
SSLProxyEngine on
ProxyPass / https://realdomain.tld:8443/proj1/
ProxyPassReverse / https://realdomain.tld:8443/proj1/
<Location />
Order allow,deny
Allow from all
</Location>
When I reload my jsp webpage, every time i get a new session id. When developing on localhost without apache and mod_proxy everything works and I keep the same session id.
For my webapp it is important to keep the same session during the time.
Any Idea how i can tell apache to keep my session. I guess apache has to redirect the cookie to tomcat right? but how...
Any time you change the context path in the proxy (/ -> proj1) you create a whole heap of problems to solve. Your immediate cookie problem can be solved with the ProxyPassReverseCookiePath directive. I then suspect you'll find the next problem to solve. You'd be better off redeploying your application as the ROOT web application so that your ProxyPass directive is ProxyPass / https://realdomain.tld:8443/
As an aside, it looks like you are proxying to Tomcat's https connector. If you aren't careful you will create security problems for yourself if httpd receives requests over http, proxies them to Tomcat over https and Tomcat treats those requests as being received over a secure channel.

Apache httpd as load balancer for jboss as well another Apache servers

I have an apache httpd server, say server1* (publicly exposed) that is acting as load balancer for some jboss servers(behind firewall) using mod_cluster. Now I want to install my static content (images/css/htmls) and probably some cg-scripts on a couple of apache servers, say **server2 and server3 (behind firewall).
Now I want server1 to act as load balancer for these server2 and server3 as well along with the jboss servers.
With this arrangement, any request for applications deployed on jboss need to be routed to jboss and any static content request should go to server2 or server3.
Here are the versions I am using
Linux Server
apache httpd - 2.2.22
JBOSS-EAP-6
What mechanism/configuration do I need to use in server1 to make it possible?
Please see if someone can help with this.
Well, you just add a ProxyPass setting. mod_cluster is compatible with ProxyPass, so you can use both.
For instance, if I would like gif images to be served by httpd, not by AS7, I can add:
ProxyPassMatch ^(/.*\.gif)$ !
Furthermore, if you set
CreateBalancers 1
mod_cluster won't create proxies for you and you have to do it yourself. This gives you an additional control. For instance:
ProxyPassMatch ^/static/ !
ProxyPass / balancer://qacluster stickysession=JSESSIONID|jsessionid nofailover=on
ProxyPassReverse / balancer://qacluster
ProxyPreserveHost on
In the aforementioned example, we proxy anything but /static/ content to the workers.
Note:If you encounter any cookies related issues, you might want to play with ProxyPassReverseCookieDomain and ProxyPassReverseCookiePath.
Note qacluster in my config. The default is mycluster, so for naming my balancer qacluster, I added this to mod_cluster config (outside VirtualHost):
ManagerBalancerName qacluster
If it is not clear, just reply and I can try to elaborate further.
I had the same issue where in we were using Apache HTTP server for static content and JBOSS AS 7 server for dynamic contents (the JSF web app).
So adding the below property at the end of Load modules tells
CreateBalancers 0
Tells to "0: Create in all VirtualHosts defined in httpd."
More at: http://docs.jboss.org/mod_cluster/1.2.0/html/native.config.html#d0e485
And the below config solved the issues of images and styel sheets not getting displayed.
<VirtualHost *:80>
ServerName dev.rama.com
DocumentRoot "/var/www/assests"
UseAlias 1
ProxyPassMatch ^(.*\.bmp)$ !
ProxyPassMatch ^(.*\.css)$ !
ProxyPassMatch ^(.*\.gif)$ !
ProxyPassMatch ^(.*\.jpg)$ !
ProxyPassMatch ^(.*\.js)$ !
ProxyPassMatch ^(.*\.png)$ !
<Directory /var/www/assests>
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
Note:
All our assests for the web app was on HTTP server at
/var/www/assests and the url I was accessing was dev.rama.com on port 80
So when it sees this ProxyPassMatch ^(.*.css)$ !
The webserver knows that the css files are local to the http server and we dont need to go to Jboss App server.
More info at http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypass

What are my options to deploy Go applications alongside PHP applications?

What I'm basically trying to accomplish is having my main website running a CMS written in Go. This will be located at www.example.com.
I also have applications written in PHP located in directories, such as www.example.com/clients/
How can I serve example.com/clients using Apache/PHP while serving example.com using Go built-in web server?
Via mod_proxy in Apache2, you can proxy different paths into different destinations at localhost or anywhere else accessible by your server, including within your local network (if your server can access it).
For this you would use ProxyPass (Apache2 Docs for ProxyPass, which is very useful reading) like the example below:
<VirtualHost *:80>
ServerName some.example.host.xyz
DocumentRoot /var/www/your-document-root
Alias /clients/ /var/www/clients/
ProxyPass /clients/ !
ScriptAlias /something-using-cgi/ /var/www/cgi-stuff/
ProxyPass /something-using-cgi/ !
ProxyPreserveHost On
ProxyPass / http://localhost:9876/
ProxyPassReverse / http://localhost:9876/
ProxyPass /elsewhere/ http://elsewhere.example.host.xyz:1234/
ProxyPassReverse /elsewhere/ http://elsewhere.example.host.xyz:1234/
</VirtualHost>
You'll want to be sure that you set your proxy security such that external users can't use your reverse proxy as a forward proxy, too. You can do that via ProxyRequests as described in the official Apache2 docs. The way I did this on a server is to put this in your server-wide config (you should verify on your own that this is secure enough):
# disables forward proxy
ProxyRequests Off
Andrew Gerrand has a good blog post about this for nginx but the principle is the same for Apache.
You want to set up Apache as a reverse proxy for requests coming in for the Go application.
For Apache you want to look at mod_proxy

jetty via apache mod_proxy

Using an Apache virtualhost and mod_proxy I want to access a java application (myapp) available in a jetty instance on port 8080.
With ProxyPass / localhost:8080/ on my apache virtualhost configuration I can access the application running in jetty with www.mydomain.com/myapp but I want the application to be accessed from www.mydomain.com.
Trying with ProxyPass / localhost:8080/myapp The application cannot be found because the request becomes www.mydomain.com/myappmyapp/.
Then tried with:
<Location />
ProxyPass localhost:8080/myapp/
SetEnv force-proxy-request-1.0 1
SetEnv proxy-nokeepalive 1
</Location>
I can access the application but just for the first request. Subsequent requests become www.mydomain.com/myappmyapp/
After reading many times wiki.eclipse.org/Jetty/Tutorial/Apache and the apache mod_proxy docs the only way I managed to use the application properly from www.mydomain.com is with the following configuration:
<Location /myapp/>
ProxyPass localhost:8080/myapp/
SetEnv force-proxy-request-1.0 1
SetEnv proxy-nokeepalive 1
</Location>
<Location />
ProxyPass localhost:8080/myapp/
SetEnv force-proxy-request-1.0 1
SetEnv proxy-nokeepalive 1
</Location>
so the request is forwarded to the jetty application in both cases.
I am quite new to apache and jetty and I am pretty sure there is a better and more elegant way of achieving the same result.
In fact apache complains saying:
[warn] worker localhost:8080/myapp/ already used by another worker
The problem is that when you deploy your application in jetty with the context path /myapp, it will generate all links accordingly. Apache mod_proxy does all the rewriting at the HTTP level (headers) and won't do anything with the response body, keeping it as it is.
If you don't mind the /myapp sticking around, you can turn mod_rewrite on and include following two lines in your Location block:
RewriteEngine on
RewriteRule ^/myapp/(.*)$ /$1 [P]
If you would like to get rid of /myapp for good, then the only option left (assuming you don't want to waste CPU power on mod_proxy_html) is to configure virtual hosts, and deploy applications on virtual hosts with context path of /.
If you want your webapp to be accessible at the root of your site, what you need is to deploy the web application into the root of container. Usually, this is done by calling the war file ROOT.war instead of myapp.war (although this ultimately depend on the configuration of your Jetty deployer, which may be more complex than the default).
Yes it works from the jetty root, but I would like to have more than one application running. The configuration for myapp is under jetty's contexts folder:
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
<Set name="contextPath">/mvc-showcase</Set>
<Set name="war"><SystemProperty name="jetty.home"/>/webapps/mvc-showcase.war</Set>
</Configure>
my jetty version is 6.1.22