The careerswales.com platform manages the education and professional progression of millions of people in Wales. When challenged with upgrading its ageing application stack to suit modern standards, we devised a solution with Symfony2 at its core. In this talk I'll discuss how the new stack was implemented, focussing on how we took advantage of Symfony2's first-class support for reverse-proxy Varnish to phase the deployment of the new system and improve performance by a significant amount. I'll also talk about the API we created to bridge its SQL Server / MySQL database platforms, and how Symfony2 was used to provide a single-sign-on solution across all of its web applications.
7. “Rewriting the code from scratch ... (is) the single
worst strategic mistake a software company can
make.”
- Joel Spolsky
8. “... the quick fix is like quicksand: The clarity of
code goes down and confusion is harvested in its
place.”
- Venkat Subramaniam and Andy Hunt
9. The Plan
Reduce cost, improve performance
Develop new application framework
Gradual deployment to careerswales.com
API to access shared data
Single sign on and shared sessions
14. Catalyst CMS
Cutting edge stack - PHP 5.4, Nginx, FPM
Reusable code through Symfony2 bundles
Inspired by Symfony2 CMF and Sonata
Fraction of the code to maintain
20. Single sign on
Single authentication system for all applications
Uses Central Authentication Service (CAS)
protocol
BeSimpleSsoAuthBundle does heavy lifting
Custom modifications via DI container
22. Varnish
Frontend proxy or HTTP accelerator
Sits between client and server
Shares cached responses between clients
Can perform load balancing and routing
29. ESI Caching
Edge Side Includes
Identifies blocks of HTML which are dynamic
Blocks are independent of the main response
Blocks can be cached and expired individually
Blocks can be identified as public (cacheable) or
private (not cacheable)
33. Carousel Block Caching
public function indexAction()
{
$response = new Response();
// cache for 1 minute
$response->setMaxAge(60);
$response->setPublic();
return $this->render(
'BoxUK:Default:index.html.twig',
array(),
$response
);
}
34. Login Button Caching
More complex: two different states
Can use varying to store two different caches
Use cookies to provide information to Varnish
BUT don’t want to vary on cookie
35. Login Button Caching
public function indexAction()
{
$response = new Response();
// cache for 1 minute
$response->setMaxAge(60);
$response->setPublic();
$response->setVary('Logged-In');
return $this->render(
'BoxUK:Default:index.html.twig',
array(),
$response
);
}
37. Login Button Caching
public function onKernelResponse(
FilterResponseEvent $event
)
{
$response = $event->getResponse();
$cookie = new Cookie('Logged-In',
$loggedIn, ...);
$response
->headers
->setCookie($cookie);
}
38. Login Button Caching
if (req.http.Cookie ~ 'Logged-In=true') {
set req.http.Logged-In = 'true';
}
Varnish cache keys are hashed on URL (host, path,
etc) and vary data
Symfony takes care of the way out
On the way in, we have to fake the header to
reproduce the hash
39. Routing
Varnish directs requests to given ‘backends’
Load balancing, e.g. round robin
More complex logic via VCL (Varnish Configuration
Language)
No EC2 load balancers!
46. Conclusions
Observable speed increase of 560%No loss of
functionality or downtime
No loss of functionality or downtime
Substantially less ‘hardware’
More complex environment