Совет по 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
У тебя есть 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
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
❤2
Векторные базы данных простыми словами
Представь, у тебя есть 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
❤13
Самый прямолинейный способ вынести секреты во внешнее хранилище в Spring Boot приложении это использовать Spring Cloud Config Server.
Spring Cloud Config Server позволяет хранить конфигурацию приложения в централизованном репозитории (обычно Git).
В случае с Git репозиторием при старте приложение подтягивает конфигурационные файлы с Config Server, а не локально, а сам Config Server берет их из Git репозитория. Ниже пример конфигурации, чтобы сервер подключался к Git репо:
Конфигурация клиента может выглядеть примерно так:
Можно шифровать чувствительные данные в конфигурационных файлах в Git репо. Ниже пример с паролем для key-store, который используется для защищенного SSL соединения (обрати внимание на префикс
Альтернатива это использовать HashiCorp Vault
👉 Java Portal
Spring Cloud Config Server позволяет хранить конфигурацию приложения в централизованном репозитории (обычно Git).
В случае с Git репозиторием при старте приложение подтягивает конфигурационные файлы с Config Server, а не локально, а сам Config Server берет их из Git репозитория. Ниже пример конфигурации, чтобы сервер подключался к Git репо:
cloud:
config:
server:
git:
uri: https://github.com/username/spring-cloud-config-git-server-repo.git
username: ${github.username}
password: ${github.password}
Конфигурация клиента может выглядеть примерно так:
config:
import: "optional:configserver:"
Можно шифровать чувствительные данные в конфигурационных файлах в Git репо. Ниже пример с паролем для key-store, который используется для защищенного SSL соединения (обрати внимание на префикс
{cipher}, он обязателен)server:
port: ${PORT:8092}
ssl:
enabled: true
key-store: classpath:books.p12
key-store-password: '{cipher}AAQAB0P8AKMImyLncL3WUbLsn2J0DlHBeMbmylb0e5RMqr7QWrPhDwJ8xVMw...'
key-store-type: PKCS12:
Альтернатива это использовать HashiCorp Vault
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Нашёл минималистичный инструмент, который берет любую shell-команду и в реальном времени рисует по ней графики. Да, прямо у тебя в консоли. Красиво и без плясок с бубном.
Что может:
• Выполняет любые команды и сразу строит графики по их выводу
• Следит за базами, CPU, сетью, очередями, деплоем и чем угодно ещё
• Бьет в колокола, если метрика вылетела за пределы
• Настраивается через обычный YAML. Пара строк и ты уже смотришь, как машина дышит
• Работает локально, без облаков и лишних зависимостей
👉 Java Portal
Что может:
• Выполняет любые команды и сразу строит графики по их выводу
• Следит за базами, CPU, сетью, очередями, деплоем и чем угодно ещё
• Бьет в колокола, если метрика вылетела за пределы
• Настраивается через обычный YAML. Пара строк и ты уже смотришь, как машина дышит
• Работает локально, без облаков и лишних зависимостей
Please open Telegram to view this post
VIEW IN TELEGRAM
В Java строки после создания не меняются.
Вообще. Совсем.
Пишешь:
Кажется, что ты просто дописал кусочек. Но на деле появился новый объект, а старый остался как был.
Зачем так заморачиваться?
Строки одна из самых используемых штук в JVM: названия классов, SQL-запросы, адреса, токены безопасности, всё подряд. И этими строками спокойно шарятся между потоками.
Если бы любой поток мог внезапно изменить текст, который использует другой поток, то был полный бардак: баги из разряда «иногда, где-то, когда-то» и куча дыр в безопасности.
Поэтому неизменяемость даёт:
• Потоки не мешают друг другу. Никаких локов и синхронизации.
• Можно безопасно кешировать строки. Тот же String Pool — из этой оперы.
• JVM может оптимизировать работу с ними как ей вздумается, без риска сломать логику программы.
Если же нужно много править текст во время выполнения (например, большая сборка строки в цикле) то бери StringBuilder или, если сильно нужна потокобезопасность, StringBuffer.
Иммутабельность строки это не чудачество создателей языка. Это фундамент стабильности и безопасности Java.
👉 Java Portal
Вообще. Совсем.
Пишешь:
String saludo = "Hola";
saludo += " mundo";
Кажется, что ты просто дописал кусочек. Но на деле появился новый объект, а старый остался как был.
Зачем так заморачиваться?
Строки одна из самых используемых штук в JVM: названия классов, SQL-запросы, адреса, токены безопасности, всё подряд. И этими строками спокойно шарятся между потоками.
Если бы любой поток мог внезапно изменить текст, который использует другой поток, то был полный бардак: баги из разряда «иногда, где-то, когда-то» и куча дыр в безопасности.
Поэтому неизменяемость даёт:
• Потоки не мешают друг другу. Никаких локов и синхронизации.
• Можно безопасно кешировать строки. Тот же String Pool — из этой оперы.
• JVM может оптимизировать работу с ними как ей вздумается, без риска сломать логику программы.
Если же нужно много править текст во время выполнения (например, большая сборка строки в цикле) то бери StringBuilder или, если сильно нужна потокобезопасность, StringBuffer.
Иммутабельность строки это не чудачество создателей языка. Это фундамент стабильности и безопасности Java.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10
Forwarded from бизнестрендс
⚡️ Запускаем крупный розыгрыш призов, где можно выиграть iPhone 17, игровые наушники, клавиатуру и мышь!
Без лишних слов, условия:
1. Подписка на:
— бизнестрендс
— Технотренды
— Блумберг
2. Нажать кнопку «Участвовать» снизу
Итоги будут опубликованы 15 ноября в 18:00 на наших каналах, желаем удачи!
Без лишних слов, условия:
1. Подписка на:
— бизнестрендс
— Технотренды
— Блумберг
2. Нажать кнопку «Участвовать» снизу
Итоги будут опубликованы 15 ноября в 18:00 на наших каналах, желаем удачи!
Spring Boot 4 показывает нормальную работу null-safety в деле
Главная беда в том, что в Java null всегда был вещью по умолчанию и нигде явно не указан. Видишь метод типа:
User findUserByEmail(String email)
Вернет null? Кто его знает
Spring Boot 4 меняет правила игры с NullMarked (на базе JSpecify + NullAway). Одна аннотация на уровне пакета делает работу с null явной. IDE сразу подсвечивает потенциальные NPE еще на этапе компиляции. Больше никаких угадай-ок и сюрпризов на проде.
Инструменты подталкивают обрабатывать null там, где это действительно важно. Типы наконец начинают говорить правду.
Вот такая developer experience, которой давно ждали.
👉 Java Portal
Главная беда в том, что в Java null всегда был вещью по умолчанию и нигде явно не указан. Видишь метод типа:
User findUserByEmail(String email)
Вернет null? Кто его знает
Spring Boot 4 меняет правила игры с NullMarked (на базе JSpecify + NullAway). Одна аннотация на уровне пакета делает работу с null явной. IDE сразу подсвечивает потенциальные NPE еще на этапе компиляции. Больше никаких угадай-ок и сюрпризов на проде.
Инструменты подталкивают обрабатывать null там, где это действительно важно. Типы наконец начинают говорить правду.
Вот такая developer experience, которой давно ждали.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3❤1