0+

Часть 1 Веб-серверы и сервисы

Rust — отличный язык программирования, который в наши дни пользуется большой популярностью. Изначально он рекламировался как язык системного программирования, наряду с другими известными языками, такими как C или Go (lang). Действительно, он постепенно проникает в ядро Linux: в настоящее время он ограничен драйверами и модулями, но его неотъемлемые качества — в основном выразительность, безопасность памяти и производительность — несомненно, откроют двери для более важных частей операционной системы. Более медленными темпами Rust также проникает во все еще конфиденциальную область веб-сборки (WAS), в браузере или в бессерверном облаке.

Как и в случае с Go, разработчики-новаторы показали, что применимость Rust выходит за рамки системного программирования и что его можно использовать, например, для разработки эффективных серверных частей веб-приложений, поддерживаемых базами данных.

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

После завершения этой части вы сможете настраивать и разрабатывать надежные серверные части приложений, включая маршрутизацию и обработку ошибок, используя Rust и несколько проверенных в полевых условиях ящиков (crates). После этого вы будете готовы приступить ко второй части.

1. Почему Rust подходит для веб-приложений?

Подключенные веб-приложения, работающие через Интернет, формируют основу современного бизнеса и цифровой жизни людей. Как частные лица, мы используем ориентированные на потребителя приложения для социальных сетей и коммуникаций, для покупок в электронной коммерции, для бронирования поездок, для осуществления платежей и управления финансами, для получения образования и для развлечения — вот лишь некоторые из них. Аналогичным образом, бизнес-ориентированные приложения используются практически во всех функциях и процессах предприятия.

Современные веб-приложения представляют собой невероятно сложные распределенные системы. Пользователи этих приложений взаимодействуют через веб- или мобильные интерфейсы. Но пользователи редко видят сложную среду серверных служб и компонентов программной инфраструктуры, которые отвечают на запросы пользователей, поступающие через простые пользовательские интерфейсы приложений. Популярные потребительские приложения содержат тысячи внутренних сервисов и серверов, распределенных в центрах обработки данных по всему миру. Каждая функция приложения может быть запущена на другом сервере, реализована с использованием другого дизайна, написана на другом языке программирования и расположена в другом географическом месте. Благодаря удобному взаимодействию с пользователем в приложении все выглядит очень просто. Но разрабатывать современные веб-приложения совсем не просто.

Мы используем веб-приложения каждый раз, когда пишем в Твиттере, смотрим фильм на Netflix, слушаем песню на Spotify, бронируем поездку, заказываем еду, играем в онлайн-игру, вызываем такси или пользуемся любым из многочисленных онлайн-сервисов в повседневной жизни. Без распределенных веб-приложений бизнес и современное цифровое общество пришли бы к полной остановке.

Веб-сайты предоставляют информацию о вашем бизнесе.
Веб-приложения предоставляют услуги вашим клиентам.

Из этой книги вы узнаете о концепциях, методах и инструментах, которые понадобятся вам при использовании Rust для проектирования и разработки распределенных веб-сервисов и приложений, взаимодействующих по стандартным интернет-протоколам. Попутно вы увидите основные концепции Rust в действии на практических примерах.

Эта книга для вас, если вы являетесь инженером-программистом веб-серверной части, разработчиком приложений с полным стеком, облачным или корпоративным архитектором, техническим директором технологического продукта или просто любопытным слушателем, заинтересованным в создании распределенных веб-приложений, которые являются невероятно безопасными, эффективными, высокопроизводительными и выполняют следующие функции: не требуют непомерных затрат на эксплуатацию и техническое обслуживание. Разрабатывая рабочий пример по ходу чтения этой книги, я покажу вам, как создавать веб-сервисы и традиционные интерфейсы веб-приложений в чистом виде в Rust.

Как вы увидите из последующих глав, Rust — это язык общего назначения, который эффективно поддерживает разработку множества различных типов приложений. В этой книге представлено одно приложение, но продемонстрированные методы применимы ко многим другим ситуациям с использованием тех же или других ящиков (crates).

В этой главе мы рассмотрим ключевые характеристики распределенных веб-приложений, поймем, как и где работает Rust, и опишем пример приложения, которое мы будем создавать вместе в этой книге.

1.1. Знакомство с современными веб-приложениями

Мы начнем с рассмотрения структуры современных распределенных веб-приложений. В распределенных системах есть компоненты, которые могут быть распределены по нескольким различным вычислительным процессорам, взаимодействовать по сети и одновременно выполнять рабочие нагрузки. Технически ваш домашний компьютер напоминает сетевую распределенную систему (учитывая современные многопроцессорные и многоядерные процессоры).

К популярным типам распределенных систем относятся:

  • Распределенные сети, такие как телекоммуникационные сети и Интернет.
  • Распределенные клиент-серверные приложения. (Большинство веб-приложений относятся к этой категории)
  • Распределенные P2P-приложения, такие как BitTorrent и Tor.
  • Системы управления в режиме реального времени, такие как управление воздушным движением и промышленностью.
  • Распределенные серверные инфраструктуры, такие как облачные, сетевые и другие формы научных вычислений.

  • Распределенные системы в широком смысле состоят из трех частей: распределенных приложений, сетевого стека и аппаратной инфраструктуры и операционной системы.

  • Распределенные приложения могут использовать широкий спектр сетевых протоколов для внутренней связи между своими компонентами. Однако сегодня HTTP является подавляющим выбором для веб-сервиса или веб-приложения, взаимодействующих с внешним миром, благодаря своей простоте и универсальности.

  • Веб-приложения — это программы, использующие HTTP в качестве протокола прикладного уровня и предоставляющие функциональность, доступную обычным пользователям через стандартные интернет-браузеры.

Когда веб-приложения не являются монолитными, а состоят из десятков или сотен распределённых прикладных компонентов, которые взаимодействуют и обмениваются данными по сети, они называются распределёнными веб-приложениями.

Примеры: Facebook, X, Amazon, eBay, Uber, Airbnb, Netflix, AWS, Google Cloud, Azure.

На рисунке 1.1 представлено логическое представление стека распределённых систем для современного веб-приложения.

Рисунок 1.1 Упрощенный стек распределённых систем для приложения социальных сетей

Аппаратные компоненты и инфраструктура операционной системы — это такие компоненты, как физические серверы (в центре обработки данных или облаке), операционная система и средства виртуализации или контейнерные среды выполнения. Такие устройства, как встроенные контроллеры, датчики и периферийные устройства, также могут быть отнесены к этому уровню (представьте себе футуристический случай, когда подписчикам сети супермаркетов в социальных сетях отправляются твиты, когда товары с RFID-маркировкой добавляются на полки супермаркетов или убираются с них).

Сетевой стек — четырёхуровневый набор интернет-протоколов:

  • Уровень сетевых соединений/доступа
  • Уровень Интернета
  • Транспортный уровень
  • Прикладной уровень

  • Первые три уровня обычно реализуются на аппаратном уровне или на уровне ОС. Для большинства распределённых веб-приложений HTTP является основным используемым протоколом прикладного уровня.

Подробнее: Internet Protocol suite

Распределённые приложения — подмножество распределённых систем.

  • Интерфейсы приложений — мобильные приложения (iOS, Android) или веб-интерфейсы.
  • Серверные части приложений — бизнес-правила, логика БД, интеграции. Развёртываются как процессы, микросервисы, контейнеры.
  • Распределённая программная инфраструктура — протоколы, БД, кэши, балансировщики, сервис-дискавери, безопасность, мониторинг.

  • Теперь, когда вы ознакомились с распределёнными веб-приложениями, давайте рассмотрим преимущества использования Rust для их создания.

1.2. Выбор Rust для веб-приложений

Rust можно использовать для создания всех трёх уровней распределённых приложений: интерфейсов, серверных служб и компонентов программной инфраструктуры. Каждый уровень — свой набор задач и характеристик.

Клиентские интерфейсы: дизайн UI, реакция на изменения состояния, обновление DOM.

Серверные службы: оптимизация API, высокая пропускная способность, низкая задержка, эффективное использование ресурсов, доступность.

Инфраструктура: минимальные задержки, низкоуровневое управление ресурсами, быстрый старт, эргономичные API для внутренних сервисов.

Один проект = минимум три набора характеристик и требований.

1.2.1. Характеристики веб-приложений

  • Критически важные приложения (автономное управление, автоматизация, трейдинг и др.)
  • Платформы для транзакций и обмена сообщениями (e-commerce, соцсети, платежи)
  • Реалтайм-приложения (игры, видео, видеоконференции)

К этим приложениям предъявляется общий набор требований:

  • Безопасность и отказоустойчивость
  • Ресурсоэффективность
  • Минимизация задержки
  • Параллелизм
  • Быстрый старт/завершение работы
  • Простота поддержки и реорганизации
  • Производительность разработчика

Все эти требования могут быть выполнены как на уровне сервисов, так и на архитектурном уровне.

1.2.2. Преимущества Rust для веб-приложений

Rust для серверных приложений и инфраструктурных служб отвечает всем критическим требованиям из предыдущего раздела.

  • Безопасность типов: статическая типизация, строгая проверка компилятором, полезные сообщения об ошибках.
  • Безопасность памяти: уникальная модель владения, автоматическое освобождение памяти (RAII), интеллектуальные указатели, отсутствие ручного управления памятью и сборщика мусора.
  • Потокобезопасность: thread-safe по умолчанию, компилятор предотвращает гонки данных.

Важные концепции:
Владение — каждому значению есть владелец. Если значение передано, старый владелец больше не может его использовать.
Заимствование — временный доступ к значению через ссылки (&T или &mut T).
Компилятор гарантирует отсутствие dangling/invalid ссылок. Примеры кода:

// Объявление переменной с выводом типа let x = 5; 
// Передача владения let s1 = String::from("hello"); let s2 = s1; // s1 больше нельзя использовать 
// Неизменяемая ссылка fn print_len(s: &String) { println!("{}", s.len()); } 
// Автоматическое освобождение памяти { let x = String::from("data"); } // x здесь уничтожается автоматически 

Гарантии безопасности:

  • Нет null- и висячих указателей
  • Нет переполнения буфера
  • Отсутствие гонок данных
  • Неизменяемость по умолчанию
  • Нет сборщика мусора → нет nondeterminism
  • Полное сопоставление с образцом (match)
  • Алгебраические типы

Для погружения в безопасность:

Продуктивность:

  • Замыкания (анонимные функции)
  • Итераторы
  • Обобщения и макросы
  • Перечисления (Option, Result)
  • Полиморфизм по трейтам
  • Динамическая диспетчеризация

Не случайно Rust — самый любимый язык в опросе Stack Overflow с 2016 по 2025 годы.

Подробнее: Почему разработчики любят Rust

1.2.3. Чего нет в Rust?

  • Высокая планка входа, особенно для новичков
  • Некоторые структуры данных сложнее (например, двусвязные списки)
  • Компилятор Rust пока медленнее других
  • Молодая экосистема и сообщество
  • Сложнее найти и нанять разработчиков
  • Меньше внедрён в крупные компании

Теперь вы ознакомились с преимуществами и недостатками использования Rust для разработки внутренних сервисов приложений. В следующем разделе — пример приложения.

1.3. Визуализация примера приложения

В следующих главах мы будем использовать Rust для создания веб-серверов, веб-служб и веб-приложений и продемонстрируем концепции на подробном примере. Наша цель — не полностью функциональное приложение, а показать подходы Rust в веб-домене.

Будем разрабатывать: цифровую витрину для преподавателей EzyTutors, где преподаватели могут размещать каталоги своих курсов. Это не marketplace, а витрина для продажи собственных курсов.

  • Регистрация и вход преподавателей
  • Публикация курсов, связь с категориями
  • Персональная страница преподавателя
  • Общий сайт — поиск и просмотр курсов

Технический стек: Rust (Actix Web), SQLx, Postgres, полный async, шаблоны для SSR.
Особенности: не используется фронтенд-фреймворк, не рассматривается CI/CD, весь проект максимально универсален (кроссплатформенность, контейнеризация поддерживается).

В процессе: создаём RESTful веб-сервис, затем расширяем модель, добавляем функциональность, рефакторим код.
Бонус: интерфейс на шаблонах, отдельная архитектура, контейнеризация.

Методы и приёмы:

  • Строгая типизация, тесты
  • Модули и рабочие пространства
  • Асинхронность, обработка ошибок
  • Чистый и идиоматичный код

Что не рассматривается: DevOps-инфраструктура, прокси, балансировщики, TLS/SSL, мониторинг, CDN и т.д.

В проекте покажем: автоматизированные тесты, структурирование, отделение конфигурации от кода, документация, идиоматичный Rust.

Готовы ли вы к практическому использованию Rust в Интернете?

1.3.2. Технические рекомендации для примера приложения

  1. Структура проекта: используем модульную систему Rust, рабочие пространства Cargo.
  2. Принцип единой ответственности: каждый модуль — отдельная функциональность.
  3. Удобство сопровождения:
    • Понятные имена переменных и функций
    • Форматирование с rustfmt
    • Автоматизированные тесты
    • Структура и имена файлов должны быть интуитивно понятны
  4. Безопасность: JWT, пароли, memory-safety Rust
  5. Конфигурация отдельно от кода
  6. Минимум внешних crate’ов
  7. Асинхронность во всём стеке

Теперь мы можем приступить к изучению веб-серверов и веб-служб в следующей главе.

Резюме

  • Современные веб-приложения — сложные, критически важные для жизни и бизнеса.
  • Веб-приложения = интерфейсы + сервер + инфраструктура.
  • Серверные части — слабо связанные сервисы с особыми требованиями к времени выполнения.
  • Rust подходит для распределённых веб-приложений: безопасность, параллелизм, низкая задержка, ресурсоэффективность.
  • В книге выбран практический пример приложения и приведены ключевые рекомендации.