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


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

РКН clck.ru/3KoGeP
Download Telegram
📦 От Кода к Продакшену: JAR и Docker

В старые времена (Java EE) процесс деплоя был адом: нужно было установить на сервер Tomcat, настроить его, скомпилировать .war файл, закинуть его в папку... 🤯

Spring Boot принес концепцию Fat JAR (Жирный JAR).

🍔 1. Fat JAR - "Всё своё ношу с собой"

Spring Boot упаковывает ваше приложение, все библиотеки (зависимости) и даже сам веб-сервер (Tomcat) в один единственный файл .jar.

Этот файл работает как .exe в Windows. Ему ничего не нужно, кроме установленной Java.

Как собрать?
В терминале (в папке проекта):


# Для Maven
./mvnw clean package

# Для Gradle
./gradlew build



В папке target (или build/libs) появится файл myapp-0.0.1-SNAPSHOT.jar.

Как запустить?
Где угодно (на сервере, на ноутбуке друга), где есть Java:


java -jar myapp.0.0.1-SNAPSHOT.jar



Всё! Сервер стартует.



🐳 2. Docker - "Работает везде"

JAR это хорошо. Но что, если на сервере стоит Java 11, а у вас Java 17? Или другая ОС? Начинается проблема "На моем компьютере работало!".

Docker решает это, упаковывая ваше приложение вместе с Java и операционной системой в Контейнер.

Пишем Dockerfile
Создайте файл без расширения с именем Dockerfile в корне проекта.

Вариант для новичков (Простой):


# 1. Берем базовый образ с Java 17 (легковесный Alpine Linux)
FROM eclipse-temurin:17-jre-alpine

# 2. Копируем наш JAR внутрь образа
# (Предварительно нужно сделать mvn package руками!)
COPY target/*.jar app.jar

# 3. Говорим, какую команду запустить при старте контейнера
ENTRYPOINT ["java", "-jar", "/app.jar"]



Как запустить:


# 1. Собираем образ (Image)
docker build -t my-spring-app .

# 2. Запускаем контейнер
# -p 8080:8080 пробрасывает порт наружу
docker run -p 8080:8080 my-spring-app





🏗 3. Multi-stage Build (Уровень Pro)

В варианте выше вам нужно сначала собрать JAR руками. Это неудобно для CI/CD.
В профессиональном Dockerfile мы делаем сборку внутри Docker.


# --- Этап 1: Сборка (Build) ---
FROM maven:3.8.5-openjdk-17 AS builder
WORKDIR /app
COPY . .
# Собираем JAR, пропуская тесты (для скорости)
RUN mvn clean package -DskipTests

# --- Этап 2: Запуск (Run) ---
# Берем чистый, маленький образ для запуска
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
# Копируем ТОЛЬКО готовый jar из первого этапа
COPY --from=builder /app/target/*.jar app.jar

ENTRYPOINT ["java", "-jar", "app.jar"]



Почему это круто? В финальном образе нет исходного кода и тяжелого Maven. Только Java и ваш JAR. Образ весит минимум, а собрать его можно одной командой docker build, даже если на компьютере вообще не установлена Java!

🔥 Итог

1. Maven/Gradle собирают код в один Fat JAR.
2. Dockerfile описывает среду для запуска.
3. Multi-stage build позволяет собирать и запускать приложение в изолированной среде, не засоряя систему.

#SpringBoot #Docker #DevOps #Deployment #Java

📲 Мы в MAX

👉@BookJava
👍74👎1
🚀 CI/CD: Роботы делают рутину за вас

Аббревиатура состоит из двух частей, и они решают разные проблемы.

🛠 1. CI (Continuous Integration / Непрерывная интеграция)

Суть: Разработчики постоянно (несколько раз в день) сливают свой код в общую ветку (например, main или develop).
Каждый раз, когда вы делаете git push, специальный сервер (GitLab CI, GitHub Actions, Jenkins) автоматически:

1. Скачивает ваш свежий код.
2. Собирает проект (mvn clean compile).
3. Запускает все Unit и Integration тесты.

Если хоть один тест упал - сборка помечается красным крестиком (Build Failed). Код не пройдет дальше.
Итог: Ваша главная ветка в Git всегда находится в рабочем состоянии.

📦 2. CD (Continuous Delivery & Deployment)

Здесь две буквы "D", и они немного отличаются:

🔴Continuous Delivery (Доставка): Код автоматически собирается в готовый артефакт (например, Docker-образ) и кладется в хранилище. Нажать кнопку "Опубликовать на Production" должен человек (например, тимлид).

🔴Continuous Deployment (Развертывание): Полная автоматизация. Прошли тесты? Собрался образ? Он сразу же автоматически загружается на боевой сервер и заменяет старую версию. (Так делает Amazon, выкатывая обновления тысячи раз в день).

⚙️ Анатомия Пайплайна (Pipeline)

Пайплайн - это скрипт, состоящий из шагов (Stages), которые выполняются строго друг за другом. Упал предыдущий - следующий не запустится.

Типичный пайплайн для Spring Boot + Docker:

1. Lint (Проверка стиля кода, нет ли неиспользуемых импортов).
2. Test (Запуск JUnit тестов).
3. Build (Сборка `app.jar`).
4. Dockerize (Сборка Docker-образа и отправка его в Docker Registry).
5. Deploy (Команда серверу: "Скачай новый образ и перезапустись").

💻 Как это выглядит в коде? (GitHub Actions)

Вам не нужно кликать мышкой в интерфейсах. Пайплайн описывается кодом (YAML) и лежит прямо в вашем репозитории (подход Infrastructure as Code).

Вот пример простого .github/workflows/build.yml для Java-проекта:


name: Spring Boot CI/CD

on:
push:
branches: [ "main" ] # Запускать только при пуше в main

jobs:
build-and-test:
runs-on: ubuntu-latest # Выделяем виртуальную машину Linux

steps:
- uses: actions/checkout@v3 # 1. Скачиваем код из Git

- name: Установка Java 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'

- name: Сборка и Тесты (Maven) # 2. Запускаем тесты и сборку
run: ./mvnw clean package

# Дальше могут быть шаги для сборки Docker и деплоя...



Стоит вам сделать git push, и GitHub сам поднимет сервер, выполнит эти команды и пришлет вам письмо, если что-то сломалось.

🆚 Что выбрать?

🔴Jenkins: "Дед" в мире CI/CD. Мощный, гибкий, но сложный в настройке (нужно поднимать свой сервер). Написан на Java.

🔴GitLab CI: Стандарт индустрии корпоративного сектора. Очень удобен, так как встроен прямо в репозиторий кода.

🔴GitHub Actions: Современный, быстрый, идеален для Open Source и проектов, уже живущих в GitHub.

🔥 Итог

CI/CD убивает фактор "человеческой ошибки". Вы перестаете бояться релизов. Деплой новой фичи превращается из стрессового события в пятницу вечером в скучную рутину: сделал пуш подождал 5 минут фича на проде.

#DevOps #CICD #Java #SpringBoot #GitHubActions

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍71
📊 Мониторинг: Пульс вашего приложения

В мире мониторинга Java есть три главных игрока:

1. Spring Boot Actuator (Генерирует метрики).
2. Prometheus (Собирает и хранит их).
3. Grafana (Рисует красивые графики).

Давайте разберем, как они работают вместе.

1️⃣ Spring Boot Actuator & Micrometer

Сначала нужно научить приложение рассказывать о себе.
В Spring Boot это делается добавлением двух зависимостей: Actuator и Micrometer.

Micrometer это как SLF4J, только для метрик. Это фасад. Вы пишете код один раз, а Micrometer умеет отправлять эти данные хоть в Prometheus, хоть в Datadog, хоть в New Relic.

В pom.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

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥64
🕸️ Распределенная Трассировка: Ищем "бутылочное горлышко" (Zipkin & Jaeger)

Если логи это текст, а метрики это графики, то трассировка это диаграмма Ганта (каскад) для каждого отдельного HTTP-запроса.

🧩 Главные понятия: Trace и Span

Вся магия строится на двух терминах:

1. Trace (След/Трасса): Это весь путь запроса от клика пользователя в браузере до самого глубокого ответа от базы данных. У него есть единый Trace ID.

2. Span (Пролет/Отрезок): Это один конкретный шаг внутри Трассы. Например, "поход в базу данных" - это один Span. "HTTP-запрос в сервис оплаты" - это другой Span. У каждого спана есть свой Span ID и информация о том, сколько миллисекунд он выполнялся.

🕵️‍♂️ Как сервисы передают ID друг другу?

Когда Gateway принимает запрос, он генерирует Trace 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

👉@BookJava
🔥51👍1