Библиотека Java разработчика
📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate. По всем вопросам @evgenycarter РКН clck.ru/3KoGeP
Больше📈 Аналитический обзор Telegram-канала Библиотека Java разработчика
Канал Библиотека Java разработчика (@bookjava) языкового сегмента Русский является активным участником. Сейчас сообщество объединяет 10 265 подписчиков, занимая 12 032 место в категории Технологии и приложения и 63 928 место в регионе Россия.
📊 Показатели аудитории и динамика
С момента создания невідомо проект демонстрирует стремительный рост, собрав аудиторию из 10 265 подписчиков.
Согласно последним данным от 09 июня, 2026, канал показывает стабильную активность. За последние 30 дней изменение числа участников составило 16, а за последние 24 часа — -6, при этом общий охват остаётся высоким.
- Статус верификации: Не верифицирован
- Уровень вовлечённости (ER): Средний показатель вовлечённости аудитории составляет 8.19%. В первые 24 часа после публикации контент обычно набирает 4.03% реакций от общего числа подписчиков.
- Охват публикаций: В среднем каждый пост получает 841 просмотров. В течение первых суток публикация набирает 414 просмотров.
- Реакции и взаимодействия: Аудитория активно поддерживает контент: среднее количество реакций на один пост — 6.
- Тематические интересы: Контент сосредоточен на ключевых темах, таких как string, интерфейс, строка, boot, api.
📝 Описание и контентная политика
Автор описывает ресурс как площадку для выражения субъективного мнения:
“📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate.
По всем вопросам @evgenycarter
РКН clck.ru/3KoGeP”
Благодаря высокой частоте обновлений (последние данные получены 10 июня, 2026) канал поддерживает актуальность и высокий уровень охвата публикаций. Аналитика показывает, что аудитория активно взаимодействует с контентом, что делает его важной точкой влияния в категории Технологии и приложения.
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"айфон 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
👉@BookJavalogo.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
👉@BookJavaUsers и разбиваем её на несколько независимых баз данных (Шардов).
🔴Шард 1: Хранит пользователей с ID от 1 до 1,000,000.
🔴Шард 2: Хранит пользователей с ID от 1,000,001 до 2,000,000.
Каждый Шард - это отдельный сервер со своим процессором и диском.
Сложность: Теперь вашему приложению (или специальному роутеру) нужно понимать, в какую именно базу отправлять SQL-запрос. А сделать JOIN между таблицами, лежащими на разных серверах, становится практически невозможно.
📐 3. Теорема CAP (Закон распределенных систем)
Как только ваша база данных перестает жить на одном сервере и разъезжается на несколько (реплики или шарды), вступает в силу суровый закон физики - Теорема CAP.
Она гласит, что в распределенной системе вы можете выбрать только ДВА из ТРЕХ свойств:
1. C (Consistency / Консистентность): Все клиенты видят одни и те же данные в один и тот же момент времени. (Если я обновил аватарку на Мастере, следующий же запрос к любому Слейву должен вернуть новую аватарку).
2. A (Availability / Доступность): Система всегда отвечает на запрос, даже если часть серверов сгорела. Никаких ошибок 500.
3. P (Partition Tolerance / Устойчивость к разделению): Система продолжает работать, даже если между серверами БД пропала сеть (они перестали видеть друг друга).
Суровая реальность: В интернете сеть пропадает всегда. Поэтому свойство P мы обязаны брать по умолчанию. Остается выбор между CP и AP.
🔴Системы CP (Консистентные): Банковские приложения. Если сеть между Мастером и Репликой упала, база откажется отдавать вам баланс, потому что боится отдать устаревшие данные. Лучше выдать ошибку, чем соврать.
🔴Системы AP (Доступные): Соцсети (Instagram, YouTube). Если вы поставили лайк, а сеть внутри дата-центра моргнула, ваш друг может еще пару минут не видеть этот лайк (данные не консистентны). Но сайт при этом не "лежит", лента листается. Это называется Eventual Consistency (Консистентность в конечном счете).
🔥 Итог
🔴Используйте Репликацию, чтобы масштабировать чтение (Read-heavy).
🔴Используйте Шардирование, чтобы масштабировать запись и объем данных (Write-heavy).
🔴Помните про CAP-теорему: для соцсетей выбираем Доступность (AP), для финансов - Консистентность (CP).
📲 Мы в MAX
👉@BookJavaOutOfMemoryError. Бизнес теряет деньги. Что делать?
У вас есть два пути масштабирования (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
👉@BookJavadefault или static методов. Главное - только один абстрактный.
📝 Аннотация @FunctionalInterface
Ставить её над интерфейсом не обязательно, но хорошим тоном считается ставить.
Зачем? Она работает как защита от дурака: если вы или ваш коллега случайно добавите второй абстрактный метод в интерфейс, компилятор сразу выдаст ошибку, не дожидаясь падения кода в местах использования лямбд.
🧰 Шпаргалка: "Великолепная четверка"
В пакете java.util.function уже есть готовые интерфейсы на 99% случаев жизни. Не пишите свои велосипеды, пока не выучите эти:
1. Predicate <T>
💙Что делает: Проверяет условие.
💙 Метод: boolean test(T t)
💙 Где нужен: Фильтрация стримов (`filter`), проверки.
2. Consumer <T>
💙 Что делает: "Потребляет" объект, ничего не возвращая.
💙 Метод: void accept(T t)
💙 Где нужен: Вывод на экран, запись в БД, forEach.
3. Supplier <T>
💙 Что делает: "Поставляет" объект (из ниоткуда), ничего не принимая.
💙 Метод: T get()
💙 Где нужен: Ленивая инициализация, генерация значений, orElseGet.
4. Function <T, R>
💙 Что делает: Превращает объект типа T в объект типа R.
💙 Метод: R apply(T t)
💙 Где нужен: Преобразование данных, map в стримах.
💻 Пример в коде
@FunctionalInterface
interface Converter {
int stringToInt(String s);
}
public class Main {
public static void main(String[] args) {
// 1. Создаем реализацию через лямбду
Converter converter = str -> Integer.parseInt(str);
// 2. Использование стандартного Consumer
java.util.function.Consumer<Integer> print = x -> System.out.println("Result: " + x);
int result = converter.stringToInt("123");
print.accept(result); // Вывод: Result: 123
}
}
🔥 Итог
Функциональные интерфейсы - это контракт для лямбда-выражений. Используйте стандартные из java.util.function, чтобы ваш код был понятен другим разработчикам без лишних документаций.
#Java #Core #Lambda #FunctionalProgramming
📲 Мы в MAX
👉@BookJavajava.util.Optional. Таким образом вы сообщаете, что этот бин является необязательным, избегаете исключения, если он не существует, и можете аккуратно обработать его отсутствие с помощью Optional API.
📲 Мы в MAX
👉@BookJavaTrace ID (например, abc-123) и кладет его в HTTP-заголовки (обычно используется стандарт W3C traceparent или b3).
Когда Gateway вызывает OrderService, он передает эти заголовки дальше. OrderService читает их и понимает: "Ага, я часть большой трассы abc-123".
Вам не нужно писать этот код руками! В Spring Boot 3 за это отвечает библиотека Micrometer Tracing. Она автоматически перехватывает все вызовы через RestTemplate, WebClient, Feign и запросы к БД, вклеивая туда нужные ID.
🛠 Настройка (Spring Boot 3 + Zipkin)
Вам нужно добавить всего пару зависимостей в pom.xml:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-brave</artifactId>
</dependency>
В application.yaml указываем адрес сервера Zipkin:
management:
tracing:
sampling:
probability: 1.0 # Отправлять 100% запросов (на проде обычно ставят 0.1, чтобы не грузить сеть)
zipkin:
tracing:
endpoint: "http://localhost:9411/api/v2/spans"
🔭 Zipkin и Jaeger: UI для детективов
Ваши микросервисы в фоновом режиме отправляют данные о спанах (время старта и конца) в специальный сервер. Самые популярные решения это Zipkin (написан на Java, проще) или Jaeger (от Uber, написан на Go, мощнее).
Вы заходите в веб-интерфейс Jaeger, вбиваете Trace ID (который вы скопировали из логов в Kibana) и видите красивую цветную лесенку:
🟦 Gateway (Всего: 5.0s)
🟩 OrderService.create() (4.9s)
🟨 DB: INSERT order (0.05s)
🟧 PaymentService.pay() (4.8s) 👈 АГА! ВОТ КТО ТОРМОЗИТ!
🟥 External Bank API (4.75s)
За 5 секунд вы поняли, что проблема не в вашем коде и не в вашей базе данных, а в том, что API стороннего банка отвечает почти 5 секунд. Вы сэкономили часы дебага!
🔥 Итог: "Святая Троица" Observability
Теперь у вас есть полный набор инструментов Senior-разработчика:
1. Метрики (Prometheus/Grafana): Говорят ЕСТЬ ЛИ проблема. (У нас всплеск 500-х ошибок!).
2. Трассировка (Jaeger/Zipkin): Говорит ГДЕ проблема. (Ошибки летят из Payment Service при походе в банк).
3. Логи (ELK): Говорят В ЧЕМ проблема. (Смотрим логи Payment Service по Trace ID и видим: ConnectionTimeoutException).
#DevOps #Jaeger #Zipkin #Tracing #Microservices #SpringBoot
📲 Мы в MAX
👉@BookJava2023-10-25 INFO [main] UserService: User created
Это плохо. Компьютеру сложно понять, где тут дата, а где сообщение.
В микросервисах мы пишем логи в JSON:
{
"timestamp": "2023-10-25T10:00:00",
"level": "INFO",
"logger": "UserService",
"message": "User created",
"user_id": "123",
"trace_id": "abc-987"
}
Как сделать в Spring Boot?
Подключаем библиотеку logstash-logback-encoder и настраиваем logback-spring.xml. Теперь ваши логи это структурированные данные, по которым можно фильтровать!
🔍 2. Correlation ID (Trace ID) - Самое важное!
Представьте ситуацию:
User - Service A - Service B - Service C (Ошибка!).
Вы видите ошибку в логах Service C. Но кто её вызвал? Какой пользователь? С какого запроса всё началось? Без связующей нити вы потратите часы на расследование.
Решение: Micrometer Tracing (бывший Spring Cloud Sleuth).
Он автоматически добавляет Trace ID и Span ID в каждый лог.
• Trace ID: Одинаковый для всей цепочки запросов (от входа пользователя до базы данных).
• Теперь в Kibana вы просто вбиваете trace_id="abc-987" и видите все логи всех сервисов, которые участвовали в этом конкретном запросе.
📊 3. Kibana: Визуализация
Kibana — это не просто поиск. Это аналитика.
Вы можете построить дашборд:
• Круговая диаграмма: Распределение ошибок по типам (NPE, DatabaseTimeout).
• График: Количество логинов в минуту.
• Таблица: Топ-10 самых медленных SQL-запросов (если вы логируете время выполнения).
🛠 Pro-Tip: MDC (Mapped Diagnostic Context)
Хотите, чтобы в каждом логе автоматически писался ID текущего пользователя или IP-адрес, но не хотите передавать их в каждый метод?
Используйте MDC.
// В фильтре на входе запроса
MDC.put("userId", request.getHeader("X-User-ID"));
// Где-то глубоко в сервисе
log.info("Заказ создан");
// В JSON-логе автоматически появится поле "userId": "123"
// В конце
MDC.clear();
🔥 Итог
1. Приложение пишет логи в JSON в консоль.
2. Filebeat забирает их и кидает в Elasticsearch.
3. Разработчик открывает Kibana и ищет проблему за 5 секунд по Trace ID.
4. Никаких SSH и grep.
#DevOps #ELK #Logging #Kibana #Elasticsearch
📲 Мы в MAX
👉@BookJavapom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
В application.yaml:
management:
endpoints:
web:
exposure:
include: prometheus, health, info
Теперь, если вы перейдете по адресу /actuator/prometheus, вы увидите не JSON, а скучный текст:
# HELP jvm_memory_used_bytes The amount of used memory
# TYPE jvm_memory_used_bytes gauge
jvm_memory_used_bytes{area="heap",id="G1 Eden Space",} 2.5165824E7
http_server_requests_seconds_count{uri="/users",status="200",} 452.0
Это и есть пища для Прометея.
2️⃣ Prometheus: Пылесос данных
Prometheus это Time Series Database (База данных временных рядов). Она хранит цифры с привязкой ко времени.
Его киллер-фича: Pull Model (Модель вытягивания).
В отличие от логов, которые приложение само отправляет (Push), Prometheus сам приходит к вашему приложению раз в 15 секунд и скачивает (Scrape) данные со страницы /actuator/prometheus.
Почему Pull лучше Push?
Если ваше приложение под дикой нагрузкой и умирает, оно не сможет отправить метрики. Но Prometheus придет, увидит, что ответа нет, и зафиксирует: "Сервис упал".
3️⃣ Grafana: Капитанский мостик
Prometheus хранит данные, но смотреть на них в текстовом виде больно.
Grafana подключается к Prometheus и превращает скучные цифры в космолет.
Вы можете создать дашборды для всего:
🔴JVM: Сколько памяти съедено? Как часто работает Garbage Collector?
🔴Tomcat: Сколько потоков занято?
🔴Бизнес-метрики: Сколько заказов оформлено за час? Какая выручка?
Alerting (Оповещения):
Самое важное - Графана умеет "кричать".
Вы настраиваете правило: "Если количество ошибок 500 превышает 1% в течение 5 минут - отправь сообщение в Telegram/Slack команде дежурных".
🛠 Кастомные метрики
Spring дает кучу метрик из коробки (CPU, Memory, HTTP requests). Но бизнесу нужны свои цифры.
Создать их легко через MeterRegistry.
@Service
public class OrderService {
private final Counter orderCounter;
public OrderService(MeterRegistry registry) {
// Создаем счетчик "orders.created"
this.orderCounter = registry.counter("orders.created");
}
public void createOrder(Order order) {
repo.save(order);
orderCounter.increment(); // +1 к метрике
}
}
Теперь в Grafana вы увидите график "Заказов в секунду".
🔥 Итог
1. Actuator открывает "дверь" (/actuator/prometheus).
2. Prometheus заходит в эту дверь каждые 15 секунд и забирает цифры.
3. Grafana рисует графики на основе этих цифр и будит вас ночью, если всё сломалось.
#DevOps #Monitoring #Prometheus #Grafana #SpringBoot
📲 Мы в MAX
👉@BookJavaapp.jar.
• Редко: 1 Pod = Java App + Sidecar (например, агент логирования). Они живут вместе, как сиамские близнецы, и делят сеть.
👮♂️ 2. Deployment (Развертывание) - Начальник
Вы никогда не создаете Поды вручную. Потому что Поды смертны. Если Под умер - он умер.
Вместо этого вы создаете Deployment. Это инструкция для K8s:
"Я хочу, чтобы у меня ВСЕГДА было 3 копии моего приложения OrderService".Deployment создает ReplicaSet, который следит за численностью. • Если один Под упал K8s создает новый. • Если нагрузка выросла Вы меняете цифру 3 на 10, и K8s мгновенно создает еще 7 копий. 🚦 3. Service (Сервис) - Единая точка входа Поды рождаются и умирают. У них меняются IP-адреса. Как фронтенду узнать, на какой IP слать запрос, если они меняются каждую минуту? Тут выходит Service. Это стабильный сетевой адрес (и DNS-имя), который не меняется никогда. • Service работает как Load Balancer (Балансировщик). • Он принимает запрос на
http://order-service и пересылает его на один из живых Подов. Ему все равно, 3 их или 30.
📝 Как это выглядит в коде? (YAML)
В мире K8s мы не пишем команды, мы пишем Манифесты (YAML-файлы), описывающие Желаемое состояние.
# 1. Описываем Deployment (Что запускать?)
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-java-app
spec:
replicas: 3 # Хочу 3 экземпляра!
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: java-app
image: my-docker-hub/app:v1 # Берем этот образ
ports:
- containerPort: 8080
---
# 2. Описываем Service (Как достучаться?)
apiVersion: v1
kind: Service
metadata:
name: my-backend-service
spec:
selector:
app: backend # Ищи Поды с меткой 'backend'
ports:
- protocol: TCP
port: 80 # Внешний порт
targetPort: 8080 # Порт контейнера
Вы скармливаете этот файл командой kubectl apply -f app.yaml, и магия случается.
🔥 Итог
1. Pod: Обертка над контейнером.
2. Deployment: Следит, чтобы нужное количество Подов всегда работало.
3. Service: Стабильный адрес, распределяющий запросы по Подам.
#Kubernetes #K8s #DevOps #Docker #Java
📲 Мы в MAX
👉@BookJava
Уже доступно! Исследование Telegram 2025 — ключевые инсайты года 
