HTTP Caching and PHP

655 views

Published on

Uncon talk at Dutch PHP Conference ’14

Published in: Software, Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
655
On SlideShare
0
From Embeds
0
Number of Embeds
22
Actions
Shares
0
Downloads
19
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

HTTP Caching and PHP

  1. 1. HTTP caching and PHP David de Boer
  2. 2. Hello DPC! • I’m David • Lead developer at Driebit, Amsterdam • Open source enthusiast
  3. 3. – Phil Karlton “There are only two hard things in Computer Science: cache invalidation and naming things.”
  4. 4. Why we cache • Reduce response times • Reduce server load • Cheap
  5. 5. How we cache Client App
  6. 6. Client AppCache How we cache
  7. 7. Efficient caching • Maximize cache hits • TTL ∞
 

  8. 8. GET  /apple  HTTP/1.1
 Host:  fresh-­‐fruit.com
 Connection:  close
 ...
 
 ! ! HTTP/1.1  200  OK
 Host:  fresh-­‐fruit.com
 X-­‐Cache:  HIT
 Age:  567648000
 ...
  9. 9. • Maximize cache hits • TTL ∞ • Invalidation Efficient caching
  10. 10. AppCache Let’s go invalidate
  11. 11. Cache • Varnish • Nginx
  12. 12. Varnish #  /etc/varnish/default.vcl   sub  vcl_hit  {
   if  (req.request  ==  "PURGE")  {
     purge;
          error  204  "Purged";
      }
 }   ! sub  vcl_miss  {
   if  (req.request  ==  "PURGE")  {
     purge;
     error  204  "Purged  (Not  in  cache)";
   }
 }
  13. 13. $  composer  require  friendsofsymfony/http-­‐cache  @alpha FOSHttpCache App
  14. 14. Connect and purge use  FOSHttpCacheProxyClientVarnish;
 
 $servers  =  ['10.0.0.1:6081'];
 $proxyClient  =  new  Varnish($servers);   $proxyClient
   -­‐>purge('/news/articles/42')
   -­‐>purge('/news')
   -­‐>flush();
  15. 15. Level up sub  vcl_recv  {     if  (req.request  ==  "BAN")  {       ban("obj.http.x-­‐host  ~  "  +  req.http.x-­‐host               +  "  &&  obj.http.x-­‐url  ~  "  +  req.http.x-­‐url         +  "  &&  obj.http.content-­‐type  ~  "  +  req.http.x-­‐content-­‐type       );   !     error  200  "Banned";     }   }   ! sub  vcl_fetch  {        #  Set  ban  lurker-­‐friendly  custom  headers     set  beresp.http.x-­‐url  =  req.url;        set  beresp.http.x-­‐host  =  req.http.host;   }
  16. 16. Level up use  FOSHttpCacheCacheInvalidator;   ! $invalidator  =  new  CacheInvalidator(
    $proxyClient
 );   ! $invalidator
    -­‐>invalidateRegex('.*',  'image/png')
    -­‐>invalidateRegex('^/admin')
   -­‐>flush();
  17. 17. Get organized • Complex relationships between URLs • Knowing when to invalidate what • Depends on application logic
  18. 18. Tagging sub  vcl_recv  {     if  (req.request  ==  "BAN")  {       if  (req.http.x-­‐cache-­‐tags)  {
       ban("obj.http.x-­‐host  ~  "  +  req.http.x-­‐host           +  "  &&  obj.http.x-­‐url  ~  "  +  req.http.x-­‐url                      +  "  &&  obj.http.content-­‐type  ~  "    +  req.http.x-­‐content-­‐type                      +  "  &&  obj.http.x-­‐cache-­‐tags  ~  "    +  req.http.x-­‐cache-­‐tags         );   
       error  200  "Banned";       }  else  {         #  ...       }     }   }   ! #  ...
  19. 19. Tagging //  overview.php
 header('Cache-­‐Control:  max-­‐age=3600');
 header('X-­‐Cache-­‐Tags:  art-­‐1,art-­‐2,art-­‐3');   ! ! //  article.php
 header('Cache-­‐Control:  max-­‐age=3600');
 header('X-­‐Cache-­‐Tags:  art-­‐2');   $invalidator-­‐>invalidateTags(['art-­‐2']);
  20. 20. use  FOSHttpCacheTestsVarnishTestCase;   ! class  MyTest  extends  VarnishTestCase
 {
   public  function  testHit()
   {       $first  =  $this-­‐>getResponse('/cached.php');       $this-­‐>assertMiss($first);       $second  =  $this-­‐>getResponse('/cached.php');       $this-­‐>assertHit($second);
    }
 } OK  (1  test,  2  assertions) Test-driven invalidation
  21. 21. Test-driven invalidation class  MyTest  extends  VarnishTestCase
 {
   public  function  testTags()
   {
     $miss  =  $this-­‐>getResponse('/article.php');
          $hit  =  $this-­‐>getResponse('/article.php');            $invalidator-­‐>invalidateTags(['art-­‐2']);
          $this-­‐>assertMiss($this-­‐>getResponse('/article.php'));
      }
 } OK  (1  test,  1  assertion)
  22. 22. Symfony bundle $  composer  require  friendsofsymfony/http-­‐cache-­‐bundle  @alpha   ! /**
  *  @InvalidateRoute("fruits-­‐overview",  params={"type"  =  "latest"})    *  @InvalidateRoute("fruits",  params={"num"  =  "id"})    */
 public  function  editAction($id)
 {     #  ...
 
 /**
  *  @Tag(expression="'fruit-­‐'~$id")
  */
 public  function  showAction($id)
 {     #  ...
  23. 23. Symfony bundle fos_http_cache:     cache_control:       rules:         -­‐           match:                           host:  ^login.example.com$           headers:             cache_control:               public:  false               s_maxage:  0               last_modified:  "-­‐1  hour"             vary:  [Accept-­‐Encoding,  Accept-­‐Language]         -­‐           match:             attributes:  {  _controller:  ^AcmeBundle:Default:.*  }             additional_cacheable_status:  [400]           headers:             cache_control:  {  public:  true,  max_age:  15,  s_maxage:  30  }  
  24. 24. Thanks! david@driebit.nl https://github.com/FriendsOfSymfony/ FOSHttpCache https://github.com/FriendsOfSymfony/ FOSHttpCacheBundle http://foshttpcache.readthedocs.org

×