Search

To speed up an already fast website and to protect it from traffic spikes, I've installed and configured Varnish to serve cached pages off my server.

So far the results are great: static content (images, css, js) is served much faster, and the load on my server when doing a benchmark is a lot less - probably because varnish is better at handling many requests at the same time, and it keeps less connections open to my webserver because they are on the same server and there is thus no latency.

There is one problem I am facing, though: cookies. At this moment Symphony is setting a session_id for every request, even though the session itself is never used. At this moment I solved it by removing the cookies for everything but the backend in the Varnish layer, and this seems to work OK.

However, I will be using the members plugin for pretty much every page - this means the general rule of removing all cookies will prevent all users from logging in.

Have you ever used Varnish (or any other reverse-proxy-cache) with Symphony? How did you get around the cookie thing?

Unfortunately, I have never used Varnish before, but ran across this Stack Overflow entry on how to get Varnish not to remove cookies.

Hopefully this helps.

@brian: Heh, I think I should have been a bit more concrete: I want to remove the cookies (otherwise Varnish won't cache the entry) but only so when the user is not authenticated (either in the backend or frontend). So a regular visitor will be greeted by a cached copy (of max. 30 mins old) while the content editor will always see the newest article he just entered.

The problem I am having is that the entire "auth" information is stored on the server, and there is no way to look at the cookies and know if you can strip them or not.

Thanks for the help though, really appreciated (oh, and, if you haven't tried Varnish yet: do so! The shear speed of it will rock your world:))

Have you taken a look at the wiki? You might work around Symphony's cookie behaviour (but I am not 100 percent sure):

Do you really need the session ID on every page? (It is definitely "yes" if for example you want to add the device type to the session using the Device Categorizr extension. In this case things will probably get rather complicated.)

Do you really need the session ID on every page?

Definitely not. That's the whole issue: the cookie is added regardless. I will need the session for every page if the user is logged in, though, so a url-based scheme won't really work.

I will need the session for every page if the user is logged in

And you can never test if he is logged in without passing the session ID to your app (i.e. Symphony, in this case). It's not mainly a Symphony problem, is it? It's a logical problem. Hard to crack.

BTW: Does Symphony really set a cookie if the browser sends a valid cookie? Have you tested this?

And you can never test if he is logged in without passing the session ID to your app (i.e. Symphony, in this case).

Exactly.

It's not mainly a Symphony problem, is it? It's a logical problem. Hard to crack.

Not really. The problem right now is that the session cookie is present even if there is no information inside the session (like auth information). A solution would be to unset the cookie if the session is empty, but I am not sure if that would have any unwanted side-effects.

A quick update; I've modified the Cookie class to only really start the session when there is data written to the session. This will probably give problems when extensions do not use the Cookie class to set session data but the normal $_SESSION array, but for testing purposes it works fine.

The result: all my standard pages are cached by Varnish, and as soon as I log in to the backend they are served by the webserver. Brilliant. Now, there is one thing: since the Cookie set by Symphony has a relatively long expire time (normal sessions time out when the browser is closed) users that visited the "old" website will not see the cached version for a while - until the Cookie expires and no new one is set. I could explicitly unset the cookie, but I might also port the change into the current code a few weeks before the launch - or just leave it be knowing at least my (JIT) assets will not require a PHP thread.

Something else: I've measured the performance with Blitz.io, but they only support loading a single page, which gives a skewed image. I'd much rather actually load a few pages with all the images, css, javascript like a browser (and user) does. Do you have suggestions here?

users that visited the "old" website will not see the cached version for a while

Won't this also happen to users that have a cookie set (because they have been logged in)? AFAIK, Varnish will not deliver cached content when the user's browser sends a cookie.

Won't this also happen to users that have a cookie set (because they have been logged in)?

Yes. But the only users that can login are content authors, and I don't mind sending the few authors I have an uncached version. So currently no cookies will be set if a random visitor visits the site, and they will get the cached version - whereas logged in users (me and a handful of other people) will see the uncached version.

The only thing I would really like to implement in the far-far future is removing edited pages from the cache directly allowing me to set a ttl of months for everything instead of the few seconds I have right now.

set a ttl of months for everything instead of the few seconds I have right now

Wow, you must hav a lot of traffic on this site!

Wow, you must hav a lot of traffic on this site!

Well, it depends on what you look at. Sustained traffic? Not really, maybe 10k requests per day. However, there are spikes of up to 150 requests per second when articles are featured on popular websites, or mentioned on twitter.

These spikes don't really last long, but still long enough to send a fair bit of visitors home disappointed without the caching layer, because Hiawatha (or apache) isn't able to handle the traffic. So the caching won't be actively used for the majority of requests (the cache will be stale before it is requested) but it does help me keep the website up.

And: I admit I dramatised the cache time a bit; currently the ttl is set to a minute - short enough for nobody to notice it, and long enough to keep my webserver alive :)

spikes of up to 150 requests per second

That is many. It should make you (and the owner) proud. And I see that caching will indeed help a lot for this website.

One more time: Wow!

@creativedutchmen - would you have time and be willing to share how you setup Varnish to work properly and efficiently with Symphony?

A quick update; I've modified the Cookie class to only really start the session when there is data written to the session. This will probably give problems when extensions do not use the Cookie class to set session data but the normal $_SESSION array, but for testing purposes it works fine.

I'd be interested in looking at this! This change was made some time ago to prevent an empty Session being written to the database. Although if I read your comments a little closer it's not this that's the problem, its the face a cookie is started in the browser?

@brian: sure! I am still fine-tuning the setup though, as it isn't quite perfect yet, but I'll be sure to share when I am finished.

@brendo: indeed, because Varnish does not cache anything when the request contains a cookie this is a real problem. There are workarounds - like removing the cookies on the request when the request is not symphony or debug - but they all depend on the URL, so if you need a few of your users to login (using Members) this approach won't work.

Varnish extension? I wish I had mad PHP skills and had a better grip of how to work with Varnish.

I ran across this interesting PHP toolkit for working with Varnish, https://github.com/timwhitlock/php-varnish and this Varnish for PHP Developers slide presentation (which has great resources at the end).

Very interesting resources Brian, thanks for posting.

Hmm @creativedutchmen, I wonder how this can be resolved. To see if one is logged into Symphony, a session has to be started to check for the existence (or lack of) credentials. I'm not sure if it's possible to start the Session, check for the existence, and if there isn't any, destroy the Session and prevent the cookie from being set by the browser.

Worth looking into. I wonder how other frameworks handle this scenario. I'm sure some clever people have used Varnish in these situations before :)

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details