Thursday, November 8, 2007

How to Install Apache2 for SSL and Load Balancing, Part 2

Here's my updated httpd.conf file for supporting load balancing. Note the key changes in green...

LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so
LoadModule ssl_module /usr/lib/apache2/modules/mod_ssl.so
LoadModule proxy_balancer_module /usr/lib/apache2/modules/mod_proxy_balancer.so

ServerName www.mydomain.com
NameVirtualHost 192.168.1.101:80

<virtualhost 192.168.1.101:80>
ServerName www.mydomain.com
ServerAlias mydomain.com
RewriteEngine on
ProxyRequests off
DocumentRoot /var/www
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ https://%{SERVER_NAME}/$1 [L,R]
</virtualhost>

NameVirtualHost 192.168.1.101:443
<virtualhost 192.168.1.101:443>
ServerName www.mydomain.com
RewriteEngine on
ProxyRequests off
ProxyPreserveHost on
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/apache.pem
DocumentRoot /var/www/ssl
ProxyPass /seaside/go balancer://seaside_cluster stickysession=server nofailover=on
ProxyPassReverse /seaside/go balancer://seaside_cluster
<proxy balancer://seaside_cluster>
BalancerMember http://localhost:9090/seaside/go route=MyApp9090
BalancerMember http://localhost:9091/seaside/go route=MyApp9091
BalancerMember http://localhost:9092/seaside/go route=MyApp9092
</proxy>
RewriteRule ^/$ balancer://seaside_cluster [P,L]
</virtualhost>


My Seaside app requires "sticky" sessions in the load balancer. Session affinity is done using cookies. The 'server' in stickysession=server refers to the identity of a cookie that must be named something like <some_arbitrary_string>.<route_identifier>. The route identifier comes from the route=MyApp<port number> above. (It's quite arbitrary--I could've used A_, B_, C_, etc.)

Your backend application server (in my case, the Seaside app) must also be configured to create this cookie (named 'server' and containing, for example, 'seaside.MyApp9090'). Here's a snippet of Seaside code to illustrate (the leading dots signify spaces):

initialRequest: aRequest
.... port
....self initialRequest: aRequest.
....port := ((HttpService allInstances
........select: [:each each isRunning])
............collect:[:each each portNumber]) first.
....self session currentRequest cookies at: #server
........ifAbsent: [self session redirectWithCookie:
............(WACookie
................key: #server
................value: 'seaside.',
....................((SmalltalkImage current imageName
........................copyAfterLast: FileDirectory slash asCharacter)
............................copyUpToLast: $.), port asString)]


The changes in red are for eliminating warning messages in Apache's error.log.

No comments: