<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://prs2rnn.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://prs2rnn.github.io/" rel="alternate" type="text/html" /><updated>2026-06-30T19:55:44+00:00</updated><id>https://prs2rnn.github.io/feed.xml</id><title type="html">Andrey Perestoronin</title><subtitle>Python Backend Developer specializing in web applications, APIs, automation, and backend systems built with Python, Django, PostgreSQL, Docker, and Linux.</subtitle><entry xml:lang="ru"><title type="html">Книги, которые повлияли на мое мышление</title><link href="https://prs2rnn.github.io/ru/posts/%D0%BA%D0%BD%D0%B8%D0%B6%D0%BD%D0%B0%D1%8F-%D0%BF%D0%BE%D0%BB%D0%BA%D0%B0/" rel="alternate" type="text/html" title="Книги, которые повлияли на мое мышление" /><published>2025-09-01T00:00:00+00:00</published><updated>2025-09-01T00:00:00+00:00</updated><id>https://prs2rnn.github.io/ru/posts/%D0%BA%D0%BD%D0%B8%D0%B6%D0%BD%D0%B0%D1%8F-%D0%BF%D0%BE%D0%BB%D0%BA%D0%B0</id><content type="html" xml:base="https://prs2rnn.github.io/ru/posts/%D0%BA%D0%BD%D0%B8%D0%B6%D0%BD%D0%B0%D1%8F-%D0%BF%D0%BE%D0%BB%D0%BA%D0%B0/"><![CDATA[<p>Ниже собраны книги, которые в разное время оказали заметное влияние на мое мировоззрение.</p>

<ul>
  <li><strong>Сунь-Цзы — «Искусство войны»</strong></li>
</ul>

<p>Одна из первых книг, которая заставила задуматься о стратегии, дисциплине и принятии решений. Многие идеи из нее применимы далеко за пределами военного дела.</p>

<ul>
  <li><strong>Никколо Макиавелли — «Государь»</strong></li>
</ul>

<p>Книга помогла взглянуть на политику и власть с прагматичной точки зрения. Не обязательно соглашаться с автором, но понимать его аргументы полезно.</p>

<ul>
  <li><strong>Марио Пьюзо — «Крёстный отец»</strong></li>
</ul>

<p>Одна из самых сильных художественных книг, которые я читал. Особенно запомнились темы семьи, ответственности, чести и последствий принимаемых решений.</p>

<ul>
  <li><strong>Теодор Драйзер — «Финансист»</strong></li>
</ul>

<p>История человека с сильным характером, который не опускает руки перед трудностями. Книга мотивирует брать ответственность за собственную жизнь.</p>

<ul>
  <li><strong>Михаил Булгаков — «Мастер и Маргарита»</strong></li>
</ul>

<p>Мое любимое произведение русской литературы. Особенно ценю сатиру на общество, многослойность сюжета и философские темы.</p>

<ul>
  <li><strong>Джордж Сэмюэль Клейсон — «Самый богатый человек в Вавилоне»</strong></li>
</ul>

<p>Простая, но полезная книга о финансовой дисциплине, накоплениях и отношении к деньгам. Многие советы остаются актуальными и сегодня, хотя мне самому далеко не всегда удается следовать им.</p>

<ul>
  <li><strong>«Бусидо»</strong></li>
</ul>

<p>Свод принципов самурайской этики, посвященный дисциплине, долгу, самообладанию и чести. Интересен прежде всего как исторический и философский источник.</p>

<ul>
  <li><strong>Юрий Никитин — цикл «Трое из леса»</strong></li>
</ul>

<p>Любимый цикл отечественного фэнтези. Несмотря на жанр, книги запомнились героями, которые продолжают идти вперед даже тогда, когда обстоятельства складываются против них.</p>]]></content><author><name></name></author><category term="reading" /><summary type="html"><![CDATA[Подборка книг, которые повлияли на мое мировоззрение, отношение к жизни, финансам, истории и принятию решений.]]></summary></entry><entry xml:lang="ru"><title type="html">Музыка, которую я слушаю</title><link href="https://prs2rnn.github.io/ru/posts/%D0%BC%D1%83%D0%B7%D1%8B%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BF%D0%BE%D0%B7%D0%B8%D1%86%D0%B8%D0%B8/" rel="alternate" type="text/html" title="Музыка, которую я слушаю" /><published>2025-09-01T00:00:00+00:00</published><updated>2025-09-01T00:00:00+00:00</updated><id>https://prs2rnn.github.io/ru/posts/%D0%BC%D1%83%D0%B7%D1%8B%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BF%D0%BE%D0%B7%D0%B8%D1%86%D0%B8%D0%B8</id><content type="html" xml:base="https://prs2rnn.github.io/ru/posts/%D0%BC%D1%83%D0%B7%D1%8B%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BF%D0%BE%D0%B7%D0%B8%D1%86%D0%B8%D0%B8/"><![CDATA[<p>Не могу сказать, что постоянно ищу новую музыку. Обычно слушаю одни и те же альбомы и исполнителей, к которым регулярно возвращаюсь. Чаще всего музыка сопровождает меня на прогулках, за рулем или во время тренировок.</p>

<ul>
  <li><strong>Тимур Муцураев</strong></li>
</ul>

<p>Исполнитель, к творчеству которого я возвращаюсь чаще всего. Ценю его песни за атмосферу, тексты и эмоциональную подачу.</p>

<ul>
  <li><strong>Группа «Кино»</strong></li>
</ul>

<p>Настоящая классика. Песни Виктора Цоя остаются актуальными вне зависимости от времени и настроения.</p>

<ul>
  <li><strong>Русский рэп</strong></li>
</ul>

<p>Чаще всего слушаю Ноггано / Басту, Гуфа, Рем Диггу, Чемодан Клан и Friendly Thug 52 NGG. У каждого из них нравится свой стиль, подача и звучание.</p>

<ul>
  <li><strong>Рок и метал</strong></li>
</ul>

<p>Из зарубежных групп чаще всего слушаю Rammstein, Deftones и Metallica. Это музыка, которая отлично подходит для тренировок.</p>]]></content><author><name></name></author><category term="music" /><summary type="html"><![CDATA[Музыка, к которой я чаще всего возвращаюсь: рок, русский рэп, группа «Кино» и другие исполнители.]]></summary></entry><entry xml:lang="ru"><title type="html">Фильмы и сериалы, которые мне запомнились</title><link href="https://prs2rnn.github.io/ru/posts/%D0%BF%D0%B5%D1%80%D0%B5%D1%87%D0%B5%D0%BD%D1%8C-%D1%84%D0%B8%D0%BB%D1%8C%D0%BC%D0%BE%D0%B2/" rel="alternate" type="text/html" title="Фильмы и сериалы, которые мне запомнились" /><published>2025-09-01T00:00:00+00:00</published><updated>2025-09-01T00:00:00+00:00</updated><id>https://prs2rnn.github.io/ru/posts/%D0%BF%D0%B5%D1%80%D0%B5%D1%87%D0%B5%D0%BD%D1%8C-%D1%84%D0%B8%D0%BB%D1%8C%D0%BC%D0%BE%D0%B2</id><content type="html" xml:base="https://prs2rnn.github.io/ru/posts/%D0%BF%D0%B5%D1%80%D0%B5%D1%87%D0%B5%D0%BD%D1%8C-%D1%84%D0%B8%D0%BB%D1%8C%D0%BC%D0%BE%D0%B2/"><![CDATA[<p>Ниже собраны фильмы, сериалы и аниме, которые в разное время произвели на меня сильное впечатление. Это не рейтинг лучших произведений, а личная подборка того, что запомнилось больше всего.</p>

<ul>
  <li><strong>«Тренировочный день» (<em>Training Day</em>, 2001)</strong></li>
</ul>

<p>Понравилось противостояние двух совершенно разных характеров и то, как раскрываются их взгляды на жизнь.</p>

<ul>
  <li><strong>«Лицо со шрамом» (<em>Scarface</em>, 1983)</strong></li>
</ul>

<p>Один из самых ярких образов в мировом кинематографе. История стремительного взлета и неизбежного падения.</p>

<ul>
  <li><strong>«Крёстный отец» (<em>The Godfather</em>, трилогия, 1972–1990)</strong></li>
</ul>

<p>Классика, к которой сложно что-либо добавить. Один из лучших фильмов о семье, власти и ответственности.</p>

<ul>
  <li><strong>«Нефть» (<em>There Will Be Blood</em>, 2007)</strong></li>
</ul>

<p>Мрачная история о человеческих амбициях, одиночестве и цене успеха.</p>

<ul>
  <li><strong>«Старикам тут не место» (<em>No Country for Old Men</em>, 2007)</strong></li>
</ul>

<p>Необычный триллер с атмосферой безысходности и одним из самых запоминающихся антагонистов.</p>

<ul>
  <li><strong>«Выстрел в пустоту» (<em>Shot Caller</em>, 2017)</strong></li>
</ul>

<p>История о том, как один выбор способен полностью изменить жизнь человека.</p>

<ul>
  <li><strong>«Большой куш» (<em>Snatch</em>, 2000)</strong></li>
</ul>

<p>Любимый фильм Гая Ричи с фирменным юмором, быстрым повествованием и яркими персонажами.</p>

<ul>
  <li><strong>«В погоне за счастьем» (<em>The Pursuit of Happyness</em>, 2006)</strong></li>
</ul>

<p>Фильм, который напоминает, что настойчивость и терпение могут изменить жизнь.</p>

<ul>
  <li><strong>«Славные парни» (<em>Goodfellas</em>, 1990)</strong></li>
</ul>

<p>Один из лучших фильмов в жанре криминальной драмы.</p>

<ul>
  <li><strong>«Казино» (<em>Casino</em>, 1995)</strong></li>
</ul>

<p>Во многом перекликается со «Славными парнями», но рассказывает совершенно другую историю.</p>

<ul>
  <li><strong>«Оружейный барон» (<em>Lord of War</em>, 2005)</strong></li>
</ul>

<p>Интересен тем, что вдохновлен реальными событиями и показывает теневую сторону мировой торговли оружием.</p>

<ul>
  <li><strong>«Гангстер» (<em>American Gangster</em>, 2007)</strong></li>
</ul>

<p>Любимая роль Дензела Вашингтона и одна из лучших криминальных драм 2000-х.</p>

<ul>
  <li><strong>«Брат» (1997)</strong></li>
</ul>

<p>Фильм, который давно стал частью современной российской культуры.</p>

<ul>
  <li><strong>«Брат 2» (2000)</strong></li>
</ul>

<p>В детстве мне очень хотелось быть похожим на Данилу Багрова. Этот фильм я пересматривал много раз и до сих пор считаю одним из любимых.</p>

<ul>
  <li><strong>«Бумер» (2003)</strong></li>
</ul>

<p>Запомнился атмосферой, диалогами и музыкой.</p>

<ul>
  <li><strong>«Жмурки» (2005)</strong></li>
</ul>

<p>Черная комедия Алексея Балабанова с характерным юмором и узнаваемым стилем.</p>

<ul>
  <li><strong>«Война» (2002)</strong></li>
</ul>

<p>Мой любимый российский фильм на военную тематику.</p>

<ul>
  <li><strong>«Груз 200» (2007)</strong></li>
</ul>

<p>Очень тяжелое кино, после просмотра которого остается сильное эмоциональное впечатление.</p>

<ul>
  <li><strong>«Мимино» (1977)</strong></li>
</ul>

<p>Люблю этот фильм за добрый юмор, атмосферу и красивые пейзажи.</p>

<ul>
  <li><strong>«Кавказский пленник» (1996)</strong></li>
</ul>

<p>Дебют Сергея Бодрова младшего в кино, любимейшего актера.</p>

<ul>
  <li><strong>«Берсерк» (<em>Berserk</em>, 1997)</strong></li>
</ul>

<p>Одно из лучших аниме, которые я видел. Даже спустя годы продолжаю слушать композицию <em>Guts’ Theme</em>, 25 серия на недосягаемом уровне.</p>

<ul>
  <li><strong>«Сага о Винланде» (<em>Vinland Saga</em>, 2019–2023)</strong></li>
</ul>

<p>Посмотрел только первый сезон, но он произвел очень сильное впечатление.</p>

<ul>
  <li><strong>«Бригада» (2002)</strong></li>
</ul>

<p>Любимый российский сериал, который я пересматривал несколько раз.</p>

<ul>
  <li><strong>«Клан Сопрано» (<em>The Sopranos</em>, 1999–2007)</strong></li>
</ul>

<p>Начал смотреть из интереса к мафиозной тематике, а в итоге получил один из лучших драматических сериалов.</p>

<ul>
  <li><strong>«НольНольНоль» (<em>ZeroZeroZero</em>, 2020)</strong></li>
</ul>

<p>Небольшой, но очень напряженный сериал о международной торговле наркотиками.</p>

<ul>
  <li><strong>«Космос: Пространство и время» (<em>Cosmos: A Spacetime Odyssey</em>, 2014)</strong></li>
</ul>

<p>Научно-популярный сериал, который заставил меня по-новому взглянуть на устройство Вселенной и историю науки.</p>]]></content><author><name></name></author><category term="movies" /><summary type="html"><![CDATA[Подборка фильмов, сериалов и аниме, которые произвели на меня сильное впечатление и к которым я готов возвращаться.]]></summary></entry><entry xml:lang="ru"><title type="html">Мои рыбалки</title><link href="https://prs2rnn.github.io/ru/posts/%D1%80%D1%8B%D0%B1%D0%B0%D0%BB%D0%BA%D0%B0/" rel="alternate" type="text/html" title="Мои рыбалки" /><published>2025-08-28T00:00:00+00:00</published><updated>2025-08-28T00:00:00+00:00</updated><id>https://prs2rnn.github.io/ru/posts/%D1%80%D1%8B%D0%B1%D0%B0%D0%BB%D0%BA%D0%B0</id><content type="html" xml:base="https://prs2rnn.github.io/ru/posts/%D1%80%D1%8B%D0%B1%D0%B0%D0%BB%D0%BA%D0%B0/"><![CDATA[<figure class="post-figure">
  <video class="post-video" controls="" preload="metadata" playsinline="">
    <source src="/assets/videos/fishing.mp4" type="video/mp4" />
    Your browser does not support the video tag.
  </video>

  
  <figcaption class="post-caption">На поплавок</figcaption>
  
</figure>]]></content><author><name></name></author><category term="fishing" /><summary type="html"><![CDATA[Видео с моих рыбалок: ловля на поплавочную удочку, красивые места и удачные моменты.]]></summary></entry><entry xml:lang="ru"><title type="html">Мои тренировки</title><link href="https://prs2rnn.github.io/ru/posts/%D1%82%D1%80%D0%B5%D0%BD%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B8/" rel="alternate" type="text/html" title="Мои тренировки" /><published>2025-05-20T00:00:00+00:00</published><updated>2025-05-20T00:00:00+00:00</updated><id>https://prs2rnn.github.io/ru/posts/%D1%82%D1%80%D0%B5%D0%BD%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B8</id><content type="html" xml:base="https://prs2rnn.github.io/ru/posts/%D1%82%D1%80%D0%B5%D0%BD%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B8/"><![CDATA[<figure class="post-figure">
  <video class="post-video" controls="" preload="metadata" playsinline="">
    <source src="/assets/videos/boxing.mp4" type="video/mp4" />
    Your browser does not support the video tag.
  </video>

  
  <figcaption class="post-caption">12 раундов по 3 минуты</figcaption>
  
</figure>

<figure class="post-figure">
  <video class="post-video" controls="" preload="metadata" playsinline="">
    <source src="/assets/videos/dips.mp4" type="video/mp4" />
    Your browser does not support the video tag.
  </video>

  
  <figcaption class="post-caption">100 отжиманий на брусьях</figcaption>
  
</figure>]]></content><author><name></name></author><category term="boxing" /><summary type="html"><![CDATA[Видео моих тренировок по боксу и силовой подготовке: работа на мешке, отжимания на брусьях и прогресс.]]></summary></entry><entry xml:lang="en"><title type="html">Trip 1 - Saint-Petersburg</title><link href="https://prs2rnn.github.io/posts/trip-1-saint-petersburg/" rel="alternate" type="text/html" title="Trip 1 - Saint-Petersburg" /><published>2024-10-10T00:00:00+00:00</published><updated>2024-10-10T00:00:00+00:00</updated><id>https://prs2rnn.github.io/posts/trip-1-saint-petersburg</id><content type="html" xml:base="https://prs2rnn.github.io/posts/trip-1-saint-petersburg/"><![CDATA[<p><img src="/assets/images/City%20Institutions%20House.webp" alt="City Institutions House Photo" />
City Institutions House</p>

<p><img src="/assets/images/Palace%20Square.webp" alt="Palace Square Photo" />
Palace Square</p>

<p><img src="/assets/images/Hermitage.webp" alt="Hermitage Photo" />
Hermitage</p>]]></content><author><name></name></author><category term="trip" /><summary type="html"><![CDATA[Sights of the Saint-Petersburg.]]></summary></entry><entry xml:lang="ru"><title type="html">Асинхронность как основной подход к разработке высоконагруженных приложений</title><link href="https://prs2rnn.github.io/ru/posts/%D0%B0%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C-%D0%BA%D0%B0%D0%BA-%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D0%BE%D0%B9-%D0%BF%D0%BE%D0%B4%D1%85%D0%BE%D0%B4-%D0%BA-%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B5-%D0%B2%D1%8B%D1%81%D0%BE%D0%BA%D0%BE%D0%BD%D0%B0%D0%B3%D1%80%D1%83%D0%B6%D0%B5%D0%BD%D0%BD%D1%8B%D1%85-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B9/" rel="alternate" type="text/html" title="Асинхронность как основной подход к разработке высоконагруженных приложений" /><published>2023-05-03T00:00:00+00:00</published><updated>2023-05-03T00:00:00+00:00</updated><id>https://prs2rnn.github.io/ru/posts/%D0%B0%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C-%D0%BA%D0%B0%D0%BA-%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D0%BE%D0%B9-%D0%BF%D0%BE%D0%B4%D1%85%D0%BE%D0%B4-%D0%BA-%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B5-%D0%B2%D1%8B%D1%81%D0%BE%D0%BA%D0%BE%D0%BD%D0%B0%D0%B3%D1%80%D1%83%D0%B6%D0%B5%D0%BD%D0%BD%D1%8B%D1%85-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B9</id><content type="html" xml:base="https://prs2rnn.github.io/ru/posts/%D0%B0%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C-%D0%BA%D0%B0%D0%BA-%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D0%BE%D0%B9-%D0%BF%D0%BE%D0%B4%D1%85%D0%BE%D0%B4-%D0%BA-%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B5-%D0%B2%D1%8B%D1%81%D0%BE%D0%BA%D0%BE%D0%BD%D0%B0%D0%B3%D1%80%D1%83%D0%B6%D0%B5%D0%BD%D0%BD%D1%8B%D1%85-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B9/"><![CDATA[<p>В данной статье освещаются основные подходы к современной разработке высоконагруженных приложений, в частности, предоставляющие основной интерфейс для взаимодействия с пользователем при помощи браузера или иного клиента, в функционал которого заложена отправка http запросов к
серверу.</p>

<h2 id="оглавление">Оглавление</h2>

<ul id="markdown-toc">
  <li><a href="#оглавление" id="markdown-toc-оглавление">Оглавление</a></li>
  <li><a href="#введение" id="markdown-toc-введение">Введение</a></li>
  <li><a href="#основные-термины" id="markdown-toc-основные-термины">Основные термины</a></li>
  <li><a href="#многопроцессорность" id="markdown-toc-многопроцессорность">Многопроцессорность</a></li>
  <li><a href="#многопоточность" id="markdown-toc-многопоточность">Многопоточность</a></li>
  <li><a href="#асинхронность" id="markdown-toc-асинхронность">Асинхронность</a></li>
  <li><a href="#заключение" id="markdown-toc-заключение">Заключение</a></li>
  <li><a href="#список-источников" id="markdown-toc-список-источников">Список источников</a></li>
</ul>

<h2 id="введение">Введение</h2>

<p>Понятие высоконагруженного приложения можно интерпретировать как любое приложение или сервис, обслуживающий большое количество одновременных запросов. Результатом данного события является значительная нагрузка на системные ресурсы, такие как использование процессора, потребление памяти, пропускная способность сети и т.д. В соответствии с этими ограничениями возникает вопрос: как обеспечить эффективную и надежную работу при высоких нагрузках?</p>

<p>­­­Об основных подходах и существующих стратегиях, которые повсеместно используются на этапе проектирования будет рассказано далее. А теме асинхронности как одному из лучших прикладных подходов в проектировании веб-приложений и не только уделяется большая часть материала.</p>

<h2 id="основные-термины">Основные термины</h2>

<p>Прежде чем приступить к рассмотрению общепринятых методов проектирования, необходимо дать понятия базовым сущностям, которые напрямую связаны с процедурой разработки.</p>

<p><strong>Процесс</strong> ­ запущенная программа и ее данные в памяти. Программа может запускать свои дочерние процессы, для которых предоставляется отдельное место в памяти. Для одного процесса операционная система выделяет пул ресурсов, включая виртуальную память, т.е. память использующуюся, когда программе требуется более того числа оперативной памяти, что есть на компьютере, путем перемещения частей программы на жесткий диск. В эту область памяти загружается транслятор, код и другие необходимые для него компоненты. Этот процесс реализуется автоматически, поэтому не требует никаких усилий от программиста, только аппаратной поддержки от ОС.</p>

<p><strong>Thread</strong> – поток выполнения программы, т.е. основные части алгоритма, которые выполняются последовательно при запуске программы. Thread является частью процесса.</p>

<p><strong>GIL</strong> (глобальная блокировка интерпретатора) ­ способ синхронизации потоков, который используется в некоторых интерпретируемых языках программирования, например в Python и Ruby.</p>

<p><strong>Синхронность</strong> – концепция по умолчанию, когда каждая последующая операция ожидает окончания предыдущей и не может быть выполнена наперед.</p>

<p><strong>Виды операций:</strong></p>

<ul>
  <li>
    <p><em>IO-bound</em> – означает, что скорость выполнения ограничена скоростью ввода/вывода. Например, запись на диск или запрос на сервер.</p>
  </li>
  <li>
    <p><em>CPU-bound</em> – означает, что скорость выполнения ограничена характеристиками CPU и оперативной памятью.</p>
  </li>
</ul>

<h2 id="многопроцессорность">Многопроцессорность</h2>

<p>Представим, что пользователь локально запускает несколько приложений совместно с теми процессами, которые необходимы для функционирования самой системы, и в результате работы переключается между ними. В данном примере при наличии одноядерного CPU с архитектурой x86 каждый процесс будет выполняться отдельно друг от друга, каждый раз переключаясь между собой. Скорость этих переключений будет зависеть от тактовой частоты – характеристикой CPU наравне с битностью (число бит, которым процессор может обмениваться с оперативной памятью за подход). Чем выше частота, тем быстрее работает процессор, поэтому скорость переключений будет выше.</p>

<p>Проблема здесь заключается в увеличении времени ожидания при большом количестве переключений, и чтобы скорость работы оставалась высокой, необходимо увеличить частоту, что может быть экономически очень затратно. Поэтому в современных процессорах реализовано несколько ядер, каждое из которых может отдельно выполнять свои задачи, т.е. при наличии многоядерного CPU процессы могут работать одновременно. Например, при наличии четырехъядерного CPU параллельно могут работать четыре процесса.</p>

<h2 id="многопоточность">Многопоточность</h2>

<p>Логика выполнения программы может быть разбита на несколько потоков в рамках одного процесса совместно с основным потоком, который выполняет ОС. В таком случае потоки будут разделять один пул ресурсов, выделенный ОС. Такая возможность позволяет реализовать одновременно дополнительные вычисления, которые будут выполняться на разных потоках выполнения. В свою очередь, разные потоки могут быть разбиты по разным процессорным ядрам, что повышает производительность и позволяет эффективно задействовать аппаратную часть компьютера. Например, 4 потока на одно ядро совместно с четырьмя разными процессами, каждый из которых выполняется одним из четырех ядер.</p>

<p>Не вдаваясь в детали взаимодействия вычислительных мощностей CPU и потоков, стоит упомянуть о главных недостатках такого подхода в целом.</p>

<p>Во-первых, в большинстве случаев нельзя реализовать 1000 потоков, чтобы сервер мог одновременно обслуживать 1000 человек, т.к. это требует большого количества процессорных ядер, что экономически невыгодно. А наличие меньшего числа потоков может привести к таймаутам, возникающих на стороне клиентов, которые ожидают, когда очередь сервера дойдет до них, если очередь есть.</p>

<p>Во-вторых, при проектировании серверной части с использованием таких языков как JavaScript или Python3, в частности такой его реализацией как CPython, многопоточность не может быть реализована в силу архитектурных особенностей данных ЯП. В CPython присутствует т.н. Global Interpreter Lock, который блокирует интерпретатор при выполнении нескольких потоков. Без GIL CPU-bound операции выполнялись бы в 25 раз медленнее.</p>

<h2 id="асинхронность">Асинхронность</h2>

<p>Наличие GIL в CPython никак не мешает использовать данный ЯП в качестве основного инструмента при проектировании серверной части высокоэффективных веб-приложений. Добиться этого позволяет такая концепция программирования как асинхронность.</p>

<p>Здесь уместно упомянуть о синхронном программировании, главными недостатками которого являются риск остановки всей программы при наличии большого времени ожидания одной операции, а также невозможность эффективно использовать то время, когда программа выполняет какую-либо логику, например, получает данные из базы или стороннего API или производит сложные вычисления. В таком случае пользователь веб-сайта во время получения каких-либо данных не смог бы перемещаться в пределах данной страницы во время выполнения запроса.</p>

<p>Представим, что сервер полностью обрабатывает запрос за 300 мс, в рамках этого времени 100 мс он получает ответ из базы данных, а остальные 200 мс ожидает. Асинхронность или по-другому кооперативная многозадачность и позволяет серверу заполнить эти 200 мс чем-то полезным, в т.ч. обрабатывать параллельные запросы в достаточно большом количестве при отсутствии больших вычислительных мощностей.
Асинхронный код работает в рамках одного процесса и в рамках одного потока, убирает блокирующую операцию из основного потока выполнения, позволяя выполнять следующую операцию, ставя предыдущую на второй план, не блокируя процесс ее выполнения. В том числе, можно запустить четыре процесса программы, где каждое ядро выполняет один процесс и один поток, который в свою очередь выполняет несколько операций одновременно, что еще больше повышает эффективность работы.</p>

<p>Стоит понимать, что асинхронность реализуется на уровне ОС, которая предоставляет необходимые сокеты, а синтаксис и способы работы с отдельными субъектами отличаются в разных ЯП.</p>

<p>Для большего понимания абстракции и концепции асинхронного подхода, необходимо разобрать основные сущности, участвующие в работе, посредством практической реализации небольшого мысленного эксперимента и скрипта.</p>

<p>Представим, что мальчик Петя на летние каникулы уехал отдыхать к бабушке в деревню со списком литературы для чтения. Каждая книга из списка является задачей (task), также у Пети может быть свой список дел, которые он хочет выполнить: сходить в лес за грибами, пойти с дедом на охоту и подстрелить фазана, искупаться в озере минимум 50 раз за лето и т.д. Т.к. Петя живет в нормальном асинхронном мире, он может заниматься своими делами в любом порядке, прерываясь по мере необходимости, т.е. может доделать что-то, оставленное на потом. В рамках этого мысленного эксперимента циклом событий (event loop) является Петя, он управляет задачами, пробегается по каждой из них и проверяет, какая из них выполнена. Задачи могут иметь за собой некий алгоритм работы, иными словами, быть функциями, данные функции называются сопрограммами (coroutine), а задачами становятся, когда передаются циклу событий и стоят в очереди на выполнение. Таким образом, в процессе участвуют три сущности: цикл событий, сопрограмма, задача.</p>

<p>Не вдаваясь в подробности синтаксиса ЯП Python3, реализуем две программы и сравним время выполнения каждой. Они обе будут выполнять одни и те же IO-bound задачи – имитировать выполнение какой-либо операции в течение 1 секунды, генерировать 10 случайных строк, каждая из которых представляет собой информацию о пользователях некоего интернет-ресурса, и записывать их в файл формата CSV.</p>

<p><em>Синхронный код:</em></p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">csv</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">monotonic</span>

<span class="kn">from</span> <span class="nn">faker</span> <span class="kn">import</span> <span class="n">Faker</span>

<span class="n">faker</span> <span class="o">=</span> <span class="n">Faker</span><span class="p">(</span><span class="s">"ru_RU"</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">make_user</span><span class="p">(</span><span class="n">uid</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span> <span class="o">|</span> <span class="nb">int</span><span class="p">]:</span>
    <span class="s">"""Функция, имитирующая выполнение какой-либо операции
    и создающая словарь, значения которого будут переданы
    в объект DictWriter и записаны в файл
    """</span>
    <span class="n">time</span><span class="p">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
    <span class="k">return</span> <span class="p">{</span><span class="s">"id_user"</span><span class="p">:</span> <span class="n">uid</span><span class="p">,</span> <span class="s">"name"</span><span class="p">:</span> <span class="n">faker</span><span class="p">.</span><span class="n">name</span><span class="p">(),</span> <span class="s">"email"</span><span class="p">:</span> <span class="n">faker</span><span class="p">.</span><span class="n">email</span><span class="p">()}</span>


<span class="k">def</span> <span class="nf">main</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="bp">None</span><span class="p">:</span>
    <span class="n">tasks</span> <span class="o">=</span> <span class="p">(</span><span class="n">make_user</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">11</span><span class="p">))</span>
    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">"users.csv"</span><span class="p">,</span> <span class="s">"w"</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s">"utf-8"</span><span class="p">)</span> <span class="k">as</span> <span class="nb">file</span><span class="p">:</span>
        <span class="n">headings</span> <span class="o">=</span> <span class="s">"id_user"</span><span class="p">,</span> <span class="s">"name"</span><span class="p">,</span> <span class="s">"email"</span>
        <span class="n">writer</span> <span class="o">=</span> <span class="n">csv</span><span class="p">.</span><span class="n">DictWriter</span><span class="p">(</span><span class="nb">file</span><span class="p">,</span> <span class="n">headings</span><span class="p">)</span>
        <span class="n">start</span> <span class="o">=</span> <span class="n">monotonic</span><span class="p">()</span>
        <span class="n">writer</span><span class="p">.</span><span class="n">writerows</span><span class="p">(</span><span class="n">tasks</span><span class="p">)</span>
        <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Uptime = </span><span class="si">{</span><span class="n">monotonic</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="si">}</span><span class="s"> sec"</span><span class="p">)</span>


<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>

</code></pre></div></div>

<p><em>Асинхронный код:</em></p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">asyncio</span>
<span class="kn">import</span> <span class="nn">csv</span>
<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">monotonic</span>

<span class="kn">from</span> <span class="nn">faker</span> <span class="kn">import</span> <span class="n">Faker</span>

<span class="n">faker</span> <span class="o">=</span> <span class="n">Faker</span><span class="p">(</span><span class="s">"ru_RU"</span><span class="p">)</span>


<span class="k">async</span> <span class="k">def</span> <span class="nf">make_user</span><span class="p">(</span><span class="n">uid</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span> <span class="o">|</span> <span class="nb">int</span><span class="p">]:</span>
    <span class="s">"""Корутина, имитирующая выполнение какой-либо операции
    и создающая словарь, значения которого будут переданы
    в объект DictWriter и записаны в файл
    """</span>
    <span class="k">await</span> <span class="n">asyncio</span><span class="p">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
    <span class="k">return</span> <span class="p">{</span><span class="s">"id_user"</span><span class="p">:</span> <span class="n">uid</span><span class="p">,</span> <span class="s">"name"</span><span class="p">:</span> <span class="n">faker</span><span class="p">.</span><span class="n">name</span><span class="p">(),</span> <span class="s">"email"</span><span class="p">:</span> <span class="n">faker</span><span class="p">.</span><span class="n">email</span><span class="p">()}</span>


<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="bp">None</span><span class="p">:</span>
    <span class="n">tasks</span> <span class="o">=</span> <span class="p">(</span><span class="n">asyncio</span><span class="p">.</span><span class="n">create_task</span><span class="p">(</span><span class="n">make_user</span><span class="p">(</span><span class="n">i</span><span class="p">))</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">11</span><span class="p">))</span>
    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">"users.csv"</span><span class="p">,</span> <span class="s">"w"</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s">"utf-8"</span><span class="p">)</span> <span class="k">as</span> <span class="nb">file</span><span class="p">:</span>
        <span class="n">headings</span> <span class="o">=</span> <span class="s">"id_user"</span><span class="p">,</span> <span class="s">"name"</span><span class="p">,</span> <span class="s">"email"</span>
        <span class="n">writer</span> <span class="o">=</span> <span class="n">csv</span><span class="p">.</span><span class="n">DictWriter</span><span class="p">(</span><span class="nb">file</span><span class="p">,</span> <span class="n">headings</span><span class="p">)</span>
        <span class="n">start</span> <span class="o">=</span> <span class="n">monotonic</span><span class="p">()</span>
        <span class="n">writer</span><span class="p">.</span><span class="n">writerows</span><span class="p">(</span><span class="k">await</span> <span class="n">asyncio</span><span class="p">.</span><span class="n">gather</span><span class="p">(</span><span class="o">*</span><span class="n">tasks</span><span class="p">))</span>
        <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Uptime = </span><span class="si">{</span><span class="n">monotonic</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="si">}</span><span class="s"> sec"</span><span class="p">)</span>


<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
    <span class="n">asyncio</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>

</code></pre></div></div>

<p>Результат обеих программ представлен ниже. Их главное отличие во времени работы. Первой синхронной программе на выполнение понадобилось 10 секунд, что отображается в консоли по завершении, а второй асинхронной – 1 секунда (к слову, можно записать и 1000 строк за это то же время).</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1,Эрнст Федосьевич Комаров,matveevanisim@example.net
2,Осип Ермолаевич Захаров,lukjan_92@example.com
3,Трифон Вячеславович Овчинников,selivan2007@example.org
4,Виктор Елисеевич Сорокин,filippovroman@example.net
5,Зуева Людмила Николаевна,milen_1973@example.com
6,Кузьмин Климент Гавриилович,kostinanaina@example.com
7,Чернов Самсон Гавриилович,galkinafevronija@example.com
8,Кузьмин Автоном Феодосьевич,avgust_1970@example.org
9,Шестакова Синклитикия Викторовна,foma1982@example.net
10,Агата Сергеевна Белякова,nikitinadam@example.org

</code></pre></div></div>

<p>Данные примеры лишь иллюстрируют принцип работы асинхронности при написании программ, требующих большую скорость работы в конкретный момент.</p>

<h2 id="заключение">Заключение</h2>

<p>В данной работе были рассмотрены использующиеся разработчиками основные методы проектирования приложений, которые позволяют создавать надежные сервисы, способные справиться даже с самой высокой нагрузкой и обеспечить оптимальную производительность для конечных пользователей.</p>

<p>Важно упомянуть, что на этапе реализации так же существуют специальные стратегии и способы, позволяющие эффективно управлять ограничениями ресурсов. К примеру, это использование механизмов кэширования для сокращения количества запросов к базе данных, развертывание нескольких серверов для обработки запросов, оптимизация кода для повышения эффективности. Совместно с внедрением алгоритмов распределения нагрузки и использованием асинхронных моделей программирования можно создавать действительно производительные и более совершенные IT продукты.</p>

<h2 id="список-источников">Список источников</h2>

<ol>
  <li>
    <p><a href="https://www.amazon.com/Python-Concurrency-asyncio-Matthew-Fowler/dp/1617298662">Фаулер М. Asyncio и конкурентное программирование на Python</a></p>
  </li>
  <li>
    <p><a href="https://realpython.com/async-io-python/">Async IO in Python: A Complete Walkthrough – Real Python</a></p>
  </li>
</ol>]]></content><author><name></name></author><category term="python" /><summary type="html"><![CDATA[В данной статье освещаются основные подходы к современной разработке высоконагруженных приложений, в частности, предоставляющие основной интерфейс для взаимодействия с пользователем при помощи браузера или иного клиента, в функционал которого заложена отправка http запросов к серверу.]]></summary></entry></feed>