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


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

РКН clck.ru/3KoGeP
Download Telegram
🧵 Виртуальные потоки: Революция производительности

Представьте, что вы строите высоконагруженный сервер. Раньше у вас было два пути:

1. Классика (Thread): Простой код, но один поток весит ~2 Мб памяти. Создадите 5,000 потоков - сервер упадет с OutOfMemoryError.
2. Асинхронность (WebFlux/Netty): Сервер держит 100k соединений, но код превращается в лапшу из callbacks и CompletableFuture, которую невозможно отлаживать.

В Java 21 появились Виртуальные потоки. Они объединяют простоту первого подхода и производительность второго.

🪶 В чем магия?

Классический поток Java (Platform Thread) привязан 1-к-1 к потоку операционной системы (OS Thread). Это дорогой ресурс.

Виртуальный поток, это просто объект в куче (heap) JVM. Он не привязан к ОС намертво.

🔴Вес: Несколько килобайт (вместо мегабайт).
🔴Количество: Можно создать миллион виртуальных потоков на обычном ноутбуке.

⚙️ Как это работает (Carrier Threads)

Под капотом работает схема Mount/Unmount:

1. JVM запускает небольшой пул обычных потоков ОС (называются Carrier Threads, обычно их число = числу ядер CPU).
2. Ваш виртуальный поток "садится верхом" на Carrier-поток и выполняет код.
3. ⚠️ Самое важное: Как только ваш код блокируется (ждет ответа от БД, читает файл, делает Thread.sleep), JVM снимает виртуальный поток с ядра.
4. Поток ОС освобождается и тут же берет в работу другой виртуальный поток.

Итог: Ядра процессора молотят на 100%, никогда не простаивая в ожидании ввода-вывода.

💻 Код: Найди 1 отличие

API практически не изменился. Вам не нужно учить новые фреймворки.


// Старый способ (Тяжелый поток ОС)
Thread.ofPlatform().start(() -> {
System.out.println("Я ем много памяти!");
});

// Новый способ (Легкий виртуальный поток)
Thread.ofVirtual().start(() -> {
System.out.println("Я ничего не вешу!");
});

// Использование с ExecutorService (для старого кода)
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 1_000_000).forEach(i -> {
executor.submit(() -> {
Thread.sleep(1000); // Блокировка теперь БЕСПЛАТНАЯ
return i;
});
});
}
// Этот код запустит миллион задач за секунду, не положив сервер.



⚰️ Конец Reactive Programming?

Многие эксперты говорят: Да.
Смысл использования сложных реактивных библиотек (RxJava, Reactor) был в том, чтобы не блокировать потоки. Виртуальные потоки делают блокировку дешевой.
Теперь вы можете писать простой, последовательный код:
var user = db.findUser();
var data = http.sendRequest(user);
...и он будет работать так же эффективно, как сложный асинхронный код.

⚠️ Когда НЕ использовать?

Виртуальные потоки идеальны для I/O задач (ждать сеть, ждать диск).
Они бесполезны для CPU-Intensive задач (майнинг, шифрование, обработка видео). Если поток не ждет, а считает, он занимает поток ОС, и виртуалка тут не поможет.

🔥 Итог
Project Loom вернул нам девиз: "Один запрос - Один поток".
Больше никаких пулов потоков с ограниченным размером. Просто создавайте новый виртуальный поток для каждой задачи.

#Java #Loom #VirtualThreads #Concurrency #HighLoad

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥113
🌍 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