Совет по продвинутому использованию Spring
Используйте Spring SSEEvent для плавных реальных обновлений в ваших приложениях.
👉 Java Portal
Используйте Spring SSEEvent для плавных реальных обновлений в ваших приложениях.
@GetMapping("/events")
public Flux<ServerSentEvent<String>> events() {
return Flux.interval(Duration.ofSeconds(1)) // каждую секунду создаётся новое событие
.map(sequence -> ServerSentEvent.<String>builder()
.id(String.valueOf(sequence)) // задаём ID события
.event("message") // тип события (можно использовать для фильтрации на клиенте)
.data("Event #" + sequence + " @ " + LocalTime.now()) // данные события
.build());
}Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍2
Вся линейка JDK уже доступна! Теперь можно использовать все основные сборки Java 25, включая IBM Semeru на движке OpenJ9 🙌
Читай в их блоге, чтобы узнать, как установить свежий JDK в свою IDE.
👉 Java Portal
Читай в их блоге, чтобы узнать, как установить свежий JDK в свою IDE.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8
Spring Boot tip:
Используй CommandLineRunner, если нужно выполнить код сразу после того, как приложение полностью поднялось и контекст инициализирован.
CommandLineRunner — это интерфейс Spring Boot, который позволяет запускать любую логику при старте приложения.
Удобно для:
заполнения базы начальными данными,
проверки состояния сервисов,
инициализации внешних ресурсов.
Пример:
Такой класс автоматически выполнится один раз при запуске Spring Boot.
👉 Java Portal
Используй CommandLineRunner, если нужно выполнить код сразу после того, как приложение полностью поднялось и контекст инициализирован.
CommandLineRunner — это интерфейс Spring Boot, который позволяет запускать любую логику при старте приложения.
Удобно для:
заполнения базы начальными данными,
проверки состояния сервисов,
инициализации внешних ресурсов.
Пример:
@Component
public class StartupRunner implements CommandLineRunner {
@Override
public void run(String... args) {
System.out.println("App started! Further setup");
}
}
Такой класс автоматически выполнится один раз при запуске Spring Boot.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤2
Тебе не нужно дробить приложение на 20 репозиториев и 15 сервисов, чтобы получить модульность.
Это можно спокойно реализовать внутри грамотно спроектированного модульного монолита.
1. Разделяй модули по функциональным доменам.
Пример: пользователи, платежи, уведомления, отчёты.
Каждый модуль — это свой пакет со своими сущностями, сервисами и бизнес-логикой.
2. Определи чёткие интерфейсы между модулями.
Один модуль не должен знать внутренние классы другого.
Общай их через интерфейсы или внутренние события (например, Spring Events).
Так сохраняется слабое связывание и высокая связность.
3. Избегай циклических зависимостей.
Если модуль A зависит от B, убедись, что B никогда не зависит от A.
Разрывай такие циклы с помощью интерфейсов, dependency injection или событий.
4. Придерживайся принципа внутренних слоёв.
В каждом модуле разделяй внутренние части (entities, repositories, services) и то, что наружу (controllers, DTO, API).
5. Рассмотри использование Spring Modulith (для Java/Kotlin).
Он не заставляет переходить на микросервисы, но даёт инструменты для организации модулей, проверки зависимостей и документирования архитектуры.
6. Опционально: подумай о доменных событиях.
Они помогают масштабировать модульность, не ломая монолит.
И если потом решишь вынести модуль отдельно — половина работы уже сделана.
Модульность зависит не от размера системы, а от чёткости её границ.
Хорошо спроектированный модульный монолит может быть гораздо проще в поддержке, чем хаотичная сеть микросервисов.
👉 Java Portal
Это можно спокойно реализовать внутри грамотно спроектированного модульного монолита.
1. Разделяй модули по функциональным доменам.
Пример: пользователи, платежи, уведомления, отчёты.
Каждый модуль — это свой пакет со своими сущностями, сервисами и бизнес-логикой.
2. Определи чёткие интерфейсы между модулями.
Один модуль не должен знать внутренние классы другого.
Общай их через интерфейсы или внутренние события (например, Spring Events).
Так сохраняется слабое связывание и высокая связность.
3. Избегай циклических зависимостей.
Если модуль A зависит от B, убедись, что B никогда не зависит от A.
Разрывай такие циклы с помощью интерфейсов, dependency injection или событий.
4. Придерживайся принципа внутренних слоёв.
В каждом модуле разделяй внутренние части (entities, repositories, services) и то, что наружу (controllers, DTO, API).
5. Рассмотри использование Spring Modulith (для Java/Kotlin).
Он не заставляет переходить на микросервисы, но даёт инструменты для организации модулей, проверки зависимостей и документирования архитектуры.
6. Опционально: подумай о доменных событиях.
Они помогают масштабировать модульность, не ломая монолит.
И если потом решишь вынести модуль отдельно — половина работы уже сделана.
Модульность зависит не от размера системы, а от чёткости её границ.
Хорошо спроектированный модульный монолит может быть гораздо проще в поддержке, чем хаотичная сеть микросервисов.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤3
Совет по Spring Boot:
используй spring-boot-starter-logging (на Logback) для логирования — он уже подключён по умолчанию.
spring-boot-starter-logging уже включён во большинство стартеров, например spring-boot-starter-web, spring-boot-starter-data-jpa и т.д.
Можно настраивать уровни логирования, отредактировав application.yml:
Чтобы изменить формат логов и политику ротации, создай файл logback-spring.xml в каталоге src/main/resources.
👉 Java Portal
используй spring-boot-starter-logging (на Logback) для логирования — он уже подключён по умолчанию.
spring-boot-starter-logging уже включён во большинство стартеров, например spring-boot-starter-web, spring-boot-starter-data-jpa и т.д.
Можно настраивать уровни логирования, отредактировав application.yml:
logging:
level:
root: INFO
com.myapp: DEBUG
Чтобы изменить формат логов и политику ротации, создай файл logback-spring.xml в каталоге src/main/resources.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
This media is not supported in your browser
VIEW IN TELEGRAM
ChartDB это опенсорс-инструмент для работы с SQL-базами данных через визуальный интерфейс.
Что умеет:
✓ интерактивная диаграмма со всеми таблицами и связями
✓ можно скачать схему как PNG-картинку
✓ поддерживает MySQL, PostgreSQL, SQLite и другие
→ app.chartdb.io
👉 Java Portal
Что умеет:
✓ интерактивная диаграмма со всеми таблицами и связями
✓ можно скачать схему как PNG-картинку
✓ поддерживает MySQL, PostgreSQL, SQLite и другие
→ app.chartdb.io
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5
Spring Boot: можно выполнять задачи через фиксированные интервалы без настройки Quartz или внешних планировщиков.
✅ Добавь
✅ Используй
👉 Java Portal
@EnableScheduling в любой конфигурационный или основной класс приложения:@SpringBootApplication
@EnableScheduling
public class MainApp { }
@Scheduled для метода:@Component
public class Scheduler {
@Scheduled(fixedRate = 5000)
public void executeTask() {
...
}
}
@EnableScheduling активирует механизм планирования, а @Scheduled задаёт частоту выполнения метода (fixedRate = 5000 — каждые 5 секунд).Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Держи сотни гигабайт свежих уроков, и каждую неделю мы подкидываем ещё!
• 1612 ГБ — DevOps
• 1402 ГБ — Python
• 1300 ГБ — C, C++
• 1815 ГБ — Frontend
• 1515 ГБ — Backend
• 898 ГБ — ИБ, Хакинг
• 996 ГБ — Kotlin, Swift
• 212 ГБ — JavaScript
• 315 ГБ — Flutter
• 820 ГБ — Go, PHP
• 419 ГБ — Java, Rust
• 648 ГБ — GameDev
• 517 ГБ — Windows, Linux
• 998 ГБ — Дизайн (UX/UI)
• 617 ГБ — Нейросети (ML/RL)
• 546 ГБ — БД (SQL & NoSQL)
• 687 ГБ — Аналитика данных
• 115 ГБ — QA-тестирование
Подписывайся и не плати за то, что можно получить бесплатно
Please open Telegram to view this post
VIEW IN TELEGRAM
У тебя есть 3 сервера. Приходит 100 запросов. Как их распределить? Вот возможные варианты:
Алгоритмы балансировки нагрузки
🔸 Round Robin (циклический)
- Запрос 1 —> на сервер A
- Запрос 2 —> на сервер B
- Запрос 3 —> на сервер C
- Запрос 4 —> снова на сервер A
- И так по кругу бесконечно
Когда использовать: все сервера одинаковые, запросы примерно равны по времени обработки. Самый простой вариант.
🔸 Weighted Round Robin (взвешенный циклический)
- Сервер A: 4 ядра, вес 4
- Сервер B: 8 ядер, вес 8
- Сервер C: 4 ядра, вес 4
- Из каждых 16 запросов: A получает 4, B — 8, C — 4
Когда использовать: мощности серверов разные, нужно распределять нагрузку пропорционально.
🔸 Least Connections (наименьшее количество соединений)
- Сервер A: 50 активных соединений
- Сервер B: 30 активных соединений
- Сервер C: 45 активных соединений
- Следующий запрос уходит на сервер B (у него меньше всего соединений)
Когда использовать: запросы обрабатываются разное время, есть долгоживущие соединения, например WebSocket.
🔸 Weighted Least Connections (взвешенный по соединениям)
- Сервер A: 50 соединений, 4 ядра → соотношение 12.5
- Сервер B: 30 соединений, 8 ядер → соотношение 3.75
- Сервер C: 45 соединений, 4 ядра → соотношение 11.25
- Следующий запрос идёт на сервер B (самое низкое соотношение)
Когда использовать: сервера разной мощности, при этом соединения держатся долго.
🔸 IP Hash (хеш по IP)
- IP пользователя: 192.168.1.100
- Этот IP хешируется и всегда маршрутизируется на сервер B
- Один и тот же пользователь всегда попадает на один и тот же сервер
Когда использовать: нужна привязка сессии к конкретному серверу, нет общего session storage. Sticky sessions.
🔸 Least Response Time (наименьшее время отклика)
- Сервер A: средний отклик 200 мс
- Сервер B: 150 мс
- Сервер C: 300 мс
- Следующий запрос уходит на сервер B (самый быстрый)
Когда использовать: производительность серверов разная, например, для чтения из реплик БД с разным lag.
🔸 Random (случайное распределение)
- Просто выбирается случайный сервер
- Ничего отслеживать не нужно
- На больших масштабах работает удивительно неплохо
Когда использовать: простые распределённые системы, stateless-сервисы, когда учёт состояния не оправдан.
В большинстве продакшн-систем хорошо себя показывает вариант Least Connections с весами.
👉 Java Portal
Алгоритмы балансировки нагрузки
- Запрос 1 —> на сервер A
- Запрос 2 —> на сервер B
- Запрос 3 —> на сервер C
- Запрос 4 —> снова на сервер A
- И так по кругу бесконечно
Когда использовать: все сервера одинаковые, запросы примерно равны по времени обработки. Самый простой вариант.
- Сервер A: 4 ядра, вес 4
- Сервер B: 8 ядер, вес 8
- Сервер C: 4 ядра, вес 4
- Из каждых 16 запросов: A получает 4, B — 8, C — 4
Когда использовать: мощности серверов разные, нужно распределять нагрузку пропорционально.
- Сервер A: 50 активных соединений
- Сервер B: 30 активных соединений
- Сервер C: 45 активных соединений
- Следующий запрос уходит на сервер B (у него меньше всего соединений)
Когда использовать: запросы обрабатываются разное время, есть долгоживущие соединения, например WebSocket.
- Сервер A: 50 соединений, 4 ядра → соотношение 12.5
- Сервер B: 30 соединений, 8 ядер → соотношение 3.75
- Сервер C: 45 соединений, 4 ядра → соотношение 11.25
- Следующий запрос идёт на сервер B (самое низкое соотношение)
Когда использовать: сервера разной мощности, при этом соединения держатся долго.
- IP пользователя: 192.168.1.100
- Этот IP хешируется и всегда маршрутизируется на сервер B
- Один и тот же пользователь всегда попадает на один и тот же сервер
Когда использовать: нужна привязка сессии к конкретному серверу, нет общего session storage. Sticky sessions.
- Сервер A: средний отклик 200 мс
- Сервер B: 150 мс
- Сервер C: 300 мс
- Следующий запрос уходит на сервер B (самый быстрый)
Когда использовать: производительность серверов разная, например, для чтения из реплик БД с разным lag.
- Просто выбирается случайный сервер
- Ничего отслеживать не нужно
- На больших масштабах работает удивительно неплохо
Когда использовать: простые распределённые системы, stateless-сервисы, когда учёт состояния не оправдан.
В большинстве продакшн-систем хорошо себя показывает вариант Least Connections с весами.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
В Spring Boot аннотация
Тесты выполняются с использованием встроенной базы данных, например H2, а после каждого теста все транзакции автоматически откатываются.
👉 Java Portal
@DataJpaTest используется для изолированного тестирования JPA-репозиториев.@DataJpaTest поднимает только JPA-слой, не загружая весь контекст приложения.Тесты выполняются с использованием встроенной базы данных, например H2, а после каждого теста все транзакции автоматически откатываются.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
29 октября(уже сегодня!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью по System Design.
Как это будет:
📂 Дмитрий Дорофеев, TeamLead в американском FitTech Truv Inc, ex-VK, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Дмитрий будет комментировать каждый ответ респондента, чтобы дать понять, чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Дмитрию
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
Как это будет:
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
Maven Plugin Tip — DepClean
DepClean автоматически чистит дерево зависимостей в Java-проектах. Он удаляет все зависимости, которые прописаны в дереве, но при сборке на самом деле не нужны.🔥
https://github.com/ASSERT-KTH/depclean
👉 Java Portal
DepClean автоматически чистит дерево зависимостей в Java-проектах. Он удаляет все зависимости, которые прописаны в дереве, но при сборке на самом деле не нужны.
https://github.com/ASSERT-KTH/depclean
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍2🔥2
Санкт-Петербург, 13 ноября в 19:00
Разберём архитектуру облачной записи встреч, наведём порядок в API и покажем, как простые решения спасают сервисы.
В программе:
📌 Как не упустить важное: архитектура облачной записи и конспектирования видеовстреч в Телемосте — Илья Григорьев, разработчик бэкенда Телемоста.
📌 Укрощение API: процессы и инструменты, которые действительно работают — Никита Ломакин, разработчик в команде Техплатформы.
📌 Как мы закапывали звездолёт: почему важно отстаивать простоту на архревью — Артемий Коцюбенко, разработчик протокольных сервисов Почты.
Команда Яндекс 360 работает с нагрузками >1.000.000+ RPS и создает продукты которыми пользуются 95+ млн человек каждый месяц — Диск, Почта, Телемост, Мессенджер и другие.
🍻А после докладов вас будут ждать афтепати и нетворкинг!
Регистрируйтесь по ссылке
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Векторные базы данных простыми словами
Представь, у тебя есть 10 000 описаний товаров. Пользователь ищет "удобная уличная мебель".
Обычная база данных:
Ищет точные совпадения слов
Находит товары с "удобная" ИЛИ "уличная" ИЛИ "мебель"
Пропускает "уютные кресла для террасы", хотя это то же самое
Ключевые слова — тупой способ поиска
Векторная база данных:
Превращает запрос в набор чисел, отражающих смысл: [0.2, 0.8, 0.1, 0.9, ...]
Каждое описание товара тоже превращается в такие числа
Сравнивает эти "векторы" и ищет похожие по смыслу
Находит "уютные кресла для террасы", потому что векторы похожи
Смысловой поиск — умный поиск
Как это работает
Шаг 1. Превращаем текст в векторы (массивы чисел)
"comfortable chair" → [0.2, 0.7, 0.1, 0.4, ...]
"cozy seat" → [0.3, 0.8, 0.2, 0.5, ...]
Похожие фразы → похожие числа
Это делает AI-модель, например OpenAI embeddings
Шаг 2. Храним векторы
В обычной БД хранят текст
В векторной — массив чисел для каждого объекта
Индексируют их, чтобы быстро искать по схожести
Оптимизировано под "найди похожие", а не "найди точное"
Шаг 3. Ищем по схожести
Запрос: "outdoor furniture"
Превращается в [0.3, 0.6, 0.2, 0.8, ...]
Система ищет ближайшие векторы (через cosine similarity)
Результаты сортируются по степени похожести
Где это используется:
- Поиск товаров, который понимает смысл, а не только слова
- Поиск по документации, который находит релевантные ответы
- Рекомендательные системы
- Чатботы, ищущие похожие вопросы
- Обнаружение аномалий
Популярные векторные базы
Pinecone = управляемая, простая, но дорогая
Weaviate = опенсорс, с кучей функций
Milvus = быстрая и масштабируемая, но сложная
pgvector = расширение для Postgres, простое и удобное
Qdrant = быстрая, написана на Rust
Спорная, но практичная мысль
В большинстве проектов тебе не нужна отдельная векторная база.
Начни с Postgres + pgvector = этого хватает, пока у тебя меньше 1 миллиона векторов.
Когда масштаб вырастет, тогда уже смотри в сторону специализированных решений.
👉 Java Portal
Представь, у тебя есть 10 000 описаний товаров. Пользователь ищет "удобная уличная мебель".
Обычная база данных:
Ищет точные совпадения слов
Находит товары с "удобная" ИЛИ "уличная" ИЛИ "мебель"
Пропускает "уютные кресла для террасы", хотя это то же самое
Ключевые слова — тупой способ поиска
Векторная база данных:
Превращает запрос в набор чисел, отражающих смысл: [0.2, 0.8, 0.1, 0.9, ...]
Каждое описание товара тоже превращается в такие числа
Сравнивает эти "векторы" и ищет похожие по смыслу
Находит "уютные кресла для террасы", потому что векторы похожи
Смысловой поиск — умный поиск
Как это работает
Шаг 1. Превращаем текст в векторы (массивы чисел)
"comfortable chair" → [0.2, 0.7, 0.1, 0.4, ...]
"cozy seat" → [0.3, 0.8, 0.2, 0.5, ...]
Похожие фразы → похожие числа
Это делает AI-модель, например OpenAI embeddings
Шаг 2. Храним векторы
В обычной БД хранят текст
В векторной — массив чисел для каждого объекта
Индексируют их, чтобы быстро искать по схожести
Оптимизировано под "найди похожие", а не "найди точное"
Шаг 3. Ищем по схожести
Запрос: "outdoor furniture"
Превращается в [0.3, 0.6, 0.2, 0.8, ...]
Система ищет ближайшие векторы (через cosine similarity)
Результаты сортируются по степени похожести
Где это используется:
- Поиск товаров, который понимает смысл, а не только слова
- Поиск по документации, который находит релевантные ответы
- Рекомендательные системы
- Чатботы, ищущие похожие вопросы
- Обнаружение аномалий
Популярные векторные базы
Pinecone = управляемая, простая, но дорогая
Weaviate = опенсорс, с кучей функций
Milvus = быстрая и масштабируемая, но сложная
pgvector = расширение для Postgres, простое и удобное
Qdrant = быстрая, написана на Rust
Спорная, но практичная мысль
В большинстве проектов тебе не нужна отдельная векторная база.
Начни с Postgres + pgvector = этого хватает, пока у тебя меньше 1 миллиона векторов.
Когда масштаб вырастет, тогда уже смотри в сторону специализированных решений.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9