{"id":20393,"date":"2023-03-29T05:00:00","date_gmt":"2023-03-29T03:00:00","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=20393"},"modified":"2024-07-22T15:04:26","modified_gmt":"2024-07-22T13:04:26","slug":"jak-wytrzymac-swiateczne-obciazenie-klasycznie-reaktywnie-czy-z-uzyciem-korutyn","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/jak-wytrzymac-swiateczne-obciazenie-klasycznie-reaktywnie-czy-z-uzyciem-korutyn\/","title":{"rendered":"Jak wytrzyma\u0107 \u015bwi\u0105teczne obci\u0105\u017cenie? Klasycznie, reaktywnie czy z u\u017cyciem korutyn?"},"content":{"rendered":"\n<p>Buduj\u0105c aplikacj\u0119, nale\u017cy pami\u0119ta\u0107 o tym, by by\u0142a ona wydajna, niezawodna oraz odporna na obci\u0105\u017cenie. \u017beby to uzyska\u0107, stosuje si\u0119 skalowanie wertykalne (dodawanie RAM oraz CPU) i horyzontalne (dodawanie wi\u0119kszej liczby instancji w po\u0142\u0105czeniu z Load Balancerem). Oczekujemy, \u017ce aplikacja b\u0119dzie odpowiada\u0142a z mo\u017cliwie nisk\u0105 latencj\u0105 (czasem odpowiedzi). <strong>Wydajno\u015b\u0107 stron oraz przetwarzania \u017c\u0105da\u0144 wp\u0142ywa znacz\u0105co na odczucia u\u017cytkownika<\/strong>.<\/p>\n\n\n\n<p><a href=\"https:\/\/www.awwwards.com\/brainfood-mobile-performance-vol3.pdf\" target=\"_blank\" aria-label=\"Wed\u0142ug bada\u0144 Google\u2019a z 2018 (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Wed\u0142ug bada\u0144 Google\u2019a z 2018<\/a>, prawie 80% os\u00f3b robi\u0105cych zakupy online, kt\u00f3re spotka\u0142y si\u0119 z problemem wolnego \u0142adowania strony, zadeklarowa\u0142o, \u017ce nie wr\u00f3ci ju\u017c na zakupy na dan\u0105 stron\u0119. Blisko po\u0142owa klient\u00f3w oczekuje, \u017ce strona za\u0142aduje si\u0119 w ci\u0105gu 2 sekund lub kr\u00f3cej. Je\u015bli dana witryna nie otworzy si\u0119 w ci\u0105gu 3 sekund, 53% u\u017cytkownik\u00f3w j\u0105 opu\u015bci.<\/p>\n\n\n\n<p>To pokazuje, jak istotne jest dbanie o szybko\u015b\u0107 dzia\u0142ania aplikacji niezale\u017cenie od obci\u0105\u017cenia. Dla u\u017cytkownika nie ma znaczenia, \u017ce trwa akurat np. okres \u015bwi\u0105teczny, wi\u0119c jest wzmo\u017cony ruch na platformach zakupowych. Klient zawsze oczekuje, \u017ce strony oraz przetwarzanie \u017c\u0105da\u0144 b\u0119dzie realizowane mo\u017cliwie szybko.<\/p>\n\n\n\n<p>Tworz\u0105c aplikacj\u0119 wykorzystuj\u0105c\u0105 framework Spring, mamy do wyboru kilka API, kt\u00f3re odpowiadaj\u0105 na powy\u017csze potrzeby.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Podej\u015bcie imperatywne \u2013 klasyczne<\/strong><\/h2>\n\n\n\n<p>Buduj\u0105c Springow\u0105 aplikacj\u0119 umo\u017cliwiaj\u0105c\u0105 komunikacj\u0119 REST-ow\u0105, najcz\u0119\u015bciej si\u0119gamy po rozwi\u0105zanie, jakim jest u\u017cycie webowego starteru wraz z wbudowanym kontenerem servlet\u00f3w <strong>Tomcat.<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n&lt;dependency&gt;\n   &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n   &lt;artifactId&gt;spring-boot-starter-webflux&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n<\/pre><\/div>\n\n\n<p>Ka\u017cde \u017c\u0105danie HTTP przychodz\u0105ce do aplikacji jest w tym przypadku przypisywane do jednego w\u0105tku z puli. Tomcat domy\u015blnie posiada takich w\u0105tk\u00f3w 200.<\/p>\n\n\n\n<p>Gdy pula tych w\u0105tk\u00f3w zostanie wykorzystana, kolejne \u017c\u0105dania HTTP zostaj\u0105 zakolejkowane i oczekuj\u0105 na zwolnienie si\u0119 w\u0105tku. Mo\u017cemy obliczy\u0107 przybli\u017con\u0105 warto\u015b\u0107 obci\u0105\u017cenia (tzw. Throughput) liczon\u0105 w \u017c\u0105daniach na sekund\u0119 RPS (Requests Per Second), jak\u0105 jest w stanie przyj\u0105\u0107 aplikacja, stosuj\u0105c wz\u00f3r:<\/p>\n\n\n\n<p>throughput = liczba w\u0105tk\u00f3w \/ \u015bredni czas obs\u0142ugi \u017c\u0105dania<\/p>\n\n\n\n<p>W idealnej sytuacji, maj\u0105c do dyspozycji 200 w\u0105tk\u00f3w oraz czas obs\u0142ugi ka\u017cdego z nich wynosz\u0105cy 500ms, serwer jest w stanie obs\u0142u\u017cy\u0107: 200req\/500ms = 400RPS.<\/p>\n\n\n\n<p>Zostawiaj\u0105c domy\u015bln\u0105 pul\u0119 w\u0105tk\u00f3w na poziomie 200 oraz chc\u0105c obs\u0142u\u017cy\u0107 wi\u0119ksze obci\u0105\u017cenie, nale\u017cy albo skr\u00f3ci\u0107 czas obs\u0142ugi pojedynczego \u017c\u0105dania albo do\u0142o\u017cy\u0107 kolejn\u0105 instancj\u0119 serwisu.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Podej\u015bcie reaktywne<\/strong><\/h2>\n\n\n\n<p>Wraz z projektem Reactor mo\u017cliwe jest pisanie kodu nieblokuj\u0105cego:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n&lt;dependency&gt;\n   &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n   &lt;artifactId&gt;spring-boot-starter-webflux&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n<\/pre><\/div>\n\n\n<p>Domy\u015blnym kontenerem servlet\u00f3w jest w tym przypadku Netty. U\u017cywa on jednego w\u0105tku na serwer oraz liczb\u0119 w\u0105tk\u00f3w r\u00f3wn\u0105 liczbie rdzeni komputera (CPU Cores) na obs\u0142ug\u0119 \u017c\u0105da\u0144. W przypadku 4-rdzeniowego komputera b\u0119d\u0105 to 4 w\u0105tki.<\/p>\n\n\n\n<p>Podej\u015bcie to umo\u017cliwia asynchroniczne oraz nieblokuj\u0105ce przetwarzania \u017c\u0105da\u0144. Przy takim za\u0142o\u017ceniu podczas wywo\u0142ania operacji wej\u015bcia\/wyj\u015bcia, np. wywo\u0142ania bazy danych, w\u0105tek nie czeka na odpowied\u017a, tylko od razu wraca do puli w\u0105tk\u00f3w i jest gotowy do przyj\u0119cia kolejnego zdarzenia. Nast\u0119pnie, dzi\u0119ki mechanizmowi callback\u00f3w, aplikacja zostaje poinformowana o rezultacie zapytania.<\/p>\n\n\n\n<p><strong>Przewag\u0105 podej\u015bcia reaktywnego<\/strong> jest wi\u0119c optymalne wykorzystanie dzia\u0142ania w\u0105tk\u00f3w bez czasu oczekiwania na odpowied\u017a, jak to ma miejsce w przypadku klasycznego podej\u015bcia.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Korutyny<\/strong><\/h2>\n\n\n\n<p>Kolejn\u0105 opcj\u0105 napisanie nieblokuj\u0105cej aplikacji jest wykorzystanie j\u0119zyka Kotlin wraz z <a href=\"https:\/\/kotlinlang.org\/docs\/coroutines-overview.html\" rel=\"nofollow\" >korutynami<\/a>. W odr\u00f3\u017cnieniu od projektu Reactor, mo\u017cliwe jest pisanie kodu w spos\u00f3b bardzo zbli\u017cony do podej\u015bcia klasycznego, co znacz\u0105co poprawia czytelno\u015b\u0107 kodu oraz \u0142atwo\u015b\u0107 testowania, wykorzystuj\u0105c zalety kodu nieblokuj\u0105cego.<\/p>\n\n\n\n<p>Korutyny cz\u0119sto nazywane s\u0105 r\u00f3wnie\u017c lekkimi w\u0105tkami. Spowodowane jest to tym, \u017ce ich utworzenie jest proste oraz wymaga niewielkich zasob\u00f3w. W przypadku tworzeniu nowego w\u0105tku zajmuje on oko\u0142o 1 MB pami\u0119ci. Korutyna potrzebuje jedynie kilkadziesi\u0105t bajt\u00f3w pami\u0119ci. Jeden w\u0105tek mo\u017ce tworzy\u0107 wiele korutyn.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n\n\n\n<p>W tym przypadku r\u00f3wnie\u017c pobieramy zale\u017cno\u015b\u0107 webfluxow\u0105, wi\u0119c ponownie domy\u015blnym kontenerem servlet\u00f3w b\u0119dzie Netty.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n&lt;dependency&gt;\n   &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n   &lt;artifactId&gt;spring-boot-starter-webflux&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n<\/pre><\/div>\n\n\n<p>Poza klasycznymi zale\u017cno\u015bciami kotlinowymi, potrzebujemy r\u00f3wnie\u017c bibliotek do obs\u0142ugi korutyn.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n&lt;dependency&gt;\n   &lt;groupId&gt;org.jetbrains.kotlinx&lt;\/groupId&gt;\n   &lt;artifactId&gt;kotlinx-coroutines-core&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n&lt;dependency&gt;\n   &lt;groupId&gt;org.jetbrains.kotlinx&lt;\/groupId&gt;\n   &lt;artifactId&gt;kotlinx-coroutines-reactor&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>Testy obci\u0105\u017ceniowe<\/strong><\/h2>\n\n\n\n<p>Do przeprowadzenia test\u00f3w obci\u0105\u017ceniowych zosta\u0142o wykorzystane narz\u0119dzie Gatling umo\u017cliwiaj\u0105ce symulowanie produkcyjnego ruchu poprzez wywo\u0142ywanie wielu zapyta\u0144 r\u00f3wnolegle przez okre\u015blony czas.<\/p>\n\n\n\n<p>Testy zosta\u0142y przeprowadzone na 6-rdzeniowym Intel i7 oraz 32GB RAM, dysk SSD. W ramach test\u00f3w por\u00f3wnano czasy odpowiedzi aplikacji zbudowanej wed\u0142ug trzech przedstawionych wy\u017cej podej\u015b\u0107.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic class CustomerRequestsSimulation extends Simulation {\n\n    HttpProtocolBuilder httpProtocol = http\n            .baseUrl(&quot;http:\/\/localhost:8080&quot;)\n            .acceptHeader(&quot;application\/json&quot;)\n            .userAgentHeader(&quot;Gatling\/Performance Test&quot;);\n\n\n    ScenarioBuilder scn = CoreDsl.scenario(&quot;Load Test Scenario&quot;)\n            .forever()\n            .on(exec(http(&quot;create-customer-request&quot;)\n                    .get(&quot;\/endpoint&quot;)\n            ));\n\n    public CustomerRequestsSimulation() {\n        setUp(scn.injectClosed(\n                        incrementConcurrentUsers(256)\n                                .times(8)\n                                .eachLevelLasting(Duration.ofSeconds(20))\n                                .separatedByRampsLasting(Duration.ofSeconds(10))\n                                .startingFrom(0)\n                )\n        ).maxDuration(Duration.ofMinutes(2))\n                .protocols(httpProtocol);\n    }\n}\n<\/pre><\/div>\n\n\n<p>W tym scenariuszu trwaj\u0105cym 2 minuty 256 u\u017cytkownik\u00f3w b\u0119dzie dodawanych w ci\u0105gu 10 sekund. Pomi\u0119dzy kolejnymi inkrementacjami jest 20 sekund przerwy.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/1-8.png\"><img decoding=\"async\" width=\"1024\" height=\"289\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/1-8-1024x289.png\" alt=\"Aktywni u\u017cytkownicy w trakcie symulacji\" class=\"wp-image-20397\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/1-8-1024x289.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/1-8-300x85.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/1-8-768x217.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/1-8.png 1329w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Ryc. 1 Aktywni u\u017cytkownicy w trakcie symulacji<\/figcaption><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Bez op\u00f3\u017anie\u0144<\/strong><\/h3>\n\n\n\n<p>W tym przyk\u0142adzie aplikacje nie b\u0119d\u0105 posiada\u0142y \u017cadnych op\u00f3\u017anie\u0144 ani logiki wewn\u0105trz kontrolera. B\u0119d\u0105 wi\u0119c pr\u00f3bowa\u0107 odpowiada\u0107 na \u017c\u0105dania tak szybko, jak tylko jest to mo\u017cliwe.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>podej\u015bcie imperatywne<\/li><\/ol>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@RestController\nclass Controller {\n\n    @GetMapping(&quot;\/endpoint&quot;)\n    public ResponseEntity&lt;Void&gt; endpoint() {\n        return ResponseEntity.ok().build();\n    }\n}\n<\/pre><\/div>\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/2-6.png\"><img decoding=\"async\" width=\"515\" height=\"391\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/2-6.png\" alt=\"\" class=\"wp-image-20399\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/2-6.png 515w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/2-6-300x228.png 300w\" sizes=\"(max-width: 515px) 100vw, 515px\" \/><\/a><figcaption>Ryc. 2 Zakresy czasu reakcji<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/3-5.png\"><img decoding=\"async\" width=\"1024\" height=\"290\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/3-5-1024x290.png\" alt=\"Rozk\u0142ad czasu odpowiedzi \" class=\"wp-image-20401\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/3-5-1024x290.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/3-5-300x85.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/3-5-768x218.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/3-5.png 1327w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Ryc. 3 Rozk\u0142ad czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\"><li>reaktywne<\/li><\/ol>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@RestController\nclass Controller {\n\n    @GetMapping(&quot;\/endpoint&quot;)\n    Mono&lt;Void&gt; endpoint() {\n        return Mono.empty();\n    }\n}\n<\/pre><\/div>\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/4-4.png\"><img decoding=\"async\" width=\"514\" height=\"388\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/4-4.png\" alt=\"Zakresy czasu odpowiedzi\" class=\"wp-image-20403\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/4-4.png 514w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/4-4-300x226.png 300w\" sizes=\"(max-width: 514px) 100vw, 514px\" \/><\/a><figcaption>Ryc. 4 Zakresy czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/5-5.png\"><img decoding=\"async\" width=\"1024\" height=\"296\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/5-5-1024x296.png\" alt=\"Rozk\u0142ad czasu odpowiedzi\" class=\"wp-image-20405\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/5-5-1024x296.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/5-5-300x87.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/5-5-768x222.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/5-5.png 1326w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Ryc. 5 Rozk\u0142ad czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\"><li>korutyny<\/li><\/ol>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n@RestController\nclass Controller {\n\n    @GetMapping(&quot;\/endpoint&quot;)\n    suspend fun endpoint(): ResponseEntity&amp;lt;Void&gt; {\n        return ResponseEntity.ok().build()\n    }\n}\n\n<\/pre><\/div>\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/6-4.png\"><img decoding=\"async\" width=\"522\" height=\"394\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/6-4.png\" alt=\"Zakresy czasu odpowiedzi\" class=\"wp-image-20409\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/6-4.png 522w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/6-4-300x226.png 300w\" sizes=\"(max-width: 522px) 100vw, 522px\" \/><\/a><figcaption>Ryc. 6 Zakresy czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/7-4.png\"><img decoding=\"async\" width=\"1024\" height=\"295\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/7-4-1024x295.png\" alt=\"Rozk\u0142ad czasu odpowiedzi\" class=\"wp-image-20411\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/7-4-1024x295.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/7-4-300x86.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/7-4-768x221.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/7-4.png 1318w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Ryc. 7 Rozk\u0142ad czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-table aligncenter\"><table><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">&nbsp;<\/td><td class=\"has-text-align-center\" data-align=\"center\">Liczba \u017c\u0105da\u0144<\/td><td class=\"has-text-align-center\" data-align=\"center\">RPS<\/td><td class=\"has-text-align-center\" data-align=\"center\">99th pct<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u015aredni czas odpowiedzi<\/td><td class=\"has-text-align-center\" data-align=\"center\">Odchylenie standardowe<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Imperatywne<\/td><td class=\"has-text-align-center\" data-align=\"center\">4&nbsp;719 272<\/td><td class=\"has-text-align-center\" data-align=\"center\">39 327<\/td><td class=\"has-text-align-center\" data-align=\"center\">45<\/td><td class=\"has-text-align-center\" data-align=\"center\">15<\/td><td class=\"has-text-align-center\" data-align=\"center\">11<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Reaktywne<\/td><td class=\"has-text-align-center\" data-align=\"center\">5&nbsp;326 083<\/td><td class=\"has-text-align-center\" data-align=\"center\">44 384<\/td><td class=\"has-text-align-center\" data-align=\"center\">29<\/td><td class=\"has-text-align-center\" data-align=\"center\">13<\/td><td class=\"has-text-align-center\" data-align=\"center\">7<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Korutyny<\/td><td class=\"has-text-align-center\" data-align=\"center\">4&nbsp;972 563<\/td><td class=\"has-text-align-center\" data-align=\"center\">41 438<\/td><td class=\"has-text-align-center\" data-align=\"center\">26<\/td><td class=\"has-text-align-center\" data-align=\"center\">14<\/td><td class=\"has-text-align-center\" data-align=\"center\">8<\/td><\/tr><\/tbody><\/table><figcaption>Tab. 1 Zestawienie wynik\u00f3w test\u00f3w bez op\u00f3\u017anie\u0144 dla 3 podej\u015b\u0107<\/figcaption><\/figure>\n\n\n\n<p>W tym przypadku <strong>nie wida\u0107 znacz\u0105cych r\u00f3\u017cnic<\/strong> pomi\u0119dzy poszczeg\u00f3lnymi technologiami. Klasyczne podej\u015bcie jest wolniejsze, ale s\u0105 to na tyle ma\u0142e warto\u015bci, \u017ce nie maj\u0105 znacz\u0105cego wp\u0142ywu na u\u017cytkowanie aplikacji.<\/p>\n\n\n\n<p>Ciekawiej zaczyna si\u0119 robi\u0107, gdy dodamy op\u00f3\u017anienia.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Op\u00f3\u017anienie 200 ms<\/strong><\/h3>\n\n\n\n<p>W tym przyk\u0142adzie do aplikacji zosta\u0142y dodane op\u00f3\u017anienia 200 ms, kt\u00f3re symuluj\u0105 odpytywanie bazy danych lub innego serwisu.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>imperatywne<\/li><\/ol>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@RestController\nclass Controller {\n\n    @GetMapping(&quot;\/endpoint&quot;)\n    public ResponseEntity&lt;Void&gt; endpoint() throws InterruptedException {\n        Thread.sleep(200);\n        return ResponseEntity.ok().build();\n    }\n}\n<\/pre><\/div>\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/8-3.png\"><img decoding=\"async\" width=\"528\" height=\"394\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/8-3.png\" alt=\"Zakresy czasu odpowiedzi\" class=\"wp-image-20413\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/8-3.png 528w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/8-3-300x224.png 300w\" sizes=\"(max-width: 528px) 100vw, 528px\" \/><\/a><figcaption>Ryc. 8 Zakresy czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/9-3.png\"><img decoding=\"async\" width=\"1024\" height=\"293\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/9-3-1024x293.png\" alt=\"Rozk\u0142ad czasu odpowiedzi\" class=\"wp-image-20415\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/9-3-1024x293.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/9-3-300x86.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/9-3-768x220.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/9-3.png 1330w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Ryc. 9 Rozk\u0142ad czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\"><li>relatywne<\/li><\/ol>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@RestController\nclass Controller {\n\n    @GetMapping(&quot;\/endpoint&quot;)\n    Mono&lt;Void&gt; endpoint() {\n        return Mono.empty()\n                .delaySubscription(Duration.ofMillis(200))\n                .then();\n    }\n}\n<\/pre><\/div>\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/10-2.png\"><img decoding=\"async\" width=\"517\" height=\"393\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/10-2.png\" alt=\"Zakresy czasu odpowiedzi\" class=\"wp-image-20417\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/10-2.png 517w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/10-2-300x228.png 300w\" sizes=\"(max-width: 517px) 100vw, 517px\" \/><\/a><figcaption>Ryc. 10 Zakresy czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/11-2.png\"><img decoding=\"async\" width=\"1024\" height=\"292\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/11-2-1024x292.png\" alt=\"Rozk\u0142ad czasu odpowiedzi\" class=\"wp-image-20419\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/11-2-1024x292.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/11-2-300x86.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/11-2-768x219.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/11-2.png 1328w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Ryc. 11 Rozk\u0142ad czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\"><li>korutyny<\/li><\/ol>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n@RestController\nclass Controller {\n\n    @GetMapping(&quot;\/endpoint&quot;)\n    suspend fun endpoint(): ResponseEntity&amp;lt;Void&gt; {\n        coroutineScope {\n            delay(200)\n        }\n        return ResponseEntity.ok().build()\n    }\n}\n<\/pre><\/div>\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/12-2.png\"><img decoding=\"async\" width=\"510\" height=\"387\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/12-2.png\" alt=\"Zakresy czasu odpowiedzi\" class=\"wp-image-20421\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/12-2.png 510w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/12-2-300x228.png 300w\" sizes=\"(max-width: 510px) 100vw, 510px\" \/><\/a><figcaption>Ryc. 12 Zakresy czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/13-2.png\"><img decoding=\"async\" width=\"1024\" height=\"275\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/13-2-1024x275.png\" alt=\"Rozk\u0142ad czasu odpowiedzi\" class=\"wp-image-20423\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/13-2-1024x275.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/13-2-300x81.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/13-2-768x207.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/13-2.png 1431w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Ryc. 13 Rozk\u0142ad czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-table aligncenter\"><table><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">&nbsp;<\/td><td class=\"has-text-align-center\" data-align=\"center\">Liczba \u017c\u0105da\u0144<\/td><td class=\"has-text-align-center\" data-align=\"center\">RPS<\/td><td class=\"has-text-align-center\" data-align=\"center\">99th pct<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u015aredni czas odpowiedzi<\/td><td class=\"has-text-align-center\" data-align=\"center\">Odchylenie standardowe<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Imperatywne<\/td><td class=\"has-text-align-center\" data-align=\"center\">113 775<\/td><td class=\"has-text-align-center\" data-align=\"center\">948<\/td><td class=\"has-text-align-center\" data-align=\"center\">1088<\/td><td class=\"has-text-align-center\" data-align=\"center\">625<\/td><td class=\"has-text-align-center\" data-align=\"center\">289<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Reaktywne<\/td><td class=\"has-text-align-center\" data-align=\"center\">339 739<\/td><td class=\"has-text-align-center\" data-align=\"center\">2 831<\/td><td class=\"has-text-align-center\" data-align=\"center\">226<\/td><td class=\"has-text-align-center\" data-align=\"center\">211<\/td><td class=\"has-text-align-center\" data-align=\"center\">7<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Korutyny<\/td><td class=\"has-text-align-center\" data-align=\"center\">344 001<\/td><td class=\"has-text-align-center\" data-align=\"center\">2 866<\/td><td class=\"has-text-align-center\" data-align=\"center\">222<\/td><td class=\"has-text-align-center\" data-align=\"center\">208<\/td><td class=\"has-text-align-center\" data-align=\"center\">6<\/td><\/tr><\/tbody><\/table><figcaption>Tab. 2 Zestawienie wynik\u00f3w test\u00f3w op\u00f3\u017anie\u0144 200 ms dla 3 podej\u015b\u0107<\/figcaption><\/figure>\n\n\n\n<p>Ju\u017c w przypadku niewielkiego op\u00f3\u017anienia w aplikacji zaczyna by\u0107 wyra\u017anie widoczna r\u00f3\u017cnica w przepustowo\u015bci serwis\u00f3w <strong>na korzy\u015b\u0107 podej\u015bcia reaktywnego oraz z u\u017cyciem korutyn<\/strong>. W przypadku podej\u015bcia klasycznego przy op\u00f3\u017anieniu wynosz\u0105cym 200 ms \u015bredni czas odpowiedzi wynosi\u0142 nieco ponad 600 ms, a 99% \u017c\u0105da\u0144 mia\u0142o czas latencji wynosz\u0105cy poni\u017cej sekundy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Op\u00f3\u017anienie 500 ms<\/strong><\/h3>\n\n\n\n<ol class=\"wp-block-list\"><li>imperatywne<\/li><\/ol>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/14-1.png\"><img decoding=\"async\" width=\"514\" height=\"390\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/14-1.png\" alt=\"Zakresy czasu odpowiedzi\" class=\"wp-image-20427\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/14-1.png 514w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/14-1-300x228.png 300w\" sizes=\"(max-width: 514px) 100vw, 514px\" \/><\/a><figcaption>Ryc. 14 Zakresy czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/15-1.png\"><img decoding=\"async\" width=\"1024\" height=\"292\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/15-1-1024x292.png\" alt=\"Rozk\u0142ad czasu odpowiedzi\" class=\"wp-image-20430\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/15-1-1024x292.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/15-1-300x86.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/15-1-768x219.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/15-1.png 1321w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Ryc. 15 Rozk\u0142ad czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\"><li>reaktywne<\/li><\/ol>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/16-1.png\"><img decoding=\"async\" width=\"511\" height=\"387\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/16-1.png\" alt=\"Zakresy czasu odpowiedzi\" class=\"wp-image-20432\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/16-1.png 511w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/16-1-300x227.png 300w\" sizes=\"(max-width: 511px) 100vw, 511px\" \/><\/a><figcaption>Ryc. 16 Zakresy czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/17.png\"><img decoding=\"async\" width=\"1024\" height=\"291\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/17-1024x291.png\" alt=\"Rozk\u0142ad czasu odpowiedzi\" class=\"wp-image-20434\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/17-1024x291.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/17-300x85.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/17-768x218.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/17.png 1320w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Ryc. 17 Rozk\u0142ad czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\"><li>korutyny<\/li><\/ol>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/18.png\"><img decoding=\"async\" width=\"514\" height=\"391\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/18.png\" alt=\"Zakresy czasu odpowiedzi\" class=\"wp-image-20436\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/18.png 514w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/18-300x228.png 300w\" sizes=\"(max-width: 514px) 100vw, 514px\" \/><\/a><figcaption>Ryc. 18 Zakresy czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/19.png\"><img decoding=\"async\" width=\"1024\" height=\"289\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/19-1024x289.png\" alt=\"Rozk\u0142ad czasu odpowiedzi\" class=\"wp-image-20438\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/19-1024x289.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/19-300x85.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/19-768x217.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/19.png 1316w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Ryc. 19 Rozk\u0142ad czasu odpowiedzi<\/figcaption><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-table aligncenter\"><table><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">&nbsp;<\/td><td class=\"has-text-align-center\" data-align=\"center\">Liczba \u017c\u0105da\u0144<\/td><td class=\"has-text-align-center\" data-align=\"center\">RPS<\/td><td class=\"has-text-align-center\" data-align=\"center\">99th pct<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u015aredni czas odpowiedzi<\/td><td class=\"has-text-align-center\" data-align=\"center\">Odchylenie standardowe<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Imperatywne<\/td><td class=\"has-text-align-center\" data-align=\"center\">45 328<\/td><td class=\"has-text-align-center\" data-align=\"center\">377<\/td><td class=\"has-text-align-center\" data-align=\"center\">2692<\/td><td class=\"has-text-align-center\" data-align=\"center\">1551<\/td><td class=\"has-text-align-center\" data-align=\"center\">717<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Reaktywne<\/td><td class=\"has-text-align-center\" data-align=\"center\">139 261<\/td><td class=\"has-text-align-center\" data-align=\"center\">1 160<\/td><td class=\"has-text-align-center\" data-align=\"center\">521<\/td><td class=\"has-text-align-center\" data-align=\"center\">513<\/td><td class=\"has-text-align-center\" data-align=\"center\">4<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Korutyny<\/td><td class=\"has-text-align-center\" data-align=\"center\">139 293<\/td><td class=\"has-text-align-center\" data-align=\"center\">1 160<\/td><td class=\"has-text-align-center\" data-align=\"center\">519<\/td><td class=\"has-text-align-center\" data-align=\"center\">512<\/td><td class=\"has-text-align-center\" data-align=\"center\">4<\/td><\/tr><\/tbody><\/table><figcaption>Tab. 3 Zestawienie wynik\u00f3w test\u00f3w op\u00f3\u017anie\u0144 500 ms dla 3 podej\u015b\u0107<\/figcaption><\/figure>\n\n\n\n<p>W przypadku op\u00f3\u017anienia 500 ms wida\u0107 <strong>znaczne problemy ze sprawn\u0105 obs\u0142ug\u0105 \u017c\u0105da\u0144<\/strong> przez serwis napisany imperatywnie. Je\u015bli chodzi o podej\u015bcie reaktywne oraz z u\u017cyciem korutyn czas obs\u0142ugi \u017c\u0105dania jest \u015brednio o 13 ms d\u0142u\u017cszy ni\u017c zaprogramowane op\u00f3\u017anienie.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Podsumowanie<\/strong><\/h2>\n\n\n\n<p>Im wi\u0119ksze symulowane op\u00f3\u017anienie, tym <strong>wi\u0119ksza przepustowo\u015b\u0107 w podej\u015bciu reaktywnym oraz z wykorzystaniem korutyn<\/strong> w stosunku do podej\u015bcia klasycznego. Nie oznacza to jednak, \u017ce trzeba wszystkie aktualne serwisy przepisa\u0107 z wykorzystaniem tych technologii, jak r\u00f3wnie\u017c, \u017ce wszystkie nowe serwisy musz\u0105 by\u0107 napisane w ten spos\u00f3b.<\/p>\n\n\n\n<p>Pisanie takiego kodu jest trudniejsze w przetestowaniu, trudniejsze w debuggowaniu oraz cz\u0119sto mniej czytelne ni\u017c w przypadku podej\u015bcia imperatywnego.<\/p>\n\n\n\n<p>Nale\u017cy wi\u0119c dobra\u0107 odpowiedni\u0105 technologi\u0119 do przypadku u\u017cycia. Gdy wi\u0119c pada pytanie, czy lepiej u\u017cy\u0107 podej\u015bcia imperatywnego, reaktywnego czy korutyn \u2013 odpowied\u017a brzmi\u2026 to zale\u017cy \ud83d\ude09<\/p>\n\n\n\n<p>*** <\/p>\n\n\n\n<p>A je\u015bli interesuje Ci\u0119, co testowa\u0107: wydajno\u015b\u0107 czy szybko\u015b\u0107 zdaniem naszych ekspert\u00f3w z CC Testing, zach\u0119camy do zapoznania z ich artyku\u0142em: Testowanie wydajno\u015bci czy szybko\u015bci? Google Lighthouse w praktyce<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;20393&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;5&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;2&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5&quot;,&quot;size&quot;:&quot;30&quot;,&quot;title&quot;:&quot;Jak wytrzyma\u0107 \u015bwi\u0105teczne obci\u0105\u017cenie? Klasycznie, reaktywnie czy z u\u017cyciem korutyn?&quot;,&quot;width&quot;:&quot;159&quot;,&quot;_legend&quot;:&quot;{score}\\\/5&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 159px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 24px;\">\n            5\/5    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Buduj\u0105c aplikacj\u0119, nale\u017cy pami\u0119ta\u0107 o tym, by by\u0142a ona wydajna, niezawodna oraz odporna na obci\u0105\u017cenie. \u017beby to uzyska\u0107, stosuje si\u0119 &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/jak-wytrzymac-swiateczne-obciazenie-klasycznie-reaktywnie-czy-z-uzyciem-korutyn\/\">Continued<\/a><\/p>\n","protected":false},"author":490,"featured_media":20442,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":6,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1314],"tags":[2427,1659,1660,1661,930,146],"class_list":["post-20393","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-twardo","tag-digital","tag-podejscie-klasyczne","tag-podejscie-reaktywne","tag-korutyny","tag-e-commerce","tag-testing"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/03\/Jak-wytrzymac-swiateczne-obciazenie-Klasycznie-reaktywnie-czy-z-uzyciem-korutyn.jpg","category_names":["Development na twardo"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/20393"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/490"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=20393"}],"version-history":[{"count":3,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/20393\/revisions"}],"predecessor-version":[{"id":20483,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/20393\/revisions\/20483"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/20442"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=20393"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=20393"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=20393"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}