Java for Beginner
672 subscribers
541 photos
155 videos
12 files
827 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Всем доброго утра!

Есть вопрос - вчера мы начали писать тестовый сервис хранения носков на складе. Стоит ли продолжить? И второй момент, что можно это сделать в середине недели. Вас это устроит, или привычнее вечер воскресения?
Anonymous Poll
88%
Да, продолжай в любой день!
8%
Да, но мне удобнее быть в воскресение
0%
Какой сервис, о чем ты?
0%
Не, не стоит продолжать, не интересно
4%
Хватит выкладывать всякую чушь!
Пагинация и фильтрация данных в REST API с использованием Spring

При работе с большими наборами данных в REST API критически важна поддержка пагинации и фильтрации. Они позволяют улучшить производительность приложения, сократить нагрузку на сервер и предоставить клиентам удобные способы получать нужные данные.

1. Пагинация (Pagination) в Spring

Пагинация позволяет разделить большие объемы данных на страницы и возвращать их по частям. В Spring Boot пагинация реализуется с помощью Spring Data JPA.

Подключение пагинации в проекте

Spring Data JPA предоставляет интерфейсы и аннотации для легкой реализации пагинации.

Добавьте параметр Pageable в методы репозитория:
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {

Page<User> findAll(Pageable pageable);

}


Page — это контейнер, который содержит данные текущей страницы и мета-информацию (например, общее количество страниц).
Pageable — это интерфейс для параметров пагинации: номер страницы, размер страницы и сортировка.


Использование Pageable в контроллере:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/users")
public class UserController {

private final UserRepository userRepository;

@Autowired
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}

@GetMapping
public ResponseEntity<Page<User>> getAllUsers(Pageable pageable) {
Page<User> users = userRepository.findAll(pageable);
return ResponseEntity.ok(users);
}
}


Пример запроса с пагинацией:
GET /api/users?page=0&size=5&sort=name,asc
page — номер страницы (начинается с 0).
size — количество элементов на странице.
sort — параметры сортировки (поле,направление).


Пример ответа:
{
"content": [
{"id": 1, "name": "John", "email": "john@example.com"},
{"id": 2, "name": "Jane", "email": "jane@example.com"}
],
"pageable": {
"pageNumber": 0,
"pageSize": 5
},
"totalPages": 2,
"totalElements": 10,
"last": false
}


2. Фильтрация данных в REST API

Фильтрация позволяет клиентам задавать условия, по которым нужно отбирать данные.


Подходы к фильтрации

Фильтрация по параметрам запроса (Request Parameters): Используется для простой фильтрации данных.

Динамическая фильтрация с помощью Specification или Criteria:
Применяется для сложных и многоуровневых условий.

Фильтрация по параметрам запроса
Реализация простого поиска с фильтрацией:

Добавьте методы в репозиторий:
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface UserRepository extends JpaRepository<User, Long> {

List<User> findByNameContaining(String name);

List<User> findByAgeGreaterThanEqual(Integer age);

}


#Java #Training #Spring #Pagination #Filter
Добавьте фильтры в контроллер:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/users")
public class UserController {

private final UserRepository userRepository;

@Autowired
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}

@GetMapping("/search")
public ResponseEntity<List<User>> searchUsers(
@RequestParam(required = false) String name,
@RequestParam(required = false) Integer age) {

if (name != null) {
return ResponseEntity.ok(userRepository.findByNameContaining(name));
} else if (age != null) {
return ResponseEntity.ok(userRepository.findByAgeGreaterThanEqual(age));
} else {
return ResponseEntity.ok(userRepository.findAll());
}
}
}


Примеры запросов:

Фильтрация по имени:
GET /api/users/search?name=John


Фильтрация по возрасту:
GET /api/users/search?age=30


Динамическая фильтрация с использованием Specification
Для сложных фильтров можно использовать Spring Data JPA Specification.

Добавьте зависимость:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>


Создайте Specification для фильтрации:
import org.springframework.data.jpa.domain.Specification;

public class UserSpecification {

public static Specification<User> hasName(String name) {
return (root, query, cb) -> cb.like(root.get("name"), "%" + name + "%");
}

public static Specification<User> hasAgeGreaterThan(Integer age) {
return (root, query, cb) -> cb.greaterThanOrEqualTo(root.get("age"), age);
}
}


Расширьте репозиторий:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
}


Добавьте динамическую фильтрацию в контроллер:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/users")
public class UserController {

private final UserRepository userRepository;

@Autowired
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}

@GetMapping("/filter")
public ResponseEntity<List<User>> filterUsers(
@RequestParam(required = false) String name,
@RequestParam(required = false) Integer age) {

Specification<User> spec = Specification.where(null);

if (name != null) {
spec = spec.and(UserSpecification.hasName(name));
}

if (age != null) {
spec = spec.and(UserSpecification.hasAgeGreaterThan(age));
}

return ResponseEntity.ok(userRepository.findAll(spec));
}
}


Пример запроса с фильтрацией:

GET /api/users/filter?name=Jane&age=25


3. Пагинация и фильтрация вместе

Совмещение пагинации и фильтрации:
@GetMapping("/filter")
public ResponseEntity<Page<User>> filterUsers(
@RequestParam(required = false) String name,
@RequestParam(required = false) Integer age,
Pageable pageable) {

Specification<User> spec = Specification.where(null);

if (name != null) {
spec = spec.and(UserSpecification.hasName(name));
}

if (age != null) {
spec = spec.and(UserSpecification.hasAgeGreaterThan(age));
}

Page<User> result = userRepository.findAll(spec, pageable);
return ResponseEntity.ok(result);
}


Пример запроса:
GET /api/users/filter?name=Jane&page=0&size=5&sort=age,desc


#Java #Training #Spring #Pagination #Filter
Что выведет код?

import java.util.HashMap;
import java.util.Map;

public class Task231224_1 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
map.put("a", 3);
map.put("c", null);

System.out.println(map.get("a") + " " + map.get("c"));
}
}


#Tasks
Варианты ответа:
Anonymous Quiz
43%
1 null
4%
3 0
52%
3 null
0%
2 null
И поднять его теперь не так просто🤪😂

https://t.me/Java_for_beginner_dev

#Mems
Обработка ошибок в REST API с использованием Spring Boot

Эффективная обработка ошибок в REST API — важный аспект разработки, обеспечивающий ясность и удобство использования для клиентов. API должен возвращать информативные сообщения об ошибках в стандартизированном формате, указывать причины проблемы и, по возможности, предлагать пути решения.

1. Основные аспекты обработки ошибок


Использование HTTP-кодов:
1xx: Informational (информационные)
2xx: Success (успешно)
3xx: Redirection (перенаправление)
4xx: Client Error (ошибка клиента, например, неправильный запрос, ресурс не найден).
5xx: Server Error (ошибка сервера, например, проблемы на уровне базы данных или приложения).


Возврат стандартного формата ошибки: Сообщения об ошибках должны быть понятны и содержать:
- Код состояния HTTP.
- Сообщение об ошибке.
- Вспомогательную информацию (например, время ошибки или идентификатор запроса).


Обработка различных типов ошибок:
- Ошибки валидации.
- Отсутствие ресурсов.
- Некорректный формат запроса.
- Ошибки на уровне сервера.


2. Обработка ошибок с использованием @ControllerAdvice

Аннотация @ControllerAdvice позволяет централизованно обрабатывать исключения, возникающие в контроллерах.

Создайте класс для обработки исключений:
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(RuntimeException.class)
public ResponseEntity<ErrorResponse> handleRuntimeException(RuntimeException ex) {
ErrorResponse errorResponse = new ErrorResponse(
HttpStatus.BAD_REQUEST.value(),
ex.getMessage(),
System.currentTimeMillis()
);
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}

@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleResourceNotFoundException(ResourceNotFoundException ex) {
ErrorResponse errorResponse = new ErrorResponse(
HttpStatus.NOT_FOUND.value(),
ex.getMessage(),
System.currentTimeMillis()
);
return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}
}


Класс ответа на ошибку:
public class ErrorResponse {

private int status;
private String message;
private long timestamp;

public ErrorResponse(int status, String message, long timestamp) {
this.status = status;
this.message = message;
this.timestamp = timestamp;
}

// Геттеры и сеттеры...
}


Пользовательское исключение для отсутствия ресурса:
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}


#Java #Training #Spring #API_Errors
3. Обработка ошибок валидации

Spring Boot поддерживает валидацию запросов с помощью аннотаций javax.validation. Ошибки можно обрабатывать централизованно.

Добавьте валидацию в сущность:
import jakarta.validation.constraints.*;

@Entity
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@NotBlank(message = "Name cannot be blank")
private String name;

@Email(message = "Invalid email address")
private String email;

@Min(value = 18, message = "Age must be at least 18")
private Integer age;

// Геттеры и сеттеры...
}


Обработайте ошибки валидации:

import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ControllerAdvice;

import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
for (FieldError error : ex.getBindingResult().getFieldErrors()) {
errors.put(error.getField(), error.getDefaultMessage());
}
return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
}
}


Пример ответа при ошибке валидации:
{
"name": "Name cannot be blank",
"email": "Invalid email address"
}


4. Обработка ошибок на уровне контроллера

Если требуется специфичная обработка для одного контроллера, можно использовать аннотацию @ExceptionHandler внутри самого контроллера.
@RestController
@RequestMapping("/api/users")
public class UserController {

@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
return userRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("User not found with id: " + id));
}

@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) {
ErrorResponse errorResponse = new ErrorResponse(
HttpStatus.NOT_FOUND.value(),
ex.getMessage(),
System.currentTimeMillis()
);
return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}
}


5. Настройка формата ответа

Вы можете настроить формат ответа об ошибке на уровне всего приложения с помощью аннотации @RestControllerAdvice (аналог @ControllerAdvice, но возвращает JSON по умолчанию).

@RestControllerAdvice
public class GlobalRestExceptionHandler {

@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGlobalException(Exception ex) {
ErrorResponse errorResponse = new ErrorResponse(
HttpStatus.INTERNAL_SERVER_ERROR.value(),
"An unexpected error occurred",
System.currentTimeMillis()
);
return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
}


#Java #Training #Spring #API_Errors
6. Настройка ошибок Spring Boot

Spring Boot возвращает стандартные страницы ошибок, такие как Whitelabel Error Page. Для кастомизации ошибок используйте ErrorController.

Отключите Whitelabel Error Page:
server.error.whitelabel.enabled=false
Создайте собственный контроллер ошибок:
java
Копировать код
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.context.request.WebRequest;

import java.util.Map;

@Controller
public class CustomErrorController implements ErrorController {

private final ErrorAttributes errorAttributes;

public CustomErrorController(ErrorAttributes errorAttributes) {
this.errorAttributes = errorAttributes;
}

@RequestMapping("/error")
public ResponseEntity<Map<String, Object>> handleError(WebRequest webRequest) {
Map<String, Object> errors = errorAttributes.getErrorAttributes(webRequest, ErrorAttributeOptions.defaults());
HttpStatus status = HttpStatus.valueOf((int) errors.get("status"));
return new ResponseEntity<>(errors, status);
}
}


7. Пример API с обработкой ошибок

Пример запроса:
GET /api/users/999


Пример ответа:

{
"status": 404,
"message": "User not found with id: 999",
"timestamp": 1702745190123
}


8. Советы по обработке ошибок

Возвращайте только необходимую информацию:
Не отправляйте stack trace клиенту.
Показывайте сообщение об ошибке, понятное конечному пользователю.


Используйте стандартные HTTP-коды:
400 (Bad Request) — ошибка клиента.
401 (Unauthorized) — пользователь не авторизован.
404 (Not Found) — ресурс не найден.
500 (Internal Server Error) — ошибка сервера.


Добавьте логирование: Все ошибки должны логироваться для анализа.


#Java #Training #Spring #API_Errors
Микросервисы в контексте Spring

Микросервисная архитектура является одним из наиболее популярных подходов к созданию современных приложений, особенно в сочетании с фреймворком Spring. Она позволяет разрабатывать, развертывать и масштабировать приложения в виде независимых компонентов, каждый из которых решает определенную бизнес-задачу.


1. Что такое микросервисы?

Микросервисы — это подход к разработке программного обеспечения, при котором приложение разбивается на множество небольших, независимых сервисов. Каждый сервис выполняет одну задачу или отвечает за один функциональный модуль (например, управление пользователями, обработка заказов, инвентаризация).

Основные характеристики микросервисов:
Независимость: Каждый сервис можно разрабатывать, тестировать и развертывать отдельно.
Декомпозиция по бизнес-функциям: Каждый микросервис реализует отдельный бизнес-контекст.
Автономность: Сервисы могут использовать разные языки программирования, базы данных и технологии.
Четкие API: Сервисы взаимодействуют между собой с использованием REST, gRPC, AMQP или других протоколов.
Устойчивость: Отказ одного микросервиса не приводит к полному выходу системы из строя.


2. Виды микросервисов

Микросервисы можно разделить по нескольким критериям:

2.1. По роли в системе:

Core Services (основные сервисы):
Реализуют ключевые бизнес-функции.
Примеры: сервис управления пользователями, сервис обработки платежей.


Supporting Services (вспомогательные сервисы):
Выполняют второстепенные задачи, такие как отправка уведомлений или сбор логов.

Integration Services (интеграционные сервисы):
Предоставляют интерфейсы для взаимодействия с внешними системами.

API Gateway:
Центральный узел для маршрутизации запросов от клиентов к микросервисам.

2.2. По типу взаимодействия:

Синхронные:
Используют REST или gRPC для запроса и получения данных.
Примеры: взаимодействие клиентского приложения с сервисом через REST API.


Асинхронные:
Обмениваются событиями через системы очередей (RabbitMQ, Kafka, ActiveMQ).
Примеры: сервисы уведомлений или обработка фоновых задач.


3. Spring и микросервисы

Spring предоставляет богатый набор инструментов для создания микросервисов, включая:

Spring Boot:
Упрощает создание самостоятельных приложений, которые легко запускать.
Предоставляет встроенные серверы (Tomcat, Jetty, Undertow).


Spring Cloud:
Специализированный модуль для работы с микросервисами.
Поддерживает маршрутизацию, конфигурацию, обнаружение сервисов и управление отказами.


Spring Data:
Упрощает работу с базами данных.

Spring Security:
Реализует безопасность микросервисов (авторизация, аутентификация, токены).

4. Взаимодействие микросервисов

Для взаимодействия между микросервисами используются два подхода:

4.1. Синхронное взаимодействие
Используется при необходимости мгновенного ответа.

Основные инструменты:
REST API:
Самый популярный способ взаимодействия микросервисов.
Формат данных: JSON или XML.


gRPC:
Высокопроизводительный протокол на базе HTTP/2.
Поддерживает сериализацию с использованием Protocol Buffers (Protobuf).


Пример REST API с Spring Boot:
Сервис UserService:
@RestController
@RequestMapping("/users")
public class UserController {

@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
User user = userService.findUserById(id);
return ResponseEntity.ok(user);
}
}


Сервис OrderService, вызывающий UserService:
import org.springframework.web.client.RestTemplate;

@Service
public class OrderService {

private final RestTemplate restTemplate;

@Autowired
public OrderService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}

public User getUserDetails(Long userId) {
return restTemplate.getForObject("http://USER-SERVICE/users/" + userId, User.class);
}
}


#Java #Training #Spring #Microservices
4.2. Асинхронное взаимодействие
Используется для передачи событий и задач, которые могут быть обработаны позже.

Основные инструменты:
RabbitMQ:
Брокер сообщений для передачи сообщений через очереди.

Apache Kafka:
Распределённая платформа потоковой обработки данных.

Пример асинхронного взаимодействия с RabbitMQ:

Отправка сообщения:
import org.springframework.amqp.rabbit.core.RabbitTemplate;

@Service
public class NotificationService {

private final RabbitTemplate rabbitTemplate;

@Autowired
public NotificationService(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}

public void sendNotification(String message) {
rabbitTemplate.convertAndSend("notificationsQueue", message);
}
}


Обработка сообщения:
import org.springframework.amqp.rabbit.annotation.RabbitListener;

@Service
public class NotificationListener {

@RabbitListener(queues = "notificationsQueue")
public void processNotification(String message) {
System.out.println("Received notification: " + message);
}
}


5. Развертывание микросервисов

Развертывание микросервисов — это ключевой этап, который можно реализовать с использованием контейнеров и оркестраторов.

5.1. Использование Docker
Создайте Dockerfile для каждого микросервиса:
FROM openjdk:17-jdk-slim
COPY target/microservice.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]


Создайте Docker Compose файл для нескольких микросервисов:
version: '3'
services:
user-service:
build: ./user-service
ports:
- "8081:8080"
order-service:
build: ./order-service
ports:
- "8082:8080"


5.2. Оркестрация с Kubernetes
Создайте Deployment для микросервиса:
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
spec:
replicas: 3
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
spec:
containers:
- name: user-service
image: user-service:latest
ports:
- containerPort: 8080


Добавьте Service для доступа к Deployment:
apiVersion: v1
kind: Service
metadata:
name: user-service
spec:
selector:
app: user-service
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP


6. Spring Cloud для микросервисов

Spring Cloud упрощает создание микросервисов, предоставляя готовые решения для:
Обнаружения сервисов: Eureka, Consul.
Маршрутизации: Spring Cloud Gateway.
Конфигурации: Spring Cloud Config.
Устойчивости: Circuit Breaker (Resilience4j, Hystrix).


Пример использования Eureka для обнаружения сервисов:
Eureka Server:
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}


Eureka Client:
@EnableEurekaClient
@SpringBootApplication
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}


#Java #Training #Spring #Microservices
Что выведет код?

import java.util.Arrays;
import java.util.List;

public class Test {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(name -> {
if (name.startsWith("A")) {
System.out.println(name);
}
});
}
}


#Tasks
Варианты ответа:
Anonymous Quiz
0%
Alice Bob Charlie
90%
Alice
3%
Alloha
7%
Java
0%
Nothing
А потом они становятся аналитиками с ЧСВ🧐🤪😂

https://t.me/Java_for_beginner_dev

#Mems
Компоненты микросервисной архитектуры

Микросервисная архитектура включает множество компонентов, которые обеспечивают её функциональность, масштабируемость и устойчивость. Разберём ключевые элементы, не повторяя уже упомянутые аспекты, и сосредоточимся на архитектурных и инфраструктурных компонентах.

1. API Gateway

API Gateway — это точка входа для клиентов в микросервисную архитектуру. Он обрабатывает все запросы от внешних приложений и маршрутизирует их к соответствующим микросервисам.


Основные функции:
Маршрутизация запросов: Отправляет запросы к нужным микросервисам.
Агрегация данных: Собирает данные от нескольких сервисов и возвращает единый ответ клиенту.
Безопасность: Реализует аутентификацию и авторизацию, ограничивает доступ к ресурсам.
Кэширование: Ускоряет ответы на повторяющиеся запросы.
Обработка ошибок: Преобразует ошибки микросервисов в понятный клиентам формат.


2. Service Discovery
В микросервисной архитектуре сервисы могут динамически добавляться или удаляться. Service Discovery помогает находить доступные сервисы в распределённой системе.

Основные компоненты:
Service Registry: Хранилище, где регистрируются все доступные сервисы (например, Eureka, Consul, Zookeeper).
Service Provider: Микросервис, который регистрируется в реестре.
Service Consumer: Клиент, который запрашивает информацию о доступных сервисах.


Подходы к Service Discovery:
Client-Side Discovery: Клиент напрямую взаимодействует с реестром и выбирает сервис.
Server-Side Discovery: API Gateway или балансировщик нагрузки управляет взаимодействием с реестром.


3. Load Balancer (Балансировщик нагрузки)


Балансировка нагрузки — важный компонент для распределения запросов между несколькими экземплярами одного микросервиса.

Она обеспечивает:
Распределение нагрузки: Запросы равномерно направляются на экземпляры.
Высокую доступность: Отказ одного экземпляра не влияет на работоспособность системы.
Масштабируемость: Добавление новых экземпляров происходит прозрачно.


Виды балансировки:
Client-Side Load Balancing:
Клиент решает, на какой экземпляр направить запрос.
Инструменты: Spring Cloud LoadBalancer, Ribbon.

Server-Side Load Balancing:
Балансировщик нагрузки (например, Nginx, AWS Elastic Load Balancer) решает, куда отправить запрос.

4. Configuration Management

Конфигурация микросервисов должна быть централизованной и управляемой. Для этого используется Configuration Management, который хранит настройки, такие как параметры подключения к базам данных, порты и ключи API.

Основные требования:
Централизованное хранилище конфигурации.
Поддержка профилей (например, dev, staging, production).
Безопасное хранение конфиденциальных данных (шифрование).


Spring Cloud Config:
Spring Cloud Config позволяет управлять конфигурацией через Git-репозиторий.

Пример конфигурации в Git:
# application.yml
database:
url: jdbc:postgresql://localhost:5432/mydb
username: user
password: secret


Клиентское приложение подключается к Config Server:

spring.config.import=configserver:http://localhost:8888


5. Centralized Logging (Централизованное логирование)


При распределённой архитектуре логи микросервисов должны быть централизованы, чтобы упрощать отладку и мониторинг.

Компоненты логирования

Логирование на уровне микросервиса:

Используются библиотеки логирования (Logback, SLF4J).
Структурированные логи (JSON) упрощают анализ.


Централизованный сбор логов:
Инструменты: ELK-стек (Elasticsearch, Logstash, Kibana), Graylog.

Трассировка запросов:
Инструменты: Spring Cloud Sleuth, Zipkin.

6. Monitoring and Metrics (Мониторинг и метрики)

Мониторинг микросервисов помогает следить за их производительностью и выявлять проблемы. Это достигается с помощью сбора метрик и создания дашбордов.


Популярные инструменты:
Prometheus: Для сбора и анализа метрик.
Grafana: Для визуализации данных.
Spring Actuator: Для сбора метрик и состояния приложения.


#Java #Training #Spring #Components_Microservices
7. Circuit Breaker (Схема предохранителя)

Circuit Breaker защищает систему от cascade failures (каскадных отказов). Если один сервис недоступен, Circuit Breaker предотвращает повторные запросы и возвращает заранее определённый ответ.


Инструменты:
Resilience4j: Легковесная библиотека для обработки отказов.
Hystrix (устаревший): Предыдущий стандарт для реализации Circuit Breaker.


8. Event-Driven Architecture

Микросервисы могут взаимодействовать друг с другом асинхронно через события. Это полезно для реализации реактивных и loosely coupled систем.

Основные инструменты:
Apache Kafka: Распределённая потоковая платформа.
RabbitMQ: Брокер сообщений для обмена событиями.
Spring Cloud Stream: Абстракция для работы с системами обмена сообщениями.


Пример работы с Kafka

Отправка события:
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;

public void publishEvent(String topic, String message) {
kafkaTemplate.send(topic, message);
}


Получение события:
@KafkaListener(topics = "user-events", groupId = "group_id")
public void consume(String message) {
System.out.println("Received message: " + message);
}


9. Database Per Service (База данных для каждого сервиса)

В микросервисной архитектуре каждый сервис имеет собственную базу данных, чтобы избежать проблем с согласованностью данных и зависимостями.

Собственная база данных:
Каждый сервис использует отдельную базу (например, PostgreSQL для одного сервиса и MongoDB для другого).

Общая база с логической изоляцией:
Используются отдельные схемы базы данных.

10. Security Components

Безопасность в микросервисах сложнее, так как система состоит из множества независимых компонентов.

Подходы к безопасности


Authentication and Authorization:
Использование OAuth2 и OpenID Connect.
Spring Security + Keycloak или Auth0.


Secure Communication:
Шифрование трафика с помощью TLS/SSL.

API Security:
Валидация входящих запросов.
Ограничение доступа с использованием JWT (JSON Web Tokens).


#Java #Training #Spring #Components_Microservices
Всем привет!🖐

Ну раз большинство проголосовало за продолжение - так тому и быть)💪

Давайте сегодня продолжим!

Как всегда в 16:00 по МСК я буду лайкодить для Вас, приходите🫡
Введение в тестирование в Spring

Основы тестирования

Тестирование — это ключевой этап разработки, позволяющий удостовериться в правильности работы приложения. Без качественных тестов сложно поддерживать стабильность приложения, особенно с ростом функциональности. Рассмотрим основные понятия тестирования и их важность.

Виды тестирования

Юнит-тесты (Unit Tests):
Тестируют отдельные модули или компоненты приложения, такие как методы или классы.
Основная цель — проверка логики отдельно взятого компонента.
Пример: Проверка корректности метода расчёта.


Интеграционные тесты (Integration Tests):
Проверяют взаимодействие между различными компонентами приложения (например, контроллер ↔️ сервис ↔️ база данных).
Цель — убедиться, что компоненты работают совместно.


Функциональные тесты (Functional Tests):
Проверяют функциональность приложения с точки зрения пользователя.
Пример: Убедиться, что REST API возвращает ожидаемые данные.


Энд-ту-энд тесты (E2E Tests):
Покрывают весь процесс использования приложения, от начала до конца.
Используются для проверки полного пользовательского сценария.


Пирамида тестирования

В идеале, проект должен иметь:
Много юнит-тестов.
Умеренное количество интеграционных тестов.
Немного функциональных и E2E тестов.
Это помогает балансировать между скоростью тестирования и его надежностью.


Инструменты тестирования

Spring предоставляет мощный набор инструментов для тестирования. Ключевые библиотеки и фреймворки:

JUnit 5 (Jupiter):
Основной фреймворк для написания юнит-тестов в Java.
Обеспечивает аннотации для написания и управления тестами.


Mockito:
Используется для создания моков (объектов-заглушек), которые эмулируют поведение реальных зависимостей.
Упрощает тестирование компонентов с зависимостями.


Spring Test:
Расширяет возможности JUnit и Mockito для работы с контекстом Spring.
Позволяет тестировать компоненты Spring (например, бины, репозитории, сервисы) в интеграционном контексте.


#Java #Training #Spring #Testing
Что выведет код

public class Task251224_1 {
public static void main(String[] args) {
int sum = 0;
for (int i = 1; i <= 5; i++) {
sum += i;
}
System.out.println(sum);
}
}


#Tasks
Варианты ответа:
Anonymous Quiz
11%
0
8%
5
3%
10
69%
15
8%
java