Advanced Reverse Proxy Load Balancing in Apache HTTP Server 2.
2
Jim Jagielski http://www.jimjag.com/ [email protected]
Whew
Thats a mouthful
About me
Longtime active contributor (July/Aug 1995) Been giving mod_proxy much TLC ASF Co-founder Other ASF titles as well CTO of Covalent Technologies Husband, father, all around nice guy
mod_proxy? Wazzat?
An Apache module Implements core proxy capability Both forward and reverse proxy In general, most people use it for reverse proxy (gateway) functionality
Forward Proxy
Intent is to protect internal clients
Forward Proxy
Reverse Proxy
Intent is to protect internal Servers
Firewall
Reverse Proxy
Internal Servers
How did we get here?
A stroll down mod_proxy lane
First available in Apache 1.1
Experimental Caching Proxy Server
In Apache 1.2, pretty stable, but just HTTP/1.0 In Apache 1.3, much improved with added support for HTTP/1.1 In Apache 2.0, break out cache and proxy
7
Whats new/improved in 2.2
Large file support Graceful stop mod_dbd mod_filter Better Debugging and info Caching Event MPM Authn/Authz
Proxy
8
Goal for mod_proxy in 2.2
Goal for mod_proxy in 2.2
Suck less ass
Proxy Improvements
Becoming a robust but generic proxy implementation Support various protocols
HTTP, HTTPS, CONNECT, FTP AJP, FastCGI (coming soonish)
Load balancing Clustering, failover
10
AJP? Really?
Yep, Apache can now talk AJP with Tomcat directly mod_proxy_ajp is the magic mojo Other proxy improvements make this even more exciting mod_jk alternative
11
But I like mod_jk
Thats fine, but...
Now the config is much easier and more consistent
ProxyPass /servlets ajp://tc.example.com:8089
Easier when Apache needs to proxy both HTTP and AJP Leverage improvements in proxy module
12
Load Balancer
mod_proxy_balancer.so mod_proxy can do native load balancing
weight by actual requests weight by traffic lbfactors
LB algos are impl as providers
easy to add no core code changes required
13
Providers? Wazzat?
New feature of Apache 2.x Originally used mostly in mod_dav Then in caching Now in other places too
authn / authz mod_proxy
14
Providers... so what
Think of providers as providing services modules implement providers and register them Other modules can then use those providers to implement that service Cool pizza delivery analogy
15
Why cool for mod_proxy?
We mentioned that right now, we balance by traffic and requests But what if you want some other method You can add that capability with no core code changes to Apache. Very flexible
16
Load Balancer
Backend connection pooling
Available for named workers:
eg: ProxyPass
/foo http://bar.example.com
Reusable connection to origin For threaded MPMs, can adjust size of pool (min, max, smax) For prefork: singleton
Shared data held in scoreboard
17
Pooling example
18
<Proxy balancer://foo> BalancerMember http://www1.example.com:80/ BalancerMember http://www3.example.com:80/ BalancerMember http://www2.example.com:80/ ProxySet lbmethod=bytraffic </Proxy>
Pooling example
loadfactor=1 loadfactor=1 loadfactor=4 status=+h
18
<Proxy balancer://foo> BalancerMember http://www1.example.com:80/ BalancerMember http://www3.example.com:80/ BalancerMember http://www2.example.com:80/ ProxySet lbmethod=bytraffic </Proxy> proxy: proxy: proxy: proxy: proxy: proxy: proxy: proxy: proxy: proxy: ... proxy: proxy: proxy: proxy: proxy: proxy:
Pooling example
loadfactor=1 loadfactor=1 loadfactor=4 status=+h
grabbed scoreboard slot 0 in child 371 for worker http://www1.example.com/ initialized single connection worker 0 in child 371 for (www1.example.com) grabbed scoreboard slot 0 in child 369 for worker http://www1.example.com/ worker http://www1.example.com/ already initialized grabbed scoreboard slot 0 in child 372 for worker http://www1.example.com/ worker http://www1.example.com/ already initialized grabbed scoreboard slot 2 in child 371 for worker http://www3.example.com/ initialized single connection worker 2 in child 371 for (www3.example.com) initialized single connection worker 0 in child 369 for (www1.example.com) grabbed scoreboard slot 2 in child 369 for worker http://www3.example.com/ grabbed scoreboard slot 6 in child 369 for worker proxy:reverse initialized single connection worker 6 in child 369 for (*) grabbed scoreboard slot 6 in child 372 for worker proxy:reverse worker proxy:reverse already initialized grabbed scoreboard slot 1 in child 369 for worker http://www1.example.com/ initialized single connection worker 6 in child 372 for (*)
18
Workers and worker
Dont get too confused Both the worker MPM and the proxy balancer use the term worker
19
Load Balancer
Sticky session support
aka session affinity Cookie based
stickysession=PHPSESSID stickysession=JSESSIONID
Natively easy with Tomcat May require more setup for simple HTTP proxying Do you really want/need it?
20
Load Balancer
Cluster set with failover
Lump backend servers as numbered sets balancer will try lower-valued sets first If no workers are available, will try next set
Hot standby
21
Example
<Proxy balancer://foo> BalancerMember http://php1:8080/ loadfactor=1 BalancerMember http://php2:8080/ loadfactor=4 BalancerMember http://phpbkup:8080/ loadfactor=4 status=+h BalancerMember http://offsite1:8080/ lbset=1 BalancerMember http://offsite2:8080/ lbset=1 ProxySet lbmethod=bytraffic </Proxy> ProxyPass /apps/ balancer://foo/
22
Embedded Admin
Allows for real-time
Monitoring of stats for each worker Adjustment of balancer and worker params
lbset lbmethod route enabled / disabled ...
23
Easy setup
<Location /balancer-manager> SetHandler balancer-manager Order Deny,Allow Deny from all Allow from 192.168.2.22 </Location>
24
Admin
25
Some tuning params
For workers:
loadfactor
normalized load for worker [1]
lbset
worker cluster number [0]
retry
retry timeout, in seconds, for non-ready workers [60]
26
Some tuning params
For workers - connection pool:
min
Initial number of connections [0]
max
Hard maximum number of connections [1| TPC]
smax:
soft max - keep this number available [max]
ttl
time to live for connections above smax
27
Some tuning params
For workers (cont):
timout
Connection timeout on backend [Timeout]
flushpackets *
Does proxy need to flush data with each chunk of data?
on : Yes off : No auto : wait and see
flushwait *
ms to wait for data before flushing
28
Some tuning params
For workers (cont):
ping *
Ping backend to check for availability; value is time to wait for response
status (+/-)
D : disabled S : Stopped I : Ignore errors H : Hot standby E : Error
29
Some tuning params
For balancers:
lbmethod
load balancing algo to use [byrequests]
For both:
ProxySet
Alternate method to set various params
ProxySet balancer://foo timeout=10 ... ProxyPass / balancer://foo timeout=10
30
Oh yeah
ProxyPassMatch
ProxyPass can now take regexs instead of just paths
ProxyPassMatch ^(/.*\.gif)$ http://backend.example.com$1
JkMount migration
Shhhh
ProxyPass ~ ^(/.*\.gif)$ http://backend.example.com$1
mod_rewrite is balancer aware
31
Gotcha
ProxyPassReverse is NOT balancer aware! The below will not work:
<Proxy balancer://foo> BalancerMember http://php1:8080/ BalancerMember http://php2:8080/ </Proxy> ProxyPass /apps/ balancer://foo/ ProxyPassReverse /apps balancer://foo/ loadfactor=1 loadfactor=4
32
Workaround
Instead, do this
<Proxy balancer://foo> BalancerMember http://php1:8080/ BalancerMember http://php2:8080/ </Proxy> ProxyPass /apps/ balancer://foo/ ProxyPassReverse /apps http://php1:8080/ ProxyPassReverse /apps http://php2:8080/ loadfactor=1 loadfactor=4
33
Putting it all together
<Proxy balancer://foo> BalancerMember http://php1:8080/ BalancerMember http://php2:8080/ BalancerMember http://phpbkup:8080/ ProxySet lbmethod=bytraffic </Proxy> <Proxy balancer://javaapps> BalancerMember ajp://tc1:8089/ BalancerMember ajp://tc2:8089/ ProxySet lbmethod=byrequests </Proxy> ProxyPass /apps/ balancer://foo/ ProxyPass /serv/ balancer://javaapps/ ProxyPass /images/ http://images:8080/ loadfactor=1 loadfactor=4 loadfactor=4 status=+h
loadfactor=1 loadfactor=4
34
Whats on the horizon?
Some additional potential backports
FastCGI proxy module HTTP ping (OPTIONS *)
More LB methods Enhancing ProxyPassReverse Better RFC compliance Something completely different...
35
Thanks!
Q&A Resources:
http://httpd.apache.org/ [email protected] A certain Open Source support provider
36