Приветствую вас, друзья! Меня зовут Олег, я системный аналитик в компании EvApps. В этой статье хочется рассказать о развитии веб-технологий и о том, как технологии  пришли из вот такого вида:

к вот такому виду: 

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

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

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

Начало: HTML и статические страницы

Развитие веба в том виде, в котором мы его знаем, началось в 1990 году, согласно Википедии. С тех пор прошло 35 лет и веб прошел колоссальный путь развития. 

Изначально он представлял собой обычные HTML-документы, обычные HTML-страницы, благодаря которым люди могли обмениваться информацией. 

HTTP-протокол (справка: HyperText Transfer Protocol — это основной протокол для передачи данных в интернете. Он определяет, как браузеры и серверы обмениваются информацией.) служит для передачи HTML-данных между клиентом (обычно веб-браузером) и сервером. При этом каждая вот такая доступная страница в интернете имеет свой адрес. А связь между этими страницами достигается за счет гиперссылок, которые позволяют из одной страницы перейти в другую.

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

Со временем простого HTML стало недостаточно. Разработчики захотели добавлять визуальные элементы на страницы: менять цвета, шрифты, размеры и позиционирование. Для этого был создан CSS (каскадные таблицы стилей), который позволил отделить содержимое страницы от ее оформления. Но, опять же, это всего лишь внешний вид нашей страницы.

Появление Backend: работа с данными

Очевидно, что рано или поздно с таким мощным инструментом обмена данными нам понадобится не только отображение какой-то информации, но и ее сбор - различные формы, с помощью которых мы можем получать информацию о пользователях, находящихся в тысячах километров от нас. Но отправить какую-то информацию мало. Эту информацию необходимо куда-то сохранить. И вот здесь мы подходим к back-end технологиям, к серверным решениям, которые будут работать с данными.

Например, как это работает:

  1. Пользователь ввел в браузере адрес какого-то приложения или сайта

  2. Отправляется HTTP GET запрос на сервер

  3. Сервер знает, какую HTML-страницу по этому адресу необходимо отдать, и отправляет пользователю в ответ

  4. Пользователь видит отрисованным в браузере HTML

Таким образом, пользователь получает готовую страницу, с которой можно уже работать и взаимодействовать. Для того, чтобы отдавать статичные страницы, в которых нет динамических данных, нам достаточно иметь простейший веб-сервер, который умеет отдавать статические файлы. То есть он “слушает” запросы и по ним идентифицирует нужные -  например,: html-файлы, index.html, contacts, about, main и так далее. И эти файлы он отдает.

Динамические данные и базы данных

Теперь мы хотим собирать данные, и, соответственно, эти данные уже не статические, а динамические. 

Например, как это работает:

  1. Пользователь открывает страницу. У него отрисована форма

  2. В эту форму он вводит какие-либо данные

  3. Нажимает кнопку “Отправить”, и на сервер отправляется POST запрос

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

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

Для простых страниц можно обойтись без JavaScript, но с усложнением он становится незаменим, так как отвечает за логику и динамику. JavaScript также позволяет использовать асинхронные запросы.

Cправка:

Синхронное взаимодействие – когда один компонент системы отправляет запрос и ждет ответа перед тем, как продолжить работу.
Пример: классический HTTP-запрос от клиента к серверу. 

Асинхронное взаимодействие – когда запрос отправляется, но система не ждет немедленного ответа и может выполнять другие задачи.
Пример: обмен данными через очереди сообщений (RabbitMQ, Kafka) или WebSockets. 

Асинхронность помогает лучше масштабировать системы, снижая зависимость компонентов друг от друга.).

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

Раньше сервер и клиент были единым целым: сервер генерировал HTML с данными и отправлял её в браузер. С появлением асинхронных запросов и JavaScript произошел еще один шаг - разделение на фронтенд (клиент) и бэкенд (сервер). Теперь это два отдельных приложения, разработкой которых занимаются разные команды — фронтендеры и бэкендеры.

Бэкенд: от монолита к микросервисам

Раньше веб-приложения состояли из множества HTML-страниц, каждая из которых ссылалась на CSS и JavaScript. С появлением асинхронных запросов и JSON необходимость в большом количестве HTML отпала - контент стал динамически обновляться через JavaScript. Так появились SPA (Single Page Application), где всё взаимодействие происходит в рамках одной страницы. Например, пользователь открывает страницу, данные подгружаются, а при переходе по ссылкам контент обновляется без перезагрузки.

Фронтенд и бэкенд теперь разделены. Фронтенд - это отдельное приложение, которое раздаётся через веб-серверы, например, Nginx или Apache. Бэкенд - это приложение с бизнес-логикой, которое  взаимодействует с базой данных (MySQL, Postgres) и возвращает данные в форматах JSON, XML и других. Один бэкенд может обслуживать множество клиентов: веб-приложения, мобильные приложения или партнёрские API.

Инфраструктура бэкенда усложнилась. Помимо реляционных баз данных (MySQL, Postgres), появились NoSQL (например, MongoDB) для хранения слабоструктурированных данных. Для ускорения доступа к данным используются кэши (Redis, Memcache), например, для хранения сессий или токенов.

Для автоматизации тестирования, сборки и развертывания применяются CI/CD (Jenkins, GitLab CI/CD, GitHub Actions). Приложения упаковываются в Docker-контейнеры, что упрощает их развертывание на разных серверах.

С ростом сложности монолитная архитектура стала менее эффективной. На смену пришли микросервисы, где каждый сервис отвечает за свою задачу: например, в интернет-магазине отдельно платежная система, информация о пользователях, авторизация, товары, заказы, отзывы и новостная лента. У каждого сервиса свой CI/CD, что делает развертывание независимым. Это повышает отказоустойчивость: если один сервис падает, другие продолжают работать. Так мы пришли к микросервисной архитектуре.

Мы декомпозировали сервисы: несмотря на их независимость, они остаются частями одного большого продукта. Для единой точки входа создается API Gateway, который перенаправляет запросы к нужным микросервисам.

Для обмена данными между фронтендом и бэкендом чаще всего используется REST API, но также могут применяться SOAP, GraphQL или gRPC. Для реального времени (например, чаты или уведомления) добавляются WebSockets.

С ростом инфраструктуры возникает необходимость хранить большие объемы файлов и аналитических данных. Для аналитики, где нужно быстро читать огромные объемы данных (например, действия пользователей, поисковые запросы, покупки), используются специализированные базы, такие как Clickhouse. Они оптимизированы для быстрого чтения и хранения больших данных.

Чтобы гарантировать доставку сообщений между микросервисами, используется брокер сообщений, например, RabbitMQ или Kaffka. Он может предотвратить потерю данных, даже если сервис временно недоступен. 

Для полнотекстового поиска, который сложно реализовать самостоятельно, используются специализированные инструменты, такие как Elasticsearch. Он позволяет быстро и эффективно искать данные в больших объемах текста.

С ростом числа микросервисов (иногда их десятки) управление контейнерами становится сложной задачей. Для этого применяется Kubernetes, который автоматизирует развертывание, масштабирование и управление контейнерами.

Для выполнения задач по расписанию, например, удаление неактивных пользователей или рассылка уведомлений по расписанию, добавляется планировщик. Он автоматически выполняет операции в заданное время, упрощая управление повторяющимися процессами.

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

В текущей точке мы имеем сложную систему с распределенной инфраструктурой, обслуживающей миллионы пользователей. Чтобы обеспечить стабильность, важно избежать зависимости от одного дата-центра. Если он выйдет из строя, весь сервис остановится, что приведёт к большим потерям. Для этого нагрузка распределяется между несколькими дата-центрами (например, 4 вместо 1). Если один откажет, остальные продолжат работу. Это касается как серверной части, так и клиентской, где Nginx раздаёт статику. Балансировщик настраивается для равномерного распределения запросов между дата-центрами.

Фронтенд: путь к микрофронтендам

Современный фронтенд - это не просто «верстка и кнопочки», а сложная система, сравнимая по масштабам с бэкендом. Чтобы упростить поддержку, фронтенд также переходит на подобную микросервисам архитектуру - микрофронтенд. В монорепозитории хранятся все микрофронтенды и переиспользуемые компоненты: UIKit (кнопки, инпуты), общие модули, конфигурации и функции. Это позволяет легко заменять или удалять сервисы без влияния на другие. Другими словами, микрофронтенд состоит из компонентов, которые могут принадлежать разным командам и развертываться независимо.

Фронтенд стал сложнее из-за роста требований к веб-приложениям: теперь они должны быть быстрее, интерактивнее и масштабируемее. Раньше это был просто HTML, CSS и немного JavaScript, но со временем появились сложные интерфейсы, требующие управления состоянием, модульности и независимого развертывания. Теперь фронтенд тоже использует “микросервисную” архитектуру, потому что крупные приложения разбивают на микрофронтенды - отдельные модули, разрабатываемые и развертываемые независимо. Это позволяет разным командам работать автономно, упрощает поддержку и масштабирование, а также делает систему более гибкой. Для упрощения работы используются сборщики (Webpack, Rollup, Vite), которые сжимают код, подготавливают его для продакшена и обеспечивают совместимость с помощью Babel. На выходе получается бандл - весь код приложения, который раздаётся сервером.

Для разработки фронтенда используются популярные фреймворки: React, Vue, Angular или Svelte и т.д. Сборка осуществляется с помощью Webpack, Vite, TurboPack, Rollup или Sbuild и т.д. Для управления состоянием применяются стейт-менеджеры: Redux, MobX, VueX, Effector. Для серверного рендеринга (SSR) используются Nuxt, Next или кастомные решения на Node.js.

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

Заключение

Развитие веб-разработки прошло долгий путь от обычной HTML страницы к микросервисной архитектуре как на бэкенде, так и на фронтенде.  

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

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

Комментарии (0)