LiveAgent contains a huge number of static files, which can be served much faster-using Varnish service as with standard web server like Apache.
Often we've seen performance boosts in range of 10x up to 100x of Apache speed on the same hardware. It is worth to spend few minutes with Varnish configuration.
Some examples of static files: images (logo, icons), HTML of the live chat window, javascript files, etc.
With Varnish we will not replace the Apache functionality. It will sit before the Apache and proxy requests to Apache in case the file is not in cache already.
Let's image your current situation:
- you are running Apache on port 80 to serve visitors of your website the content of your web page
- Example request: Visitor's browser requesting file example.jpg (port 80) <----> Apache (port 80)
With Varnish will be the situation following:
- On port 80 will listen to Varnish, Apache will be set to listen e.g. on port 8080
- Example request: Visitor's browser requesting file example.jpg (port 80) <----> Varnish (port 80) <----> Apache (port 8080)
Installation
1. Varnish service installation is on each operating system different. Therefore please ask your server administrator to install it properly based on your operating system.
To install it using yum, try following commands:
yum install epel-release rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-4.1.el6.rpm yum install varnish
2. Configuration:
The varnish service configuration file (/etc/sysconfig/varnish) could look like (please tune storage size depending on the size of your server memory):
# Configuration file for Varnish Cache # # /etc/init.d/varnish expects the variable $DAEMON_OPTS to be set from this # shell script fragment. # # Maximum number of open files (for ulimit -n) NFILES=131072 # Locked shared memory (for ulimit -l) # Default log size is 82MB + header MEMLOCK=82000 # Maximum number of threads (for ulimit -u) NPROCS="unlimited" # Maximum size of corefile (for ulimit -c). Default in Fedora is 0 # DAEMON_COREFILE_LIMIT="unlimited" # Init script support to reload/switch vcl without restart. # To make this work, you need to set the following variables # explicit: VARNISH_VCL_CONF, VARNISH_ADMIN_LISTEN_ADDRESS, # VARNISH_ADMIN_LISTEN_PORT, VARNISH_SECRET_FILE. RELOAD_VCL=1 # Main configuration file. VARNISH_VCL_CONF=/etc/varnish/default.vcl # # Default address and port to bind to # Blank address means all IPv4 and IPv6 interfaces, otherwise specify # a host name, an IPv4 dotted quad, or an IPv6 address in brackets. VARNISH_LISTEN_PORT=80 # # Telnet admin interface listen address and port VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1 VARNISH_ADMIN_LISTEN_PORT=6082 # # Shared secret file for admin interface VARNISH_SECRET_FILE=/etc/varnish/secret # # The minimum number of worker threads to start VARNISH_MIN_THREADS=50 # # The Maximum number of worker threads to start VARNISH_MAX_THREADS=1000 # # Cache file size: in bytes, optionally using k / M / G / T suffix. VARNISH_STORAGE_SIZE=512M # # Backend storage specification VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}" # # Default TTL used when the backend does not specify one VARNISH_TTL=120 # # DAEMON_OPTS is used by the init script. DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \ -f ${VARNISH_VCL_CONF} \ -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \ -p thread_pool_min=${VARNISH_MIN_THREADS} \ -p thread_pool_max=${VARNISH_MAX_THREADS} \ -S ${VARNISH_SECRET_FILE} \ -s ${VARNISH_STORAGE}"
Vcl configuration file (/etc/varnish/default.vcl) could looks like:
vcl 4.0; backend default { .host = "127.0.0.1"; .port = "8080"; .first_byte_timeout = 600s; .connect_timeout = 600s; .between_bytes_timeout = 600s; } sub vcl_recv { set req.backend_hint = default; if (req.http.x-forwarded-for) { set req.http.X-Forwarded-For = req.http.X-Forwarded-For +",+ "+ client.ip; } else { set req.http.X-Forwarded-For = client.ip; } if (req.http.Accept-Encoding) { if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|mp4|swf)") { # No point in compressing these unset req.http.Accept-Encoding; } else if (req.http.Accept-Encoding ~ "gzip") { set req.http.Accept-Encoding = "gzip"; } else if (req.http.Accept-Encoding ~ "deflate") { set req.http.Accept-Encoding = "deflate"; } else { # unknown algorithm unset req.http.Accept-Encoding; } } if (req.method != "GET" && req.method != "HEAD" && req.method != "PUT" && req.method != "POST" && req.method != "TRACE" && req.method != "OPTIONS" && req.method != "DELETE") { /* Non-RFC2616 or CONNECT which is weird. */ return (pipe); } if (req.url ~ "M\=readBus") { return (pipe); } if (req.method != "GET" && req.method != "HEAD") { /* We only deal with GET and HEAD by default */ return (pass); } if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|mp4|swf|html|js|css|zip|pdf)") { unset req.http.Cookie; } if (req.url ~ "cache/bus/.*\.js") { return (pass); } return (hash); } sub vcl_pipe { set req.http.connection = "close"; set bereq.http.connection = "close"; return (pipe); } sub vcl_pass { return (fetch); } sub vcl_backend_response { unset beresp.http.X-Varnish; if (beresp.ttl < 2m) { set beresp.grace = 5m; } else { set beresp.grace = 15s; } if (beresp.http.content-type ~ "(text|javascript)") { set beresp.do_gzip = true; } if (beresp.ttl > 14400s) { set beresp.ttl=14400s; } # These status codes should always pass through and never cache. if (beresp.status >= 400 || !(beresp.ttl > 0s) || beresp.http.Cache-Control ~ "(private|no-cache|no-store)") { set beresp.ttl=0s; set beresp.uncacheable = true; return (deliver); } if (bereq.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|mp4|swf|html|js|css|zip|pdf)") { unset beresp.http.set-cookie; } return (deliver); } sub vcl_deliver { set resp.http.Vary= "Accept-Encoding"; set resp.http.Via= "1.1 varnish (1.lb-app.la.linode-sg)"; } sub vcl_miss { return (fetch); } sub vcl_backend_error { set beresp.http.Content-Type = "text/html; charset=utf-8"; set beresp.http.Retry-After = "60"; synthetic( {" <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <title>"} + beresp.status + " " + beresp.reason + {"</title> </head> <body> <h1>Error "} + beresp.status + " " + beresp.reason + {"</h1> <p>"} + beresp.reason + {"</p> <h3>Guru Meditation:</h3> <p>XID: "} + bereq.xid + {"</p> <hr> <p>Varnish cache server</p> </body> </html>"} ); return (deliver); }
3. Change in your apache configuration the port, where Apache will listen from 80 to 8080
4. Restart Apache and then start the Varnish service