CI/CD
Gradle легко интегрируется с CI/CD системами, такими как Jenkins, GitLab CI и GitHub Actions, обеспечивая автоматизацию сборки, тестирования и публикации.
Gradle в Jenkins
Настройка:
Установите Gradle Plugin в Jenkins.
Создайте задачу с Gradle Wrapper:
Настройте gradle.properties для CI:
GitLab CI
Пример
GitHub Actions
Пример
Нюансы:
Используйте --no-daemon в CI для экономии памяти.
Включите Build Cache для ускорения:
Публикуйте Build Scans для анализа CI-сборок.
Gradle Daemon и производительность
Gradle Daemon — это фоновый процесс, который сохраняет JVM между сборками для ускорения.
Включение:
По умолчанию включен.
Отключение:
Производительность:
Ускоряет повторные сборки, избегая инициализации JVM.
Поддерживает --parallel для параллельного выполнения задач.
Нюансы:
Используйте --no-daemon в CI/CD, чтобы избежать утечек памяти.
Остановите Daemon:
Настройте память в gradle.properties:
Build Scan: анализ, оптимизация, диагностика
Build Scans — это веб-отчеты, предоставляющие детальную информацию о сборке.
Настройка:
Генерация:
Использование:
Анализ времени выполнения задач.
Выявление узких мест (медленные задачи, конфликты зависимостей).
Диагностика ошибок через логи и зависимости.
Нюансы:
Полезен для оптимизации CI/CD и крупных проектов.
Храните ссылки на Build Scans для командной работы.
#Java #middle #Gradle #Task #integration
Gradle легко интегрируется с CI/CD системами, такими как Jenkins, GitLab CI и GitHub Actions, обеспечивая автоматизацию сборки, тестирования и публикации.
Gradle в Jenkins
Настройка:
Установите Gradle Plugin в Jenkins.
Создайте задачу с Gradle Wrapper:
./gradlew clean build --no-daemon
Настройте gradle.properties для CI:
org.gradle.jvmargs=-Xmx2048m
org.gradle.caching=true
В памяти: Используйте --no-daemon в CI, чтобы избежать постоянного процесса Gradle Daemon, экономя память (200-300 МБ).
GitLab CI
Пример
.gitlab-ci.yml:
stages:
- build
build:
stage: build
image: gradle:8.1-jdk11
script:
- ./gradlew clean build --no-daemon
cache:
paths:
- ~/.gradle/caches/
- ~/.gradle/wrapper/
В памяти: Кэширование ~/.gradle/caches между сборками снижает сетевые запросы, но требует дискового пространства.
GitHub Actions
Пример
.github/workflows/build.yml:
name: Build
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: gradle/gradle-build-action@v2
with:
gradle-version: 8.1
- run: ./gradlew clean build --no-daemon
В памяти: GitHub Actions кэширует зависимости через gradle-build-action, минимизируя overhead.
Нюансы:
Используйте --no-daemon в CI для экономии памяти.
Включите Build Cache для ускорения:
buildCache {
local { enabled = true }
}
Публикуйте Build Scans для анализа CI-сборок.
Gradle Daemon и производительность
Gradle Daemon — это фоновый процесс, который сохраняет JVM между сборками для ускорения.
Включение:
По умолчанию включен.
Отключение:
./gradlew build --no-daemon.
Производительность:
Ускоряет повторные сборки, избегая инициализации JVM.
Поддерживает --parallel для параллельного выполнения задач.
В памяти: Daemon потребляет 200-300 МБ памяти в простое. Для крупных проектов может достигать 1-2 ГБ при активной сборке.
Нюансы:
Используйте --no-daemon в CI/CD, чтобы избежать утечек памяти.
Остановите Daemon:
./gradlew --stop.
Настройте память в gradle.properties:
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
Build Scan: анализ, оптимизация, диагностика
Build Scans — это веб-отчеты, предоставляющие детальную информацию о сборке.
Настройка:
plugins {
id 'com.gradle.build-scan' version '3.17.4'
}
buildScan {
termsOfServiceUrl = 'https://gradle.com/terms-of-service'
termsOfServiceAgree = 'yes'
}
Генерация:
./gradlew build --scan
Использование:
Анализ времени выполнения задач.
Выявление узких мест (медленные задачи, конфликты зависимостей).
Диагностика ошибок через логи и зависимости.
В памяти: Build Scan загружает метаданные сборки (граф задач, зависимости, время выполнения) в память, добавляя 50-100 МБ overhead. Данные отправляются на сервер Gradle Enterprise, требуя сетевых операций.
Нюансы:
Полезен для оптимизации CI/CD и крупных проектов.
Храните ссылки на Build Scans для командной работы.
#Java #middle #Gradle #Task #integration
👍4
Введение в Nginx
Nginx (произносится как "engine x") — это высокопроизводительное программное обеспечение с открытым исходным кодом, выполняющее функции веб-сервера, обратного прокси-сервера, балансировщика нагрузки, TCP/UDP-прокси и почтового прокси-сервера. Созданное Игорем Сысоевым в 2004 году, оно распространяется под лицензией BSD из 2 пунктов. Nginx завоевал популярность благодаря своей скорости, стабильности и низкому потреблению ресурсов, что делает его выбором для многих высоконагруженных сайтов, таких как Netflix, Dropbox, Яндекс и ВКонтакте.
Согласно данным W3Techs (по состоянию на апрель 2025 года), Nginx занимает первое место среди веб-серверов, обслуживая 33,8% всех веб-сайтов, опережая Apache (26,4%) и Cloudflare Server (23,4%). Это подчеркивает его широкое признание и надежность.
Как работает Nginx?
Nginx использует асинхронную событийно-ориентированную архитектуру, которая позволяет обрабатывать тысячи одновременных соединений с минимальным использованием ресурсов.
Основные аспекты его работы включают:
Один основной процесс и несколько рабочих процессов: Основной процесс управляет конфигурацией и координирует работу, а рабочие процессы обрабатывают запросы пользователей. Это снижает накладные расходы по сравнению с многопоточной моделью, используемой, например, в Apache.
Механизмы событий: Nginx поддерживает такие технологии, как kqueue (FreeBSD), epoll (Linux) и другие, для эффективной обработки сетевых соединений.
Оптимизация передачи данных: Использование технологий, таких как sendfile и асинхронный ввод/вывод (AIO), минимизирует копирование данных и ускоряет доставку контента.
Низкое потребление памяти: Например, для 10 000 неактивных HTTP keep-alive соединений требуется всего около 2,5 МБ памяти.
Запросы пользователей разбиваются на небольшие сетевые соединения, которые обрабатываются асинхронно. После обработки они собираются в единый ответ и отправляются клиенту. Одно соединение может обрабатывать до 1024 запросов, что значительно повышает производительность.
Для чего нужен Nginx?
Nginx универсален и применяется в различных сценариях:
Веб-сервер
Обслуживает статический контент (HTML, CSS, изображения, JavaScript) с высокой скоростью.
Обратный прокси
Перенаправляет запросы к другим серверам, скрывая их от клиента.
Балансировка нагрузки
Распределяет входящий трафик между несколькими серверами для повышения отказоустойчивости.
Кеширование
Сохраняет часто запрашиваемый контент для ускорения доставки.
Почтовый прокси
Поддерживает протоколы IMAP, POP3, SMTP с возможностью аутентификации через HTTP.
Безопасность
Поддерживает SSL/TLS, ограничение доступа по IP и защиту от DDoS-атак.
Nginx особенно эффективен для высоконагруженных веб-приложений, где требуется быстрая доставка контента и стабильность при большом количестве запросов.
Почему выбрать Nginx?
Nginx выделяется среди других веб-серверов, таких как Apache, по нескольким причинам:
Высокая производительность: Асинхронная архитектура позволяет обрабатывать больше запросов с меньшими ресурсами.
Эффективность для статического контента: Nginx быстрее Apache в доставке статических файлов, таких как изображения и CSS.
Модульная архитектура: Легко расширяется с помощью модулей для добавления новых функций.
Низкое потребление ресурсов: Минимизирует использование памяти и процессора, что идеально для серверов с ограниченными ресурсами.
Широкое применение: Используется крупными компаниями, такими как Netflix, Dropbox и WordPress.com, что подтверждает его надежность.
Nginx также может работать в связке с Apache: Nginx обрабатывает статический контент, а Apache — динамический, что оптимизирует производительность сайта.
#Java #middle #on_request #nginx
Nginx (произносится как "engine x") — это высокопроизводительное программное обеспечение с открытым исходным кодом, выполняющее функции веб-сервера, обратного прокси-сервера, балансировщика нагрузки, TCP/UDP-прокси и почтового прокси-сервера. Созданное Игорем Сысоевым в 2004 году, оно распространяется под лицензией BSD из 2 пунктов. Nginx завоевал популярность благодаря своей скорости, стабильности и низкому потреблению ресурсов, что делает его выбором для многих высоконагруженных сайтов, таких как Netflix, Dropbox, Яндекс и ВКонтакте.
Согласно данным W3Techs (по состоянию на апрель 2025 года), Nginx занимает первое место среди веб-серверов, обслуживая 33,8% всех веб-сайтов, опережая Apache (26,4%) и Cloudflare Server (23,4%). Это подчеркивает его широкое признание и надежность.
Как работает Nginx?
Nginx использует асинхронную событийно-ориентированную архитектуру, которая позволяет обрабатывать тысячи одновременных соединений с минимальным использованием ресурсов.
Основные аспекты его работы включают:
Один основной процесс и несколько рабочих процессов: Основной процесс управляет конфигурацией и координирует работу, а рабочие процессы обрабатывают запросы пользователей. Это снижает накладные расходы по сравнению с многопоточной моделью, используемой, например, в Apache.
Механизмы событий: Nginx поддерживает такие технологии, как kqueue (FreeBSD), epoll (Linux) и другие, для эффективной обработки сетевых соединений.
Оптимизация передачи данных: Использование технологий, таких как sendfile и асинхронный ввод/вывод (AIO), минимизирует копирование данных и ускоряет доставку контента.
Низкое потребление памяти: Например, для 10 000 неактивных HTTP keep-alive соединений требуется всего около 2,5 МБ памяти.
Запросы пользователей разбиваются на небольшие сетевые соединения, которые обрабатываются асинхронно. После обработки они собираются в единый ответ и отправляются клиенту. Одно соединение может обрабатывать до 1024 запросов, что значительно повышает производительность.
Для чего нужен Nginx?
Nginx универсален и применяется в различных сценариях:
Веб-сервер
Обслуживает статический контент (HTML, CSS, изображения, JavaScript) с высокой скоростью.
Обратный прокси
Перенаправляет запросы к другим серверам, скрывая их от клиента.
Балансировка нагрузки
Распределяет входящий трафик между несколькими серверами для повышения отказоустойчивости.
Кеширование
Сохраняет часто запрашиваемый контент для ускорения доставки.
Почтовый прокси
Поддерживает протоколы IMAP, POP3, SMTP с возможностью аутентификации через HTTP.
Безопасность
Поддерживает SSL/TLS, ограничение доступа по IP и защиту от DDoS-атак.
Nginx особенно эффективен для высоконагруженных веб-приложений, где требуется быстрая доставка контента и стабильность при большом количестве запросов.
Почему выбрать Nginx?
Nginx выделяется среди других веб-серверов, таких как Apache, по нескольким причинам:
Высокая производительность: Асинхронная архитектура позволяет обрабатывать больше запросов с меньшими ресурсами.
Эффективность для статического контента: Nginx быстрее Apache в доставке статических файлов, таких как изображения и CSS.
Модульная архитектура: Легко расширяется с помощью модулей для добавления новых функций.
Низкое потребление ресурсов: Минимизирует использование памяти и процессора, что идеально для серверов с ограниченными ресурсами.
Широкое применение: Используется крупными компаниями, такими как Netflix, Dropbox и WordPress.com, что подтверждает его надежность.
Nginx также может работать в связке с Apache: Nginx обрабатывает статический контент, а Apache — динамический, что оптимизирует производительность сайта.
#Java #middle #on_request #nginx
👍6🔥3
Простая установка Nginx на Ubuntu
Установка Nginx на Ubuntu проста и занимает всего несколько минут.
Обновите списки пакетов:
Установите Nginx:
Запустите Nginx:
Включите автозапуск Nginx:
Проверьте статус Nginx:
Для настройки брандмауэра (если используется ufw) разрешите HTTP-трафик:
Демонстрация работы Nginx
После выполнения вышеуказанных шагов откройте веб-браузер и введите IP-адрес вашего сервера (например, http://your_server_ip). Вы увидите стандартную страницу приветствия Nginx.
Эта страница подтверждает, что Nginx установлен и функционирует корректно. Если страница не отображается, проверьте статус сервера и настройки брандмауэра.
#Java #middle #on_request #nginx
Установка Nginx на Ubuntu проста и занимает всего несколько минут.
Обновите списки пакетов:
sudo apt update
Эта команда обновляет индекс пакетов для системы управления пакетами apt.
Установите Nginx:
sudo apt install nginx
Подтвердите установку, нажав Y и Enter, когда система запросит разрешение.
Запустите Nginx:
sudo systemctl start nginx
Эта команда запускает веб-сервер.
Включите автозапуск Nginx:
sudo systemctl enable nginx
Это гарантирует, что Nginx будет запускаться автоматически при перезагрузке системы.
Проверьте статус Nginx:
sudo systemctl status nginx
Если в выводе указано active (running), сервер работает корректно.
Для настройки брандмауэра (если используется ufw) разрешите HTTP-трафик:
sudo ufw allow 'Nginx HTTP'
sudo ufw status
Демонстрация работы Nginx
После выполнения вышеуказанных шагов откройте веб-браузер и введите IP-адрес вашего сервера (например, http://your_server_ip). Вы увидите стандартную страницу приветствия Nginx.
Эта страница подтверждает, что Nginx установлен и функционирует корректно. Если страница не отображается, проверьте статус сервера и настройки брандмауэра.
#Java #middle #on_request #nginx
👍5🔥1
Раздел 4: Управляющие конструкции
Глава 2: Циклы
while / do-while в Java
Циклы в Java позволяют выполнять блок кода несколько раз, что полезно для повторяющихся задач, таких как обработка данных или ожидание ввода пользователя. В этом уроке мы разберем два типа циклов: while и do-while. Они используются, когда количество итераций неизвестно заранее и зависит от условия.
1. Цикл while
1.1. Синтаксис
Цикл while проверяет условие перед каждой итерацией. Если условие истинно (true), код внутри цикла выполняется. Если ложно (false), выполнение переходит к следующей строке после цикла.
1.2. Как работает
Проверяется условие.
Если условие истинно, выполняется блок кода.
После выполнения блока кода условие проверяется снова.
Если условие ложно, цикл завершается, и выполнение продолжается после цикла.
1.3. Примеры
Простой счетчик
Суммирование чисел до ввода 0
Цикл с несколькими условиями
Бесконечный цикл
1.4. Особенности
Проверка условия: Условие проверяется перед выполнением блока кода, поэтому цикл может не выполниться ни разу, если условие изначально ложно.
Обновление переменных: Необходимо обновлять переменные внутри цикла, чтобы условие в конечном итоге стало ложным.
Использование: Подходит для задач, где количество итераций неизвестно, например, чтение данных до конца файла или ожидание ввода пользователя.
2. Цикл do-while
2.1. Синтаксис
Цикл do-while выполняет блок кода хотя бы один раз, а затем проверяет условие. Если условие истинно, цикл продолжается.
2.2. Как работает
Выполняется блок кода.
Проверяется условие.
Если условие истинно, выполнение возвращается к блоку кода.
Если условие ложно, цикл завершается.
#Java #для_новичков #beginner #while #do_while
Глава 2: Циклы
while / do-while в Java
Циклы в Java позволяют выполнять блок кода несколько раз, что полезно для повторяющихся задач, таких как обработка данных или ожидание ввода пользователя. В этом уроке мы разберем два типа циклов: while и do-while. Они используются, когда количество итераций неизвестно заранее и зависит от условия.
1. Цикл while
1.1. Синтаксис
Цикл while проверяет условие перед каждой итерацией. Если условие истинно (true), код внутри цикла выполняется. Если ложно (false), выполнение переходит к следующей строке после цикла.
while (условие) {
// Код, который выполняется, если условие истинно
}
Условие: Выражение, возвращающее boolean (true или false).
Блок кода: Выполняется, пока условие истинно.
1.2. Как работает
Проверяется условие.
Если условие истинно, выполняется блок кода.
После выполнения блока кода условие проверяется снова.
Если условие ложно, цикл завершается, и выполнение продолжается после цикла.
1.3. Примеры
Простой счетчик
int i = 1;
while (i <= 5) {
System.out.println("Число: " + i);
i++;
}
Вывод:
Число: 1
Число: 2
Число: 3
Число: 4
Число: 5
Объяснение: Цикл начинается с i = 1. Пока i <= 5, печатается значение i, и i увеличивается на 1. Когда i становится 6, условие становится ложным, и цикл завершается.
Суммирование чисел до ввода 0
import java.util.Scanner;
Scanner scanner = new Scanner(System.in);
int sum = 0;
int number;
System.out.println("Введите числа для суммирования (0 для завершения):");
number = scanner.nextInt();
while (number != 0) {
sum += number;
number = scanner.nextInt();
}
System.out.println("Сумма: " + sum);
Объяснение: Пользователь вводит числа, которые добавляются к sum, пока не введет 0. Цикл while проверяет number != 0 перед добавлением.
Цикл с несколькими условиями
int x = 10;
int limit = 20;
while (x > 0 && x < limit) {
System.out.println("x = " + x);
x--;
}
Вывод:
x = 10
x = 9
x = 8
...
x = 1
Объяснение: Цикл выполняется, пока выполняются оба условия: x > 0 и x < limit. Числа печатаются от 10 до 1.
Бесконечный цикл
int i = 0;
while (true) {
System.out.println("Итерация: " + i);
i++;
if (i >= 3) {
break; // Выход из цикла
}
}
Вывод:
Итерация: 0
Итерация: 1
Итерация: 2
Объяснение: Условие true делает цикл бесконечным, но break прерывает его, когда i достигает 3.
1.4. Особенности
Проверка условия: Условие проверяется перед выполнением блока кода, поэтому цикл может не выполниться ни разу, если условие изначально ложно.
Обновление переменных: Необходимо обновлять переменные внутри цикла, чтобы условие в конечном итоге стало ложным.
Использование: Подходит для задач, где количество итераций неизвестно, например, чтение данных до конца файла или ожидание ввода пользователя.
2. Цикл do-while
2.1. Синтаксис
Цикл do-while выполняет блок кода хотя бы один раз, а затем проверяет условие. Если условие истинно, цикл продолжается.
do {
// Код, который выполняется хотя бы один раз
} while (условие);
Условие: Выражение, возвращающее boolean.
Блок кода: Выполняется перед проверкой условия.
2.2. Как работает
Выполняется блок кода.
Проверяется условие.
Если условие истинно, выполнение возвращается к блоку кода.
Если условие ложно, цикл завершается.
#Java #для_новичков #beginner #while #do_while
👍4
2.3. Примеры
Простой счетчик
Выполнение при ложном условии
Меню с вводом пользователя
2.4. Особенности
Гарантированное выполнение: Блок кода выполняется хотя бы один раз, даже если условие ложно.
Использование: Подходит для задач, где нужно выполнить действие хотя бы раз, например, отображение меню или запрос ввода.
3. Правильное применение
3.1. Лучшие практики
Используйте фигурные скобки {}:
Обновляйте переменные:
Убедитесь, что переменные в условии изменяются, чтобы избежать бесконечных циклов.
Проверяйте на null:
Используйте понятные имена:
Например, counter вместо i делает код понятнее.
Избегайте бесконечных циклов:
3.2. Распространенные ошибки
Неправильный выбор цикла:
Использование do-while, когда while лучше, или наоборот.
Сложные условия:
4. Работа под капотом
4.1. Компиляция в байт-код
Цикл while:
Компилируется в инструкции if и goto. Условие проверяется перед выполнением, и если оно истинно, JVM переходит к блоку кода.
Пример байт-кода (упрощенно):
Цикл do-while:
Блок кода выполняется сначала, затем проверяется условие с помощью if и goto.
Пример байт-кода:
4.2. Память и стек
Стек операндов: Условие цикла вычисляется в стеке операндов JVM.
Стек вызовов: Локальные переменные цикла (например, i) хранятся в стеке вызовов.
Куча: Если в цикле создаются объекты (например, new String()), они хранятся в куче.
4.3. Оптимизация в JVM
JIT-компиляция: JVM может оптимизировать циклы, встраивая их в машинный код для повышения производительности.
Короткое замыкание: Если условие содержит логические операторы (&&, ||), JVM пропускает ненужные вычисления.
Удаление пустых циклов: Если цикл не выполняет полезной работы, JIT-компилятор может его убрать.
4.4. Ошибки в памяти
Бесконечные циклы: Могут переполнить стек или кучу, если создаются объекты.
NullPointerException: Работа с объектами без проверки на null в условии.
#Java #для_новичков #beginner #while #do_while
Простой счетчик
int i = 1;
do {
System.out.println("Число: " + i);
i++;
} while (i <= 5);
Вывод:
Число: 1
Число: 2
Число: 3
Число: 4
Число: 5
Объяснение: Блок кода выполняется, затем проверяется i <= 5. Цикл продолжается, пока условие истинно.
Выполнение при ложном условии
int i = 6;
do {
System.out.println("Это выполнится один раз");
} while (i <= 5);
Вывод: Это выполнится один раз
Объяснение: Блок кода выполняется один раз, даже если условие i <= 5 изначально ложно.
Меню с вводом пользователя
import java.util.Scanner;
Scanner scanner = new Scanner(System.in);
String input;
do {
System.out.print("Введите команду (или 'quit' для выхода): ");
input = scanner.nextLine();
System.out.println("Вы ввели: " + input);
} while (!input.equalsIgnoreCase("quit"));
Объяснение: Пользователь вводит команды, пока не введет "quit". Цикл гарантирует, что запрос появится хотя бы один раз.
2.4. Особенности
Гарантированное выполнение: Блок кода выполняется хотя бы один раз, даже если условие ложно.
Использование: Подходит для задач, где нужно выполнить действие хотя бы раз, например, отображение меню или запрос ввода.
3. Правильное применение
3.1. Лучшие практики
Используйте фигурные скобки {}:
Даже для одной строки, чтобы избежать ошибок и улучшить читаемость.// Плохо: без скобок
while (i < 5)
System.out.println(i++);
// Хорошо: со скобками
while (i < 5) {
System.out.println(i++);
}
Обновляйте переменные:
Убедитесь, что переменные в условии изменяются, чтобы избежать бесконечных циклов.
Проверяйте на null:
Если работаете с объектами, проверяйте их на null, чтобы избежать NullPointerException.String input = null;
while (input != null && !input.isEmpty()) {
// Обработка ввода
}
Используйте понятные имена:
Например, counter вместо i делает код понятнее.
Избегайте бесконечных циклов:
Если используете while (true), добавьте break для выхода.while (true) {
if (условие) break;
}
3.2. Распространенные ошибки
Забыть обновить переменную:int i = 1;
while (i <= 5) {
System.out.println(i); // Бесконечный цикл, так как i не увеличивается
}
Неправильный выбор цикла:
Использование do-while, когда while лучше, или наоборот.
Сложные условия:
Слишком сложные условия затрудняют чтение. Разбивайте их на переменные.
// Плохо
while (x > 0 && y < 10 && z != null && z.isValid()) {}
// Хорошо
boolean isValid = x > 0 && y < 10 && z != null && z.isValid();
while (isValid) {}
4. Работа под капотом
4.1. Компиляция в байт-код
Цикл while:
Компилируется в инструкции if и goto. Условие проверяется перед выполнением, и если оно истинно, JVM переходит к блоку кода.
Пример байт-кода (упрощенно):
while (i < 5) {
i++;
}
Байт-код:iload i
bipush 5
if_icmpge end
iinc i, 1
goto loop
end:
Цикл do-while:
Блок кода выполняется сначала, затем проверяется условие с помощью if и goto.
Пример байт-кода:
do {
i++;
} while (i < 5);
Байт-код:loop:
iinc i, 1
iload i
bipush 5
if_icmplt loop
4.2. Память и стек
Стек операндов: Условие цикла вычисляется в стеке операндов JVM.
Стек вызовов: Локальные переменные цикла (например, i) хранятся в стеке вызовов.
Куча: Если в цикле создаются объекты (например, new String()), они хранятся в куче.
4.3. Оптимизация в JVM
JIT-компиляция: JVM может оптимизировать циклы, встраивая их в машинный код для повышения производительности.
Короткое замыкание: Если условие содержит логические операторы (&&, ||), JVM пропускает ненужные вычисления.
Удаление пустых циклов: Если цикл не выполняет полезной работы, JIT-компилятор может его убрать.
4.4. Ошибки в памяти
Бесконечные циклы: Могут переполнить стек или кучу, если создаются объекты.
NullPointerException: Работа с объектами без проверки на null в условии.
String s = null;
while (s.length() > 0) { // Ошибка: NullPointerException
}
#Java #для_новичков #beginner #while #do_while
👍3
Apache Kafka.
Введение и архитектура
Apache Kafka представляет собой распределенную платформу для обработки потоков данных в реальном времени, которая сочетает в себе функции очереди сообщений, хранилища данных и системы обработки событий. Разработанная изначально в LinkedIn для решения задач высоконагруженных систем, Kafka эволюционировала в мощный инструмент для построения масштабируемых конвейеров данных.
Основные концепции: topic, partition, offset, segment, log, leader/follower, ISR
Kafka строится вокруг понятия Topic — логическая категория для потоков сообщений.
Topic — это не монолитная структура, а распределенная очередь, разделенная на партиции (partitions). Каждая партиция представляет собой упорядоченную, неизменяемую последовательность записей (records), которая хранится как append-only лог. Это значит, что данные в партиции добавляются только в конец, без возможности модификации существующих записей. Партиции позволяют параллелизовать обработку: разные партиции могут обрабатываться независимо, что обеспечивает масштабируемость.
Внутри партиции каждая запись идентифицируется offset'ом — это монотонно возрастающее целое число, начиная с 0, которое указывает позицию записи в логе. Offset уникален только в пределах партиции; для разных партиций offset'ы независимы. Когда потребитель (consumer) читает данные, он отслеживает текущий offset, чтобы знать, с какой позиции продолжить чтение. В памяти потребителя offset хранится локально, но для надежности Kafka предоставляет механизм коммита offset'ов в специальную внутреннюю тему
Партиция физически хранится как лог (log) — последовательность файлов на диске брокера. Лог разбивается на сегменты (segments) для управления размером: каждый сегмент — это файл с записями, начиная с определенного offset'а (base offset). Когда сегмент достигает заданного размера (по умолчанию 1 ГБ, создается новый. Старые сегменты могут удаляться по политикам retention. В памяти брокера сегменты не загружаются целиком; вместо этого Kafka использует memory-mapped files (mmap) для доступа к диску, что позволяет ОС кэшировать горячие данные в page cache, минимизируя реальные I/O-операции.
Для репликации партиции имеют лидера (leader) и фолловеров (followers). Лидер — это реплика партиции на одном брокере, которая принимает все записи от продюсеров (producers) и обслуживает чтение от потребителей. Фолловеры — реплики на других брокерах, которые синхронизируют данные с лидером. ISR (In-Sync Replicas) — это подмножество реплик (включая лидера), которые полностью синхронизированы с лидером. ISR определяется по отставанию фолловеров: если фолловер не запрашивает данные в течение
В памяти брокера для каждой партиции лидер хранит в RAM метаданные, такие как текущий high-watermark (максимальный offset, закоммиченный на всех ISR), а также буферы для входящих запросов. Фолловеры используют отдельные потоки (replica fetchers) для pull-запросов к лидеру, копируя данные в свои логи.
Архитектура брокера: роль брокера, контроллера, брокерная конфигурация
Брокер (broker) — это основной узел (сервер) Kafka-кластера, отвечающий за хранение и обслуживание данных. Каждый брокер управляет подмножеством партиций: для каждой партиции один брокер является лидером, а другие — фолловерами. Брокеры образуют кластер, координируемый через ZooKeeper (до Kafka 2.8) или встроенный KRaft (Kafka Raft) в новых версиях, который устраняет зависимость от ZooKeeper.
#Java #middle #Kafka
Введение и архитектура
Apache Kafka представляет собой распределенную платформу для обработки потоков данных в реальном времени, которая сочетает в себе функции очереди сообщений, хранилища данных и системы обработки событий. Разработанная изначально в LinkedIn для решения задач высоконагруженных систем, Kafka эволюционировала в мощный инструмент для построения масштабируемых конвейеров данных.
Основные концепции: topic, partition, offset, segment, log, leader/follower, ISR
Kafka строится вокруг понятия Topic — логическая категория для потоков сообщений.
Topic — это не монолитная структура, а распределенная очередь, разделенная на партиции (partitions). Каждая партиция представляет собой упорядоченную, неизменяемую последовательность записей (records), которая хранится как append-only лог. Это значит, что данные в партиции добавляются только в конец, без возможности модификации существующих записей. Партиции позволяют параллелизовать обработку: разные партиции могут обрабатываться независимо, что обеспечивает масштабируемость.
Внутри партиции каждая запись идентифицируется offset'ом — это монотонно возрастающее целое число, начиная с 0, которое указывает позицию записи в логе. Offset уникален только в пределах партиции; для разных партиций offset'ы независимы. Когда потребитель (consumer) читает данные, он отслеживает текущий offset, чтобы знать, с какой позиции продолжить чтение. В памяти потребителя offset хранится локально, но для надежности Kafka предоставляет механизм коммита offset'ов в специальную внутреннюю тему
__consumer_offsets
, где они реплицируются как обычные записи.Партиция физически хранится как лог (log) — последовательность файлов на диске брокера. Лог разбивается на сегменты (segments) для управления размером: каждый сегмент — это файл с записями, начиная с определенного offset'а (base offset). Когда сегмент достигает заданного размера (по умолчанию 1 ГБ, создается новый. Старые сегменты могут удаляться по политикам retention. В памяти брокера сегменты не загружаются целиком; вместо этого Kafka использует memory-mapped files (mmap) для доступа к диску, что позволяет ОС кэшировать горячие данные в page cache, минимизируя реальные I/O-операции.
Для репликации партиции имеют лидера (leader) и фолловеров (followers). Лидер — это реплика партиции на одном брокере, которая принимает все записи от продюсеров (producers) и обслуживает чтение от потребителей. Фолловеры — реплики на других брокерах, которые синхронизируют данные с лидером. ISR (In-Sync Replicas) — это подмножество реплик (включая лидера), которые полностью синхронизированы с лидером. ISR определяется по отставанию фолловеров: если фолловер не запрашивает данные в течение
replica.lag.time.max.ms
(по умолчанию 30 секунд), он исключается из ISR. Это обеспечивает баланс между доступностью и consistency: записи считаются закоммиченными, когда они реплицированы на все реплики в ISR (min.insync.replicas
).В памяти брокера для каждой партиции лидер хранит в RAM метаданные, такие как текущий high-watermark (максимальный offset, закоммиченный на всех ISR), а также буферы для входящих запросов. Фолловеры используют отдельные потоки (replica fetchers) для pull-запросов к лидеру, копируя данные в свои логи.
Архитектура брокера: роль брокера, контроллера, брокерная конфигурация
Брокер (broker) — это основной узел (сервер) Kafka-кластера, отвечающий за хранение и обслуживание данных. Каждый брокер управляет подмножеством партиций: для каждой партиции один брокер является лидером, а другие — фолловерами. Брокеры образуют кластер, координируемый через ZooKeeper (до Kafka 2.8) или встроенный KRaft (Kafka Raft) в новых версиях, который устраняет зависимость от ZooKeeper.
#Java #middle #Kafka
👍6