Slide 1

Slide 1 text

Роман Лапин, Evercode Lab [email protected] @memphys Изучаем HTTP Cache с Symfony2

Slide 2

Slide 2 text

Что такое кэш?

Slide 3

Slide 3 text

Что представляет моя мама

Slide 4

Slide 4 text

Что представляют мои друзья

Slide 5

Slide 5 text

Что подсказывает google

Slide 6

Slide 6 text

Что такое кэш на самом деле Промежуточное хранение данных и результатов для ускорения повторных запросов к ним.

Slide 7

Slide 7 text

Что такое HTTP Cache HTTP Specification – RFC 2616, Section 13

Slide 8

Slide 8 text

Что такое HTTP Cache “Web caching is one of the most misunderstood technologies on the Internet.” http://www.mnot.net/cache_docs/

Slide 9

Slide 9 text

Немного статистики http://httparchive.org/interesting.php?a=All&l=Nov%201%202012#max-age

Slide 10

Slide 10 text

Немного статистики http://httparchive.org/trends.php?s=All&minlabel=Nov+1+2011&maxlabel=Nov+1+2012#maxageNull

Slide 11

Slide 11 text

Немного статистики

Slide 12

Slide 12 text

Почему это важно •Latency •Traffic •CPU •Cash •Happiness

Slide 13

Slide 13 text

Типы HTTP Cache

Slide 14

Slide 14 text

Browser

Slide 15

Slide 15 text

Proxy Internet

Slide 16

Slide 16 text

Proxy

Slide 17

Slide 17 text

Gateway (reverse proxy) Internet

Slide 18

Slide 18 text

Gateway (reverse proxy)

Slide 19

Slide 19 text

Public vs Private

Slide 20

Slide 20 text

Safe Methods •GET & HEAD •Приложение не меняет состояние •PUT, POST и DELETE не кэшируются

Slide 21

Slide 21 text

Заголовки ответов

Slide 22

Slide 22 text

Заголовки ответов •Cache-Control •Expires •ETag •Last-Modified

Slide 23

Slide 23 text

Symfony2?

Slide 24

Slide 24 text

Заголовки ответов. API $response = new Response(); $response->setPublic(); $response->setPrivate(); $response->setMaxAge(600); $response->setSharedMaxAge(600); $response->headers->addCacheControlDirective('must-revalidate', true); $response->setExpires($date); $response->setETag(md5($response->getContent())); $response->setLastModified($date);

Slide 25

Slide 25 text

Заголовки ответов. API $response->expire(); $response->setNotModified(); // Set cache settings in one call $response->setCache(array( 'etag' => $etag, 'last_modified' => $date, 'max_age' => 10, 's_maxage' => 10, 'public' => true, // 'private' => true, ));

Slide 26

Slide 26 text

Symfony2 Reverse Proxy

Slide 27

Slide 27 text

loadClassCache(); // wrap the default AppKernel with the AppCache one $kernel = new AppCache($kernel); $request = Request::createFromGlobals(); $response = $kernel->handle($request); $response->send(); $kernel->terminate($request, $response); Symfony2 Reverse Proxy

Slide 28

Slide 28 text

Symfony2 Reverse Proxy It’s that easy!

Slide 29

Slide 29 text

// app/AppCache.php use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache; class AppCache extends HttpCache { protected function getOptions() { return array( 'debug' => false, 'default_ttl' => 0, 'private_headers' => array( 'Authorization', 'Cookie' ), 'allow_reload' => false, 'allow_revalidate' => false, 'stale_while_revalidate' => 2, 'stale_if_error' => 60, ); } } Symfony2 Reverse Proxy

Slide 30

Slide 30 text

HTTP Expiration and Validation

Slide 31

Slide 31 text

Expiration http://www.flickr.com/photos/urbancamper/

Slide 32

Slide 32 text

$date = new DateTime(); $date->modify('+3600 seconds'); $response->setExpires($date); Expires: Thu, 01 Mar 2011 16:00:00 GMT Expiration c Expires •Date header •<= 1 год

Slide 33

Slide 33 text

// set the private or shared max age $response->setMaxAge(3600); $response->setSharedMaxAge(3600); Cache-Control: max-age=3600, s-maxage=3600 Expiration c Cache control

Slide 34

Slide 34 text

Validation http://www.flickr.com/photos/my-photos-for-all/

Slide 35

Slide 35 text

public function indexAction() { $response = $this->render('MyBundle:Main:index.html.twig'); $response->setETag(md5($response->getContent())); $response->setPublic(); $response->isNotModified($this->getRequest()); return $response; } Validation c ETag

Slide 36

Slide 36 text

$projectDate = new \DateTime($latestProject->getUpdatedAt()); $response->setLastModified($projectDate); $response->setPublic(); if ($response->isNotModified($this->getRequest())) { return $response; } // ... more work with content of the response or just render return $response; Validation c Last-Modified

Slide 37

Slide 37 text

Edge Side Includes

Slide 38

Slide 38 text

# app/config/config.yml framework: # ... esi: { enabled: true } # app/config/routing.yml _internal: resource: "@FrameworkBundle/Resources/config/routing/ internal.xml" prefix: /_internal ESI

Slide 39

Slide 39 text

public function indexAction() { $response = $this->render( 'AppDefaultBundle:Default:index.html.twig' ); // marks the response as public $response->setSharedMaxAge(30*24*60*60); return $response; } ESI

Slide 40

Slide 40 text

{% render 'AppMainBundle:Default:blog', {'standalone': true} %} public function blogAction() { // ... $response->setSharedMaxAge(3*24*60*60); } ESI

Slide 41

Slide 41 text

{% render "KnpLastTweetsBundle:Twitter:lastTweets" with {'username': 'evercodelab', 'limit': 3, 'age': 12*60*60}, {'standalone': true} %} ESI

Slide 42

Slide 42 text

Cache Invalidation

Slide 43

Slide 43 text

•Инвалидация HTTP Cache не нужна •если все сделано правильно •Специфична для каждого reverse proxy •PURGE HTTP Method Cache Invalidation

Slide 44

Slide 44 text

Пример

Slide 45

Slide 45 text

Пример

Slide 46

Slide 46 text

Пример •Клиенты и проекты •Блог •Twitter •indexAction — 30 дней •Блог — 3 дня •Twitter — 12 часов s-maxage

Slide 47

Slide 47 text

Пример

Slide 48

Slide 48 text

Что почитать •Caching Tutorial (http://www.mnot.net/cache_docs/) •Web Cache (http://en.wikipedia.org/wiki/Web_cache) •HTTP Cache (http://symfony.com/doc/2.0/book/http_cache.html) •Cache them if you can (http://www.stevesouders.com/blog/ 2012/03/22/cache-them-if-you-can/) •Things Caches Do (http://tomayko.com/writings/things-caches- do)

Slide 49

Slide 49 text

“The fastest HTTP request is the one not made.” Немного философии

Slide 50

Slide 50 text

Вопросы? Роман Лапин, Evercode Lab [email protected] @memphys Спасибо!