grâce aux tags varnish, j'ai switché ma prod sur raspberry pi
TRANSCRIPT
![Page 1: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/1.jpg)
Going to production ona Raspberry Pi with
varnish tags
![Page 2: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/2.jpg)
Who am I?
Jérémy DERUSSÉ
Web Technical Leader
AptusHealth
@jderusse
![Page 3: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/3.jpg)
How to get fast responsesfrom a Symfony application?
you can't
![Page 4: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/4.jpg)
How to get fast responsesfrom a Symfony application?your backend
you can't
![Page 5: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/5.jpg)
Solution
using http shared cachedescribe in RFC-2616 RFC-7234
![Page 6: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/6.jpg)
Integration in Symfonyuse Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache; /** * @Cache(smaxage="3600") */ public function indexAction() { // ... }
Advanced usage with FriendsOfSymfony/FOSHttpCacheBundle
![Page 7: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/7.jpg)
Issue #1Unsharable resources
private resources (ie. invoice, shopping cart, ...)per role representations
Solutionvary cache on user/role/othersee SfLive 2015 Jérôme Vieilledent & David Buchmann Repousser les limites : HTTP cache et utilisateurs connectés
![Page 8: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/8.jpg)
Issue #2Cache invalidation
“ There are only two hard things in Computer Science: cacheinvalidation and naming things.
Phil Karlton
![Page 9: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/9.jpg)
Cache models
Validation modeletaglast-modified
drawbacks
application is bootedhard to implement
Expiration modelexpirescache-control
drawback
no control on invalidation
![Page 10: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/10.jpg)
cache modelIn a real world
Backend can't validate every cache HITLife time is not predictable
BUT
Varnish can be requested to partially invalidate responsesBackend knows when resources changeResponses are build on top of resources
![Page 11: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/11.jpg)
curl -I "http://varnish.myapp.com/c"
curl -I "http://varnish.myapp.com/b"
curl -I "http://varnish.myapp.com/a"
HTTP/1.1 200 OK Cache-Control: public, s-maxage=3600 X-Cache-Tags: Foo,Bar
HTTP/1.1 200 OK Cache-Control: public, s-maxage=3600 X-Cache-Tags: Foo
Varnish tags
curl \ -X "BAN" \ -H "X-Cache-Tags: Foo" \ "http://varnish.myapp.com"
HTTP/1.1 200 OK Cache-Control: public, s-maxage=3600 X-Cache-Tags: Bar,Qux
![Page 12: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/12.jpg)
Varnish tagscurl "http://varnish.myapp.com/posts/42"
HTTP/1.1 200 OK Cache-Control: public, s-maxage=86400 X-Cache-Tags: Post:42,Author:12,Comment:314,Comment:1337 { "id": 42, "title": "My blog post.", "body": "Lorem Ipsum.", "author": { "id": 12, "username": "jderusse" }, "comments": [ { "id": 314, "message": "Wow such post" }, { "id": 1337, "message": "much performance" } ] }
![Page 13: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/13.jpg)
Automate Tagging
Tagging Response1. Collect displayed resources2. Generate resource identifier3. Tag response
![Page 14: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/14.jpg)
Automate TaggingTagging Response - 1. Collect displayed resources
namespace App\EventListener; use JMS\Serializer\EventDispatcher\Events; use JMS\Serializer\EventDispatcher\EventSubscriberInterface; use JMS\Serializer\EventDispatcher\ObjectEvent; class SerializationTagListener implements EventSubscriberInterface { public function onPostSerialize(ObjectEvent $event) { $resource = $event->getObject(); // TODO } public static function getSubscribedEvents() { return [ [ 'event' => Events::POST_SERIALIZE, 'format' => 'json', 'method' => 'onPostSerialize', ], ]; } }
![Page 15: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/15.jpg)
Automate TaggingTagging Response - 2. Generate resource identifier
namespace App\EventListener; use App\Tag\TagExtractorInterface; use FOS\HttpCacheBundle\Handler\TagHandler; use JMS\Serializer\EventDispatcher\EventSubscriberInterface; use JMS\Serializer\EventDispatcher\ObjectEvent; class SerializationTagListener implements EventSubscriberInterface { private $tagExtractor; public function __construct(TagExtractorInterface $tagExtractor) { $this->tagExtractor = $tagExtractor; } public function onPostSerialize(ObjectEvent $event): void { //... $tags = $this->tagExtractor->extract($event->getObject()); } //... }
![Page 16: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/16.jpg)
Automate TaggingTagging Response - 3. Tag response
namespace App\EventListener; use App\Tag\TagExtractorInterface; use FOS\HttpCacheBundle\Handler\TagHandler; use JMS\Serializer\EventDispatcher\EventSubscriberInterface; use JMS\Serializer\EventDispatcher\ObjectEvent; class SerializationTagListener implements EventSubscriberInterface { private $tagExtractor; private $tagHandler; public function __construct(TagExtractorInterface $tagExtractor, TagHandler $tagHandler) { $this->tagExtractor = $tagExtractor; $this->tagHandler = $tagHandler; } public function onPostSerialize(ObjectEvent $event): void { $tags = $this->tagExtractor->extract($event->getObject()); $this->tagHandler->addTags($tags); } //... }
![Page 17: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/17.jpg)
Automate Tagging
Tagging Response1. Collect displayed resources2. Generate resource identifier3. Tag response
Invalidate cache1. Listen changes2. Generate resource identifier3. Call varnish
![Page 18: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/18.jpg)
Automate TaggingInvalidate Cache - 1. Listen changes
namespace App\EventListener; use Doctrine\Common\EventSubscriber; use Doctrine\ORM\Event\OnFlushEventArgs; use Doctrine\ORM\Events; class DoctrineInvalidationTagListener implements EventSubscriber { public function getSubscribedEvents() { return [Events::onFlush]; } public function onFlush(OnFlushEventArgs $eventArgs) { $uow = $eventArgs->getEntityManager()->getUnitOfWork(); foreach ($uow->getScheduledEntityUpdates() as $resource) { // TODO } foreach ($uow->getScheduledEntityDeletions() as $resource) { // TODO } } }
![Page 19: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/19.jpg)
Automate TaggingInvalidate Cache - 2. Generate resource identifier
namespace App\EventListener; use App\Tag\TagExtractorInterface; use Doctrine\Common\EventSubscriber; class DoctrineInvalidationTagListener implements EventSubscriber { private $tagExtractor; public function __construct(TagExtractorInterface $tagExtractor) { $this->tagExtractor = $tagExtractor; } public function onFlush(OnFlushEventArgs $eventArgs) { $uow = $eventArgs->getEntityManager()->getUnitOfWork(); $tags = []; foreach ($uow->getScheduledEntityUpdates() as $resource) { $tags = array_merge($tags, $this->tagExtractor->extract($resource)); } foreach ($uow->getScheduledEntityDeletions() as $resource) { $tags = array_merge($tags, $this->tagExtractor->extract($resource)); } // TODO } }
![Page 20: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/20.jpg)
Automate TaggingInvalidate Cache - 3. Call varnish
namespace App\EventListener; use App\Tag\TagExtractorInterface; use Doctrine\Common\EventSubscriber; use FOS\HttpCache\Handler\TagHandler; class DoctrineInvalidationTagListener implements EventSubscriber { private $tagExtractor; public function __construct(TagExtractorInterface $tagExtractor, TagHandler $tagHandler) { $this->tagExtractor = $tagExtractor; $this->tagHandler = $tagHandler; } public function onFlush(OnFlushEventArgs $eventArgs) { // ... $this->tagHandler->invalidateTags($tags); } }
![Page 21: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/21.jpg)
Automate Tagging
Tagging Response1. Collect displayed resources2. Generate resource identifier3. Tag response
Invalidate cache1. Listen changes2. Generate resource identifier3. Call varnish
Enjoy
![Page 22: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/22.jpg)
Silver bullet?
Works well whenHIT >> MISSRead >> WriteApplication knows resources used to buildresponse
DrawbackOperations are not AtomicB ackend handles writesBackend knows infrastructureIt slows writes
![Page 23: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/23.jpg)
Demo
Software - env=dev
- fetch=lazy
symfony/symfonydoctrine/doctrine-bundle
friendsofsymfony/rest-bundlejms/serializer-bundle
friendsofsymfony/http-cache-bundle
marmelab/admin-on-rest
![Page 24: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/24.jpg)
Demo
HardwareRaspberry Pi Orange Pidocker
MySQLNGINXPHP7-FPMVarnish
$9.59
![Page 25: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/25.jpg)
Demo
![Page 26: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/26.jpg)
ab -n 8000 -c 26 192.168.1.17:81/comments/1This is ApacheBench, Version 2.3 <$Revision: 1757674 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.netLicensed to The Apache Software Foundation, http://www.apache.org/
Server Software: nginx/1.10.3Server Hostname: 192.168.1.16Server Port: 80
Document Path: /comments/1Document Length: 576 bytes
Concurrency Level: 26Time taken for tests: 26.912 secondsComplete requests: 200Failed requests: 0Total transferred: 193400 bytesHTML transferred: 115200 bytesRequests per second: 7.43 [#/sec] (mean)Time per request: 3498.553 [ms] (mean)Time per request: 134.560 [ms] (mean, across all concurrentTransfer rate: 7.02 [Kbytes/sec] received
Connection Times (ms) min mean[+/-sd] median maxConnect: 1 2 1.4 1 6Processing: 546 3342 1156.7 3020 7204Waiting: 546 3342 1156.7 3020 7204Total: 550 3344 1156.5 3021 7205
in numbers
ab -n 8000 -c 26 192.168.1.17/comments/1This is ApacheBench, Version 2.3 <$Revision: 1757674 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.netLicensed to The Apache Software Foundation, http://www.apache.org/
Server Software: nginx/1.10.3Server Hostname: 192.168.1.17Server Port: 80
Document Path: /comments/1Document Length: 576 bytes
Concurrency Level: 26Time taken for tests: 2.340 secondsComplete requests: 8000Failed requests: 0Total transferred: 8948504 bytesHTML transferred: 4608000 bytesRequests per second: 3418.52 [#/sec] (mean)Time per request: 7.606 [ms] (mean)Time per request: 0.293 [ms] (mean, across all concurrentTransfer rate: 3734.21 [Kbytes/sec] received
Connection Times (ms) min mean[+/-sd] median maxConnect: 0 2 0.8 2 7Processing: 2 5 3.3 5 55Waiting: 2 5 3.3 4 55Total: 2 8 3.3 7 56
app varnish
![Page 27: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/27.jpg)
Thank You
![Page 28: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/28.jpg)
Questions?
![Page 29: Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi](https://reader033.vdocuments.site/reader033/viewer/2022052418/58eb8deb1a28ab10188b4571/html5/thumbnails/29.jpg)
Credits
http://linuxgizmos.com/10-dollar-orange-pi-one-pits-quad-core-cortex-a7-against-pi-zero/http://toutsurlesbisounours.centerblog.net/rub-bisounours-3eme-generation-.htmlhttps://de.wikipedia.org/wiki/Carambarhttps://rcgo.com.br/recursos.html