Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use Apache mod_proxy as a connection pool, under the Prefork MPM?

Summary/Quesiton:

I have Apache running with Prefork MPM, running php. I'm trying to use Apache mod_proxy to create a reverse proxy that I can re-route my requests through, so that I can use Apache to do connection pooling. Example impl:

in httpd.conf:

SSLProxyEngine On
ProxyPass /test_proxy/ https://destination.server.com/ min=1 keepalive=On ttl=120

but when I run my test, which is the following command in a loop:

curl -G 'http://localhost:80/test_proxy/testpage'

it doesn't seem to re-use the connections.

After some further reading, it sounds like I'm not getting connection pool functionality because I'm using the Prefork MPM rather than the Worker MPM. So each time I make a request to the proxy, it spins up a new process with its own connection pool (of size one), instead of using the single worker that maintains its own pool. Is that interpretation right?


Background info:

There's an external server that I make requests to, over https, for every page hit on a site that I run.

Negotiating the SSL handshake is getting costly, because I use php and it doesn't seem to support connection pooling - if I get 300 page requests to my site, they have to do 300 SSL handshakes to the external server, because the connections get closed after each script finishes running.

So I'm attempting to use a reverse proxy under Apache to function as a connection pool, to persist the connections across php processes so I don't have to do the SSL handshake as often.

Sources that gave me this idea:

  • http://httpd.apache.org/docs/current/mod/mod_proxy.html
  • http://geeksnotes.livejournal.com/21264.html
like image 438
Nathan Avatar asked Oct 09 '22 17:10

Nathan


1 Answers

First of all, your test method cannot demonstrate connection pooling since for every call, a curl client is born and then it dies. Like dead people don't talk a lot, a dead process cannot keep a connection alive.

You have clients that bothers your proxy server.

Client ====== (A) =====> ProxyServer

Let's call this connection A. Your proxy server does nothing, it is just a show off. The handsome and hardworking server is so humble that he hides behind.

Client ====== (A) =====> ProxyServer ====== (B) =====> WebServer

Here, if I am not wrong, the secured connection is A, not B, right?

Repeating my first point, on your test, you are creating a separate client for each request. Every client needs a separate connection. Connection is something that happens between at least two parties. One side leaves and connection is lost.

Okay, let's forget curl now and look together at what we really want to do.

We want to have SSL on A and we want A side of traffic to be as fast as possible. For this aim, we have already separated side B so it will not make A even slower, right?

Connection pooling? There is no such thing as connection pooling at A. Every client comes and goes making a lot of noise. Only thing that can help you to reduce this noise is "Keep-Alive" which means, keeping connection alive from a client for some short period of time so this very same client can ask for other files that will be required by this request. When we are done, we are done.

For connections on B, connections will be pooled; but this will not bring you any performance since on one-server setup you did not have this part of the noise production.

How do we help this system run faster?

If these two servers are on the same machine, we should get rid of the show-off server and continue with our hardworking webserver. It adds a lot of unnecessary work to the system.

If these are separate machines, then you are being nice to web server by taking at least encyrption (for ssl) load from this poor guy. However, you can be even nicer.

If you want to continue on Apache, switch to mpm_worker from mpm_prefork. In case of 300+ concurrent requests, this will work much better. I really have no idea about the capacity of your hardware; but if handling 300 requests is difficult, I believe this little change will help your system a lot.

If you want to have an even more lightweight system, consider nginx as an alternative to Apache. It is very easy to setup to work with PHP and it will have a better performance.

Other than front-end side of things, also consider checking your database server. Connection pooling will make real difference here. Be sure if your PHP installation is configured to reuse connections to database.

In addition, if you are hosting static files on the same system, then move them out either on another web server or do even better by moving static files to a cloud system with CDN like AWS's S3+CloudFront or Rackspace's CloudFiles. Even without CloudFront, S3 will make you happy. Rackspace's solution comes with Akamai!

Taking out static files will make your web server "oh what happened, what is this silence? ohhh heaven!" since you mentioned this is a website and web pages have many static files for each dynamically generated html page most of the time.

I hope you can save the poor guy from the killer work.

like image 61
hasanyasin Avatar answered Oct 12 '22 10:10

hasanyasin