Apache: ProxyPass max parameter has no effect - apache

I am using the following Apache config to forward requests to a Tomcat server:
ProxyPass /myapp ajp://localhost:8009/myapp max=2
This is a simplified config, but is enough to reproduce the issue, which is that the max parameter has no effect. If I through 10 concurrent requests to Apache, all 10 are forwarded to Tomcat at the same time, while I would like to have them forwarded 2 by 2. Should I use something other than the max parameter for this?

The max=2 failed to limit the number of requests concurrently forwarded to Tomcat because I was running this on UNIX, and my Apache came preconfigured with prefork MPM, which creates one process per request. The max applies per process, hence doesn't have the desired effect.
If you are in this situation and need to limit the number concurrent request forwarded to Tomcat, then you'll need to replace your Apache with a worker or event MPM Apache, in the config set ServerLimit to 1, and ThreadsPerChild and MaxClients to the same value, which will be the total number of concurrent connections your Apache will be able to process. You can find more information about this in this section documenting the recommended Apache configuration for Orbeon Forms.

service apache2 restart

Related

Apache - limit scope of RequestReadTimeout

We are running apache and using nagios to query http for alerting / monitoring purposes. We have a few webservers that required more sensitive settings for mod_reqtimeout.c and on those servers we periodically / sporadically get alerts about "UNKNOWN 500 read timeout". Nothing is actually wrong with the webserver / apache when this is happening and we think we have narrowed down the problem to our relatively strict settings for:
RequestReadTimeout header=
We have quite a few vhosts configured on some of these servers and are trying to find a way to modify our global header read timeout setting to ignore certain IP addresses, for example the IP address of our nagios server.
Otherwise a way to have it only apply to certain domains, without having to specifically add the setting into every vhost entry where it needs to exist.
Is there a resource available that talks about how to limit a global parameter to ignore certain IPs or page requests?
Although you can define the timeout at both the server config and virtual host level, in my testing with Apache 2.4.41 I wasn't able to apply a configuration at the server config level and then override it at the virtual host. It just continued to apply the server config values. So I ended up increasing values in the server config.
If you are on Ubuntu then you probably have defaults defined in /etc/apache2/mods-available/reqtimeout.conf for the whole server which then means you aren't able to set values for a virtual host without first changing the configuration here.
There's a short thread about this on the apache users list.
According to the [official documentation][1]
[1]: https://httpd.apache.org/docs/2.4/mod/mod_reqtimeout.html, you should be able to override the global config in vhost config.
Context: server config, virtual host

apache requests very slow after using ProxyPass

So I'm running Tomcat(8.0) behind Apache(2.4) on Windows Server 2012 and using ProxyPass to pass through all traffic. Everything works fine, but whenever I do nothing for 60 seconds, and then hit the server again, i get a 8-20 second delay, like apache is creating a new process to handle the request.
My configuration is pretty much the default that comes with Apache Haus, with the addition of the proxy stuff, which I believe is the culprit:
ProxyPass /static/ !
ProxyPass / http://localhost:8088/
ProxyPassReverse / http://localhost:8088/
I added the
/static/ !
exemption to see if same problem would happen on static files being served, and apparently it does. I further narrowed it down by commenting out all the ProxyPass stuff, and verifying my static file always loads fast. Then i uncommented ProxyPass stuff, and only requested my static file, and it again always returned fast. But once I hit a URL that takes me through the proxy, wait a minute, then hit it again, something goes horribly wrong. Below is network monitor output for two requests, first of the static file being requested a second time after a 1 minute delay before proxy use, the other after the proxy had been used twice with delay between proxy requests.
3501 4:17:48 PM 10/21/2015 104.2752287 httpd.exe HTTP HTTP:Request, GET /static/index.html
3502 4:17:48 PM 10/21/2015 104.2760830 httpd.exe HTTP HTTP:Response, HTTP/1.1, Status: Not modified, URL: /static/index.html
After (8 seconds to return):
24232 4:26:13 PM 10/21/2015 608.7355960 httpd.exe HTTP HTTP:Request, GET /static/index.html
24775 4:26:20 PM 10/21/2015 616.0896861 httpd.exe HTTP HTTP:Response, HTTP/1.1, Status: Not modified, URL: /static/index.html
I'm noticing more of this SynReTransmit line after it was initially broken, not sure if it's relevant:
24226 4:26:13 PM 10/21/2015 608.7286692 httpd.exe TCP TCP:[SynReTransmit #24107]Flags=......S., SrcPort=61726, DstPort=HTTP(80), PayloadLen=0, Seq=1157444168, Ack=0, Win=8192 ( Negotiating scale factor 0x2 ) = 8192
But basically every call, be it to static file or over proxy, if it's been over 60 seconds since the last call, will take forever to get a response!
Any ideas?
UPDATE:
I was running a slightly older version of Apache, 2.4.12, but updating to latest, 2.4.17, didn't fix it. I've tried all sorts of keepalive settings, nothing seems to help. On another forum i was directed at this apache dev thread which has a proposed patch for what sounds like a similar issue, guess I'll wait for an apache update:
http://marc.info/?l=apache-httpd-dev&m=144543644225945&w=2
Try explicitly tuning the ProxyReceiveBufferSize:
# For increase throughput (bytes)
ProxyReceiveBufferSize 2048
In httpd config, add these follow lines:
AcceptFilter http none
AcceptFilter https none
EnableSendfile Off
EnableMMAP off
right after this line:
Listen 80
My response get less than 2 time but it still quite slow than normal.
From https://www.apachelounge.com/viewtopic.php?p=26601
I was using Apache httpd as reverse proxy and it was drastically slow (2 mins to load a single web page). But, as soon as changed the hostname to IP address it was super fast.
before:
ProxyPass "/home" "http://hostname.domain.com:port/home"
After:
ProxyPass "/home" "http://ip:port/home"
Hope it helps someone.

Apache mod_proxy: Parameter `acquire` doesn't work

We use the apache2-worker package with mod_proxy, mod_proxy_balancer and mod_status.
Apache is configured as a load balancer / dispatcher to WFS servers.
OS: SuSE SLES 11 SP2
Apache httpd: version 2.2.12
All of our workers (WFS servers) can handle only one request at a time. So in /etc/apache2/server-tuning.conf, section <IfModule worker.c>, we sat the parameter ServerLimit to 1.
In the configuration of a BalancerMember we used the parameter max=1.
I.e. /etc/apache2/conf.d/proxy.conf looks like that:
<Proxy balancer://wfscluster>
BalancerMember http://wfsserver01:9090 max=1 timeout=3600 acquire=30000
BalancerMember http://wfsserver01:9091 max=1 timeout=3600 acquire=30000
BalancerMember http://wfsserver02:9090 max=1 timeout=3600 acquire=30000
</Proxy>
ProxyPass /wfs balancer://wfscluster/ nofailover=On
The parameter acquire:
Documentation says:
If set this will be the maximum time to wait for a free connection in the connection pool, in milliseconds. If there are no free connections in the pool the Apache will return SERVER_BUSY status to the client.
My understanding of the parameter acquire is the following, and that my desired behaviour, too:
The load balancer gets some requests from clients. At some point in time all workers are busy.
The next request remains on hold by the load balancer until a worker becomes free. If a worker becomes free the pending request is assigned to the free worker, which then accepts the connection.
If there are no free workers in the time specified by parameter acquire the client gets an error response.
But the parameter acquire doesn't work as expected. The load balancer assignes the next request to a busy worker.
Even if another worker gets free in the meantime, the request is still assigned to the busy worker an the client has to wait until the busy worker finished the current request and accepts the new one.
If you do a /etc/init.d/apache2 reload you get an error message in apaches error_log:
BalancerMember Acquire timeout has wrong format
After that message httpd dies.
If you only start or restart the httpd you don't get that message and the httpd is alive.
I also tried to specify a unit like in acquire=30000ms. But the error remains.
The only thing which helps is to remove the acquire parameter, but the described behaviour is the same.
So the question is:
How do I have to use the parameter acquire? Has someone a working example?
Do I have to use other parameters to get the desired behaviour?

Configuration of Apache and Tomcat for load balancing

I'm trying to setup Apache as a load balancer for 2 Tomcat instances with session affinity.
The goal is to have the session stick to one server but to have next session (when it's changed by the backend server) to go to the next available server (let's say using round-robin algorithm for easier implementation). When using the "jvmRoute" in Tomcat and an equivalent "route" in Apache the actual value that does the routing is the route name which does not change and all requests are routed always to the same backend server for a single client.
I found out so far that there's an chicken/egg problem when using just the JSESSIONID cookie. Let's consider the following setup:
2 Tomcat servers listening on ports 8009 and 8010 (AJP13)
1 Apache server with the following configuration
<Proxy balancer://hello-cluster>
BalancerMember ajp://127.0.0.1:8009/hello
BalancerMember ajp://127.0.0.1:8010/hello
</Proxy>
ProxyPass /hello balancer://hello-cluster stickysession=JSESSIONID
And here's the scenario:
The first request has no cookie so Apache selects the next available server in the load balancer to handle the request.
The backend Tomcat server sets JSESSIONID but does not note the actual value being returned.
The next request comes in, Apache notes that there's no backend server noted for the given JSESSIONID so it selects the next available, which in this case the other one as served the first request
Tomcat notices that the value of JSESSIONID is invalid so it creates a new one.
Apache does not take a note that the JSESSIONID has changed to pin it down to that backend server.
Back to pt. 3
Is there a way to convince Apache to note the value returned by Tomcat?
maybe if you try with tomcat session replication. I found this interesting post:
http://www.bradchen.com/blog/2012/12/tomcat-auto-failover-using-apache-memcached
.
You could try too with redis:
http://shivganesh.com/2013/08/15/setup-redis-session-store-apache-tomcat-7/
Let me know your experience please.

apache/mod_wsgi: How do I spawn specific number of processes?

How do I spawn a specific number of processes in Apache when using mod_wsgi with the WSGIDaemonProcess setting?
I have my VirtualHost setup with the following (as a test):
WSGIDaemonProcess webserver user=webserver group=webserver processes=24 threads=8 display-name=%{GROUP} python-path=/var/virtualenv/lib/python2.6/site-packages
While my httpd.conf is setup as follows:
<IfModule prefork.c>
StartServers 8
MinSpareServers 1
MaxSpareServers 8
ServerLimit 24
MaxClients 24
MaxRequestsPerChild 4000
</IfModule>
Note, that I'm running a very constrained 256MB server with PostgreSQL database installed as well.
However, system shows far more than 24 processes for apache (more than 30). I expected that if I set the ServerLimit to the same as processes in WSGIDaemonProcess it would run at the constant 24. However, there seems to be a bunch of spare processes running for unknown reasons?
The ServerLimit directive has got nothing to do with mod_wsgi daemon mode. The 'processes' option to WSGIDaemonProcess is what specifies how many daemon processes mod_wsgi will create. It is a static number and not a dynamic number so just set it to how many you need. For that number of threads per process, there is no point setting it to more that 'processes=3' to start with as you are limited to 24 concurrent requests in the Apache child worker processes which proxy requests to the mod_wsgi daemon processes, so not possible to handle any more requests than that.
In general, if you are running in a memory constrained environment, then you should not be using prefork MPM but worker MPM. Is there a reason you must, such as needing to run PHP code as well? If not, change the MPM used.
How else you could configure things really depends on your code, response times and request throughput, which only you know.