Sf sf v5

Post on 30-Nov-2014

1,182 views 0 download

Tags:

description

PErfor

transcript

Nice performance using SF2 cache wrapping sf1

application

Marc Weistroff \ Emmanuel CohenSf Live \ SF 2011

Thursday, March 3 2011

Who we are

Emmanuel Cohen Project manager at Sensio Labs 4 year experience with PHP5 5+ year experience with Java EE Learned Basic on Amstrad CPC 6128

Who we are

Marc Weistroff Developer at Sensio Labs since 11/2009 Lead developer on this project Experiences with C, and PHP from version 3 Encountered programming with Amos Basic on

Amiga 500

This talk

Symfony2 symfony 1 HTTP Cache Edge Side Includes (ESI) Web architecture Online media

Our client

L’Express Magazine Express-Roularta Group Magazine created in 1953

http://www.lexpress.fr Top 3 French online news Need for speed!

The project

A cultural knowledge base

A bridge between hot news and cultural knowledge

An extension of www.lexpress.fr

Technical objectives

Performance

A full scale Proof-of-Concept for the future

Keep it Simple

Constraints

Heterogeneous XML Sources

Solution based on symfony 1

Adaptability (for future extensions)

How does this app work ?

Our symfony 1 application design

HTML Renderer

XML Server

OCARI CultureOCARI Content

• Stores• Normalizes• Aggregates• Serves XML

Sources deliverheterogeneousdata

•Renders HTML with XSL•Renders static layouts

Our symfony 1 application design

Highly specialized applications

Loose coupling

Front dedicated to delivering content fast

Addressing performance with Symfony2

Addressing performance with Sf2

With Symfony2 built-in Gateway :

HTTP cache ESI : Edge Side Includes

Performance with Symfony2 : HTTP Cache

HTTP RFC

http://tools.ietf.org/wg/httpbis/

http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-12

Performance with Symfony2 : HTTP Cache

Symfony2 uses HTTP cache headers to handle cache

s-maxage or max-age Etag, Last-Modified, If-Modified-Since

http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-12

Performance with Symfony2 : HTTP Cache

symfony 1 Applicative cache

Symfony2 Light-weight

HttpKernel The application is not

hit Supports a standard

Find out what’s stale The problem of invalidation

Performance with Symfony2: Cache issues

Selective caching Do not regenerate the whole page when you just

need to regenerate small parts of it

Performance with Symfony2: Cache issues

Performance with Symfony2: ESI

Edge-Side include: A markup language

W3C note from Akamai

http:// www.w3.org/TR/esi-langhttp:// www.akamai.com/html/support/esi.html

ESI : A page in lexpress.fr

Performance with Symfony2: ESI

Each fragment has its own ttl or validation rule => the fragments are selectively refreshed

Performance with Symfony2: ESI

Dependance is defined once and for all

In expiration: simply set your ttl for each fragment

How does ESI work?

Performance with Symfony2: ESI

Represented by an HTML Tag• <esi:include src=“/movie/dogma/critics” />

Processed by a proxy Transformed into HTTP Request to the application Response is inserted in place of the esi tag HTTP cache is handled independently for each esi

tag

/movie/dogma

/movie/dogma

Html Fragment

Pure HTML Inserted in lieu of the

<esi /> tag No <html>, <body>

or <head> tag in this case

What you need

Any client! A proxy that handles ESI (ie: Varnish or Symfony2) An application that delivers HTML and HTTP cache

headers Serve HTML pages that contain ESI tags

First request ever

ClientClient ProxyProxy ApplicationApplication

/movie/dogma /movie/dogma

miss

Cache-Control: s-maxage=600

/movie/dogma/casting

/movie/dogma/critics

Cache-Control: s-maxage=3600

Cache-Control: s-maxage=300

Request at t+200

ClientClient ProxyProxy ApplicationApplication

/movie/dogma

hit

The application is never hit!

As if the complete page was cached in the reverse proxy

Request at t+500

ClientClient ProxyProxy ApplicationApplication

/movie/dogma

/movie/dogma/critics

Cache-Control: s-maxage=300

hit

The application is partially hit

And has to build only a small fragment of the page

Pros

You use HTTP cache, not the application one. Performance improvements! Granularity: Different cache strategy or TTL on

different parts of your page

Cons

Your app will be hit n times upon the very first request

Your app have to be designed to support the rendering of fragments

But our app is symfony 1 right ?

What to do with your symfony 1 application when you are dying to use Symfony2?

Wrap it.

Our app is symfony 1

Our symfony 1 application design

HTML Renderer

XML Server

OCARI CultureOCARI Content

• Stores• Normalizes• Aggregates• Serves XML

Sources deliverheterogeneousdata

•Renders HTML with XSL•Renders static layouts

Symfony1 wrapper

Edge side Symfony2

Wrapping symfony 1 with Symfony2

Constraint

We use the Symfony2 ESI/Cache proxy All the call to our app is done in the same PHP

process

symfony 1 needs tweaking in order to work around a few obstacles

Which ones ?

It is not reentrant• sfConfig singleton• sfContext singleton

It sends the response directly to the client• Filter chain execution• At the end, sfRenderingFilter sends the complete response

What about Symfony2?

Better architecture: Symfony2 is reentrant Symfony2 is heavily based on interfaces Symfony2 is divided into several components HttpKernel\HttpKernelInterface

HttpKernel\HttpKernelInterface

Lightweight (1 method) Forces to implement a “handle” method that

accepts a Symfony2 Request object and returns a Symfony2 Response object

Used by all the classes that act as a Kernel in Symfony2 (ie: HttpKernel\HttpCache)

Addressing the issues

Reentrance• Override the super globals• Create a fresh new context each time

Filter chain• Replace sfRenderingFilter by a noRenderingFilter class

Create a Symfony2 Response object and returns it

Final app architecture

EsiCacheKernelEsiCacheKernel

SymfonyWrapperKernelSymfonyWrapperKernel

symfony 1applicationsymfony 1application

https://github.com/marcw/sflive-2011

Then…

You have to design your app to serve HTML fragments!

Designing your app

Don’t think partials or components, think actions! Actions render HTML fragments Actions MUST define explicitly the response cache

headers.

And now where happy

Or are we ?

Our choices

The choice of symfony 1 The choice of Symfony2 The choice to mix Expiration over validation

This is symfony1 : DO NOT TRY ANY OF THIS AT HOME!

Our results

It works! The frontend is scalable and extensible Performance is nice, but we needed to improve the

Store.php class

What to do next ?

Implementing cache validation

The application needs to garantee freshness How to avoid hitting the application ?

Proxy ESI

New responseOr304

URL-> {ETag}ETag-> lastmodified

If Etag absentor stale

Response with HTTP headersEtagLastModified

Client

Request withHTTP headersIf-None-MatchIf-Modified-Since

App

New responseOr304

If cache entry is not fresh enough

Cache Validati

on Optimiz

er

Contact @ L’Express

Sébastien Angèle sangele@groupe-exp.com

Jérôme Macias jmacias@groupe-exp.com

Questions ?

Marc Weistroff @futurecat marc.weistroff@sensio.com http://www.marcw.net

Emmanuel Cohen @emmanuelcohen emmanuel.cohen@sensio.com

Thank you!

Please rate this talk athttp://joind.in/2749