Библиотека Java разработчика
10.3K subscribers
1.05K photos
594 videos
58 files
1.41K links
📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate.


По всем вопросам @evgenycarter

РКН clck.ru/3KoGeP
Download Telegram
От 1 до миллиона пользователей (Масштабирование)

Представьте: вы написали крутой стартап. Он крутится на дешевом сервере за $5 в месяц. База данных, бэкенд и фронтенд лежат в одном месте.
Вдруг о вас снимает ролик популярный блогер. Трафик вырастает в 10,000 раз. Сервер ложится через 3 секунды от OutOfMemoryError. Бизнес теряет деньги. Что делать?

У вас есть два пути масштабирования (Scaling).

📈 1. Вертикальное масштабирование (Scale Up)

Это самый простой и интуитивный подход.
Сервер не справляется? Давайте купим сервер мощнее! Было 2 ГБ оперативки - поставим 128 ГБ. Был 1 ядерный процессор - купим 64-ядерный.

🔴Плюсы: Не нужно менять ни строчки кода. Всё просто работает быстрее.
🔴Минусы: 1. Физический предел. Вы не можете купить сервер с бесконечной памятью. Самый мощный сервер рано или поздно закончится.
2. SPOF (Single Point of Failure). Единая точка отказа. Каким бы мощным ни был сервер, если уборщица выдернет шнур питания в дата-центре - ваш бизнес остановится.

🌐 2. Горизонтальное масштабирование (Scale Out)

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

🔴Плюсы: Масштабирование практически бесконечно. Упал один сервер? Ничего страшного, трафик подхватят остальные 999.
🔴Минусы: Архитектура становится в разы сложнее. Появляется куча новых проблем: как делить трафик, как синхронизировать данные, как хранить сессии.

⚖️ 3. Балансировщик нагрузки (Load Balancer)

Допустим, мы выбрали горизонтальное масштабирование и запустили 5 одинаковых серверов с нашим Spring Boot приложением.
Но пользователи (клиенты) знают только один домен: mysite.com. Как сделать так, чтобы запросы распределялись между этими пятью серверами равномерно?

Перед нашими серверами встает Load Balancer (Балансировщик) - например, Nginx, HAProxy или облачный AWS ALB.

Пользователь стучится в Балансировщик, а тот перенаправляет запрос на наименее загруженный сервер.

🔴Round Robin: Самый простой алгоритм. Запросы раздаются по кругу: первому серверу, второму, третьему, первому, второму...
🔴Least Connections: Запрос уходит на тот сервер, у которого сейчас меньше всего активных соединений.

🧠 4. Главное правило: Stateless (Без состояния)

Горизонтальное масштабирование ломает старый подход к хранению сессий.
Если пользователь залогинился и попал на Сервер №1, этот сервер сохранил его данные в оперативной памяти. При следующем клике балансировщик может кинуть пользователя на Сервер №2. А Сервер №2 скажет: "Я тебя не знаю, авторизуйся заново".

Решение: Серверы приложения должны быть "глупыми" и ничего не помнить (Stateless).
Состояние должно храниться в общем внешнем хранилище (например, в Redis, как мы обсуждали в прошлых сезонах), либо передаваться прямо в запросе с помощью токенов (JWT).

🔥 Итог

1. Vertical Scaling (вверх) - купить "железо" помощнее. Дорого, есть предел.

2. Horizontal Scaling (вширь) - поставить больше дешевых серверов. Требует изменения архитектуры.

3. Load Balancer - дирижер, который распределяет трафик между клонами.

4. Stateless - обязательное условие. Приложение не должно хранить локальное состояние.

#SystemDesign #Architecture #Scaling #LoadBalancing #Backend

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6👏1
🌍 CDN: Как обмануть скорость света и расстояния

CDN (Content Delivery Network / Сеть доставки контента) - это географически распределенная сеть серверов, задача которых - отдавать контент пользователю из максимально близкой к нему точки.

🏢 1. Origin и Edge: Разделение ролей

В архитектуре с CDN появляются два новых понятия:

Origin Server (Главный сервер): Это ваш настоящий сервер, где крутится Spring Boot, лежит база данных и хранятся оригиналы всех файлов (например, в Amazon S3).
Edge Servers (Граничные серверы / Точки присутствия - PoP): Это тысячи серверов CDN-провайдера (например, Cloudflare или Akamai), раскиданные по всему земному шару: в Сиднее, Токио, Нью-Йорке, Лондоне, Москве.

⚙️ 2. Как это работает (Cache Hit & Miss)

Представьте, что австралийский пользователь впервые запрашивает логотип вашего сайта logo.png.

1. Cache Miss (Промах кэша): Запрос летит на ближайший к нему Edge-сервер в Сиднее. Сервер проверяет свою память и видит: "У меня нет этого файла".

2. Поход на Origin: Edge-сервер сам идет на ваш главный сервер в Германию, скачивает logo.png, сохраняет копию у себя на диске (кэширует) и отдает пользователю. Это было долго (те самые 300 мс).

3. Cache Hit (Попадание в кэш): Через секунду заходит второй пользователь из Сиднея и просит тот же logo.png. Edge-сервер моментально отдает ему файл из своей памяти за 5 миллисекунд. Запрос до Германии даже не доходит!

📦 3. Что кладем в CDN, а что нет?

CDN идеально подходит для Статического контента:

• Картинки, видео, аудио.
• Скомпилированные файлы JavaScript и CSS.
• Шрифты.

CDN категорически НЕ подходит для Динамического контента:

• Баланс банковского счета.
• Корзина товаров.
• Приватные данные пользователя.
(Запросы к API /api/v1/users/me должны идти напрямую на ваш сервер, минуя кэш CDN).

🛡️ 4. Защита от DDoS

Современные CDN (тот же Cloudflare) - это не просто кэш. Это гигантский щит.
Если хакеры решат "положить" ваш сайт и отправят миллион запросов в секунду, этот удар примут на себя серверы CDN. Их пропускная способность измеряется терабитами. Они отфильтруют "мусорный" трафик, и ваш маленький Origin-сервер в Германии даже не заметит атаки.

🔥 Итог

Ускорение: Пользователи получают тяжелый контент мгновенно, потому что скачивают его из своего же города.

Экономия: Ваш главный сервер больше не тратит процессорное время и трафик на отдачу терабайтов картинок. Вы платите за сервера меньше.

Безопасность: CDN скрывает реальный IP-адрес вашего сервера и защищает от DDoS-атак.

#SystemDesign #CDN #Cloudflare #Architecture #HighLoad

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🔎 Elasticsearch: Как найти иголку в стоге сена за 10 мс

Представьте каталог на 10 миллионов товаров. Пользователь вводит в поиск: "айфон 15 про макс".

🐌 1. Почему SQL здесь бессилен?

В реляционной базе (PostgreSQL/MySQL) вы бы написали:
SELECT * FROM products WHERE name LIKE '%айфон 15%'

В чем проблема?

1. Full Table Scan: База данных не может использовать обычный B-Tree индекс для поиска по части слова (с LIKE '%...'). Ей придется прочитать все 10 миллионов строк на диске, чтобы найти совпадения. Это убьет процессор.

2. Нулевая толерантность к ошибкам: Если пользователь опечатался и написал "айфно", SQL вернет 0 результатов. Бизнес потерял клиента.

3. Нет релевантности: SQL не понимает, какой товар подходит "лучше". Он просто отдает всё, что нашел, по дате добавления.

🧠 2. Инвертированный индекс (Inverted Index)

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

Вместо того чтобы искать слово на страницах, мы заранее составляем список всех слов и записываем, на каких страницах они встречаются.

Пример:
У нас есть три товара (Документа):

Doc 1: "Красный телефон Apple"
Doc 2: "Синий чехол для телефона"
Doc 3: "Красный чехол"

Инвертированный индекс будет выглядеть так:

красный -> [Doc 1, Doc 3]
телефон -> [Doc 1, Doc 2]
apple -> [Doc 1]
синий -> [Doc 2]
чехол -> [Doc 2, Doc 3]

Теперь, если мы ищем "красный телефон", система просто берет списки для этих двух слов: [1, 3] и [1, 2]. Пересечение этих списков - Doc 1. Мы нашли результат за O(1)! Никакого сканирования миллионов строк.

🚀 3. Встречайте Elasticsearch (ES)

Elasticsearch - это не просто база данных, это полноценный поисковый движок (написанный на Java поверх библиотеки Apache Lucene).

Он хранит данные не в таблицах, а в виде JSON-документов, и автоматически строит инвертированный индекс для каждого текстового поля.

🪄 Магия Elasticsearch:

1. Анализаторы (Стемминг и Лемматизация): Перед тем как положить текст в индекс, ES его обрабатывает. Он приводит слова к базовой форме, убирает окончания и предлоги.
Слова "айфон", "айфону", "айфоном" попадут в индекс как один токен "айфон".


2. Поиск с опечатками (Fuzzy Search): ES использует Расстояние Левенштейна (сколько букв нужно изменить, чтобы получить правильное слово).
Запрос "йафон" автоматически найдет "айфон", потому что разница всего в одну перестановку.


3. Релевантность (Scoring - BM25): ES каждому результату присваивает "Оценку". Чем реже слово встречается во всей базе и чем чаще в конкретном документе, тем выше этот документ будет в выдаче.

🏗️ 4. Как это выглядит в Архитектуре?

Важное правило: Elasticsearch не заменяет вашу основную базу данных.
ES - это поисковик. Он может потерять данные при сбоях (он оптимизирован на скорость чтения, а не на надежность хранения ACID).

Правильный паттерн (CQRS-лайт):

1. "Правда" живет в PostgreSQL.

2. Когда товар добавляется или меняется в Postgres, вы отправляете событие в брокер сообщений (Kafka) или используете CDC (Change Data Capture - например, Debezium), чтобы прочитать логи БД.

3. Специальный воркер берет эти изменения из Kafka и синхронизирует их с Elasticsearch.

4. Фронтенд: за созданием/покупкой товара ходит в Postgres, а за поиском — в Elasticsearch.

🔥 Итог

SQL LIKE - для админок и маленьких таблиц.
Инвертированный индекс - ключ к мгновенному поиску.
Elasticsearch - стандарт индустрии для полнотекстового умного поиска, логов (помните ELK?) и аналитики.

#SystemDesign #Elasticsearch #Search #Architecture #HighLoad

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥74👍1
🕸️ Service Mesh: Инфраструктура, невидимая для кода

Проблема: "Толстые" микросервисы
Если вы используете Spring Cloud (Netflix OSS), ваша бизнес-логика перемешана с сетевой логикой.
Вам нужно добавлять в код Java аннотации для ретраев (повторных запросов), настраивать Circuit Breaker (Предохранитель), писать логику для распределенной трассировки.

А теперь представьте, что в компанию пришла команда, которая пишет на Go или Node.js. Им придется искать аналоги всех этих библиотек для своих языков! Разве сеть это проблема программиста? Нет, это проблема инфраструктуры.

🦸‍♂️ Решение: Service Mesh и паттерн Sidecar
Service Mesh (Сервисная сетка) - это выделенный инфраструктурный слой для безопасного, быстрого и надежного общения микросервисов друг с другом. Самый популярный инструмент на рынке - Istio.

Вся магия строится на паттерне Sidecar (Коляска мотоцикла).


Рядом с вашим контейнером Java в том же поде (Pod) Kubernetes незаметно запускается второй маленький контейнер - Proxy-сервер (обычно это Envoy).

Теперь ваше Java-приложение вообще ничего не знает о внешнем мире.
1. Оно хочет отправить запрос в PaymentService? Оно просто шлет HTTP-запрос на localhost.

2. Sidecar-прокси перехватывает этот запрос.

3. Sidecar сам находит нужный сервис, сам шифрует трафик, сам делает ретраи, если сеть моргнула, и отправляет запрос другому Sidecar-у на стороне PaymentService.

🎛️ Как устроен Istio: Data Plane и Control Plane

Data Plane (Плоскость данных): Это армия тех самых Sidecar-прокси (Envoy), которые стоят рядом с каждым сервисом и перекидывают байты.

Control Plane (Плоскость управления): Это мозг (Istiod). Он раздает команды всем прокси-серверам: "Так, с сегодняшнего дня все запросы шифруем", "А теперь 5% трафика направь на новую версию сервиса".

Суперспособности Service Mesh

Зачем терпеть усложнение архитектуры? Ради этих фич:

1. Управление трафиком (Traffic Routing)
Вам больше не нужно деплоить новую версию на всех сразу и молиться, чтобы она не упала.
Вы можете сказать Istio: "Пусти 99% пользователей на версию v1, и только 1% пользователей с iPhone - на версию v2 (Канареечный релиз)". Если v2 работает стабильно, плавно увеличиваем процент.

2. Нулевое доверие (Zero-Trust Security & mTLS)
Если хакер проникнет во внутреннюю сеть дата-центра, он сможет "слушать" трафик между вашими сервисами (там могут лететь пароли и токены в открытом виде).
Istio из коробки включает mTLS (Mutual TLS). Трафик между ВСЕМИ микросервисами автоматически шифруется. При этом разработчикам не нужно возиться с сертификатами в Java-коде.

3. Наблюдаемость (Observability) без кода
Помните Jaeger, Zipkin и Prometheus из прошлого сезона? Чтобы они работали, мы добавляли библиотеки в pom.xml.
С Service Mesh это не нужно! Так как все запросы проходят через Sidecar-прокси, он сам собирает метрики (сколько времени занял запрос, какие были ошибки) и сам рисует красивые графы зависимостей в Grafana и Jaeger.

4. Устойчивость к сбоям (Resilience)
Если PaymentService "лежит", Sidecar может автоматически сделать 3 повторные попытки (Retry) с интервалом в секунду. Если сервис всё равно не отвечает, Sidecar включит Circuit Breaker (разорвет цепь) и будет сразу возвращать ошибку, чтобы не перегружать зависший сервис.

⚔️ Service Mesh vs API Gateway
Часто спрашивают: "Зачем мне Istio, если у меня уже есть Spring Cloud Gateway?"
API Gateway: Управляет трафиком Север-Юг (Снаружи вовнутрь). Он стоит на границе интернета и вашей системы, принимает запросы от пользователей, проверяет JWT-токены и пускает внутрь.

Service Mesh: Управляет трафиком Восток-Запад (Внутри системы). Он следит за тем, как микросервисы общаются между собой за закрытыми дверями.

🔥 Итог
Service Mesh (Istio) - это инструмент для крупных и сложных систем.
Если у вас 5 микросервисов - это оверкилл, используйте Spring Cloud.
Если у вас 100 микросервисов на разных языках программирования, строгие требования к безопасности (банки) и частые релизы без Service Mesh вы сойдете с ума.

#SystemDesign #ServiceMesh #Istio #Microservices #DevOps

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥43👍2💩1
🔌 Проектирование API: REST, GraphQL или gRPC?


🧱 1. REST (Классика и Стандарт)

REST (Representational State Transfer) - это де-факто стандарт интернета. Большинство публичных API (GitHub, Stripe, Telegram) построены на нем.

Суть: В центре всего находится Ресурс (Существительное). А действия над ним выполняются через стандартные HTTP-методы (Глаголы).
GET /users/123 - Дай мне пользователя 123.
POST /users - Создай пользователя.
DELETE /users/123 - Удали пользователя.

Плюсы:

Простота: Понятен всем, легко тестировать через Postman или браузер.

Кэширование: Идеально работает с CDN (о которых мы говорили раньше), так как использует стандартные механизмы HTTP.

Минусы:

Over-fetching (Избыточность): Мобильному приложению нужно только имя пользователя, но метод GET /users/1 возвращает огромный JSON на 50 полей (с адресами, датами и т.д.). Вы тратите трафик впустую.

Under-fetching (Недостаточность) и проблема N+1: Чтобы показать профиль пользователя и его 10 последних постов, фронтенду придется сделать 1 запрос к /users/1 и еще 10 запросов к /posts?userId=1. Это медленно.


🕸️ 2. GraphQL (Мечта Фронтендера)

Разработан в Facebook для решения проблем REST при слабом мобильном интернете.

Суть: У вас есть всего один Endpoint (обычно POST /graphql). Клиент сам пишет запрос-схему, где указывает, какие конкретно поля ему нужны.

Запрос клиента:

query {
user(id: "123") {
name
email
posts(last: 10) {
title
}
}
}

Ответ сервера: Вернется JSON строго с именем, email и 10 заголовками постов. Ни одним байтом больше!

Плюсы:

• Решает проблемы Over-fetching и Under-fetching. Один запрос = ровно те данные, что нужны для отрисовки экрана.

• Быстрая итерация фронтенда: UI-команде больше не нужно просить бэкендеров написать новый endpoint /users-with-posts-and-comments.


Минусы:

Сложность кэширования: Так как всё идет через один URL POST /graphql, вы не можете просто закэшировать это на уровне CDN (Cloudflare).

Угроза для Базы Данных: Если клиент напишет слишком глубокий вложенный запрос (Пользователь -> Посты -> Комментарии -> Авторы комментариев -> Их посты), ваша БД просто "ляжет".


🚀 3. gRPC (Спидраннер для Микросервисов)

Разработан в Google. Если REST и GraphQL общаются с помощью удобочитаемого текста (JSON) поверх старого HTTP/1.1, то gRPC ломает эти правила.

Суть: Вы вызываете функцию на другом сервере так, будто она лежит в вашем собственном коде.
Он использует HTTP/2 (поддерживает стриминг) и Protobuf (Protocol Buffers).
Protobuf - это бинарный формат. Вместо того чтобы передавать ключи "name": "Alex", он передает просто байты по заранее оговоренной жесткой схеме (.proto файл).



Плюсы:

Невероятная скорость: Бинарный формат весит в разы меньше JSON и парсится процессором мгновенно. gRPC работает до 10 раз быстрее REST.

Строгая типизация: Вы описываете контракты в .proto файле, и из него автоматически генерируется код и для Java-бэкенда, и для Python-клиента. Никаких ошибок "ожидал строку, пришло число".

Стриминг: Можно открыть соединение и непрерывно лить данные в обе стороны.


Минусы:

Не читается человеком: Вы не можете просто открыть консоль браузера и посмотреть payload, там будут непонятные бинарные символы.

Плохая поддержка браузерами: Напрямую из JavaScript в браузере gRPC вызвать сложно (нужен прокси grpc-web), поэтому для публичного фронтенда его почти не используют.


В идеальной современной архитектуре:
Мобилка общается с API Gateway по GraphQL —> Gateway общается с внутренними микросервисами по gRPC.

#SystemDesign #API #REST #GraphQL #gRPC #Java

📲 Мы в MAX

👉@BookJava
8👍6