Fact: fronting Tomcat or Jetty with any actual webserver will make page load times faster by caching most if not all non-servlet requests; mileage with vary, depends on caching/upstream config.
I chose to work with nginx, because of great experiences in the past. Unfortunately no mainline support for AJP. There is an addon module, nginx_ajp_module, but I just could not get it to compile with nginx 1.2.4, even after some hackish patching. Will have to fork and dig around with it further at some point.
I use the --no-check-certificate
option with wget because the AWS image
bundling procedure eats .pem files on some of my boxes. The apt-get command
should get you all the dependencies you need to compile nginx with everything
except pcre-jit enabled.
wget http://nginx.org/download/nginx-1.2.4.tar.gz
tar xzvf nginx-1.2.4.tar.gz
wget --no-check-certificate https://github.com/gnosek/nginx-upstream-fair/tarball/master
mv master gnosek-nginx-upstream-fair.tar.gz
tar xzvf gnosek-nginx-upstream-fair.tar.gz
apt-get install build-essential libpcre++0 libpcre++-dev zlib1g-dev zlib1g openssl libssl-dev
cd nginx-1.2.4
./configure --add-module=../gnosek-nginx-upstream-fair-* --with-http_ssl_module
make
make install
For all your dependency-based Debian booting needs: /etc/init.d/nginx
#! /bin/sh
### BEGIN INIT INFO
# Provides: nginx
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts the nginx web server
# Description: starts nginx using start-stop-daemon
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/nginx/sbin/nginx
NAME=nginx
DESC=nginx
test -x $DAEMON || exit 0
set -e
case "$1" in
start)
echo -n "Starting $DESC: "
start-stop-daemon --start --quiet --pidfile /usr/local/nginx/logs/nginx.pid --exec $DAEMON -- $DAEMON_OPTS
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon --stop --quiet --pidfile /usr/local/nginx/logs/nginx.pid --exec $DAEMON
echo "$NAME."
;;
restart|force-reload)
echo -n "Restarting $DESC: "
start-stop-daemon --stop --quiet --pidfile /usr/local/nginx/logs/nginx.pid --exec $DAEMON
sleep 1
start-stop-daemon --start --quiet --pidfile /usr/local/nginx/logs/nginx.pid --exec $DAEMON -- $DAEMON_OPTS
echo "$NAME."
;;
reload)
echo -n "Reloading $DESC configuration: "
start-stop-daemon --stop --signal HUP --quiet --pidfile /usr/local/nginx/logs/nginx.pid --exec $DAEMON
echo "$NAME."
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0
located at /usr/local/nginx/conf/nginx.conf
Please see the HttpCoreModule wiki page for more information about core directives. For additonal information about the directives to use with the HttpUpstreamFairModule.
#user nobody;
worker_processes 3; #make use of multiple cores efficiently
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
keepalive_timeout 2; #in seconds
gzip on;
client_max_body_size 2m; #handle <2MB media uploads
proxy_connect_timeout 10s;
proxy_read_timeout 40s; #max loading response for long AJAX processing time
upstream dev {
server 192.168.11.11:8081;
server 192.168.21.21:8081;
server 127.0.0.1:8081;
fair;
}
upstream production {
server 192.168.10.10:8080;
server 192.168.20.20:8080;
server 127.0.0.1:8080;
fair;
}
include /usr/local/nginx/conf/nginx_host.conf;
}
For more on creating unified CRTs: https://www.startssl.com/?app=42
located at /usr/local/nginx/conf/nginx_host.conf
#redirect all HTTP requests not handled to HTTPS
server {
listen 80 default;
rewrite ^(.*) https://$host$1 permanent;
access_log /dev/null;
error_log /dev/null;
}
#production
server {
ssl on;
listen 443;
server_name production.myservice.com;
ssl_certificate /srv/tls/production-unified.crt;
ssl_certificate_key /srv/tls/production.key;
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
location = /favicon.ico {
expires max;
add_header Cache-Control public;
}
# serve static files
location ~ ^/(css|images|javascript|js|script|style)/ {
expires 2d;
}
location / {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://production;
}
access_log /dev/null;
error_log /dev/null;
}
#dev
server {
ssl on;
listen 443;
server_name dev.myservice.com;
ssl_certificate /srv/tls/dev-unified.crt;
ssl_certificate_key /srv/tls/dev.key;
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
location = /favicon.ico {
expires max;
add_header Cache-Control public;
}
location / {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://dev;
}
access_log /dev/null;
error_log /dev/null;
}
Please see Configuring HTTPS servers for more information on configuring nginx with HTTPS.
Server Name Indication,
which allows for TLS name-based virtual hosting
(using different CRTs per virtual host) is not supported by all
HTTPS clients or HTTPS servers. If you really want to host a bunch of HTTPS
subdomains - *.yourdomain.com
- purchase a wildcard SSL certificate. I ran into
trouble getting Jenkins CI jobs kicked off
from bitbucket commits
because old versions of GNU Wget do not support TLS SNI.
I know I am
still waiting for the latest stable Debian release
to include the GNU Wget update.