This document provides an overview of using caching to serve visitor-specific content quickly while avoiding server-side sessions. It discusses using HTTP caching headers, a reverse proxy like Varnish, and the Symfony cache to cache responses varying by target groups identified in request cookies. The target groups are reevaluated on cache hits by making conditional requests in the reverse proxy layer using Varnish configuration.
10. 200 OK
Cache-Control: max-age=240
200 OK
X-Reverse-Proxy-TTL: 2400
200 OK
Cache-Control: max-age=240
Browser
Reverse
Proxy
Symfony
Application
GET / GET /
Browser
GET /
PURGE /
GET /
200 OK
X-Reverse-Proxy-TTL: 2400
13. // src/CacheKernel.php
<?php
namespace App;
use SymfonyBundleFrameworkBundleHttpCacheHttpCache;
class CacheKernel extends HttpCache {}
// public/index.php
<?php
use AppKernel;
use AppCacheKernel;
// ...
$kernel = new Kernel($env, $debug);
$kernel = new CacheKernel($kernel);
// ...
14. // src/Controller/NameController.php
<?php
namespace AppController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAnnotationRoute;
class NameController {
/**
* @Route("/name/{name}")
*/
public function index(string $name) {
$response = new Response('Your name is ' . $name);
$response->setSharedMaxAge(3600);
return $response;
}
}
15. – Harder to setup
– Implemented in C
– Super performant
– Many more features
– Configured using VCL
Varnish
16. Varnish Installation
1. Actually install varnish
2. Start varnish on port 80
3. Start your application on a different port
4. Tell varnish on which port your application is running
5. Add varnish as a trusted proxy in Symfony
6. Add cache headers to your responses
7. Configure the cache with VCL in more detail
17. # default.vcl
vcl 4.0;
# Default backend definition. Set this to point to your content server.
backend default {
.host = "127.0.0.1";
.port = "8080";
}
4
19. // src/Controller/NameController.php
<?php
namespace AppController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAnnotationRoute;
class NameController {
/**
* @Route("/name/{name}")
*/
public function index(string $name) {
$response = new Response('Your name is ' . $name);
$response->setSharedMaxAge(3600);
return $response;
}
} 6
20. # default.vcl
sub vcl_recv {
# Happens before we check if we have this in cache already.
#
# Typically you clean up the request here, removing cookies you don't need,
# rewriting the request, etc.
}
sub vcl_deliver {
# Happens when we have all the pieces we need, and are about to send the
# response to the client.
#
# You can do accounting or modifying the final object here.
}
7
23. Audience Targeting
Goals
– Differentiate between different visitor target groups
– Target groups are evaluated by a ruleset
– first visit
– each browser session
– each hit
– Do not start a session on the server
– Cache the response per target group
28. Browser
Reverse
Proxy
Symfony
Application
GET /en
Accept-Encoding: gzip
200 OK
Vary: Accept-Encoding
GET /en
Accept-Encoding: identity
200 OK
Cache-Control: max-age=0
GET /en
Accept-Encoding: gzip
200 OK
Vary: Accept-Encoding
GET /en
Accept-Encoding: gzip
200 OK
Vary: Accept-Encoding
Browser
200 OK
Vary: Accept-Encoding
GET /en
Accept-Encoding: identity