Микросервисная архитектура
Микросервисы — это архитектурный стиль, при котором приложение разбивается на набор небольших, независимых сервисов. Каждый сервис отвечает за свою бизнес-функцию и взаимодействует через API.
▸Преимущества
▸Недостатки
Spring Cloud: компоненты
▸Service Discovery (Eureka)
1// Eureka Server2@SpringBootApplication3@EnableEurekaServer4public class DiscoveryServerApplication {5 public static void main(String[] args) {6 SpringApplication.run(DiscoveryServerApplication.class, args);7 }8}910// Eureka Client11@SpringBootApplication12@EnableDiscoveryClient13public class UserServiceApplication {14 public static void main(String[] args) {15 SpringApplication.run(UserServiceApplication.class, args);16 }17}
▸Config Server
1// Config Server2@SpringBootApplication3@EnableConfigServer4public class ConfigServerApplication {5 public static void main(String[] args) {6 SpringApplication.run(ConfigServerApplication.class, args);7 }8}910// application.yml для Config Server11spring:12 cloud:13 config:14 server:15 git:16 uri: https://github.com/config-repo17 default-label: main
▸API Gateway
1@SpringBootApplication2@EnableDiscoveryClient3public class GatewayApplication {4 public static void main(String[] args) {5 SpringApplication.run(GatewayApplication.class, args);6 }7}89// application.yml10spring:11 cloud:12 gateway:13 routes:14 - id: user-service15 uri: lb://user-service16 predicates:17 - Path=/api/users/**18 filters:19 - StripPrefix=12021 - id: order-service22 uri: lb://order-service23 predicates:24 - Path=/api/orders/**25 filters:26 - StripPrefix=1
Circuit Breaker (Resilience4j)
▸Настройка
1@Service2@RequiredArgsConstructor3public class OrderService {45 private final UserServiceClient userClient;67 @CircuitBreaker(name = "userService", fallbackMethod = "getUserFallback")8 public UserDto getUser(Long userId) {9 return userClient.getUser(userId);10 }1112 public UserDto getUserFallback(Long userId, Exception ex) {13 return new UserDto(userId, "Unknown", "fallback@example.com");14 }15}
▸Конфигурация
1resilience4j:2 circuitbreaker:3 instances:4 userService:5 slidingWindowSize: 106 failureRateThreshold: 507 waitDurationInOpenState: 10s8 permittedNumberOfCallsInHalfOpenState: 3
Межсервисное взаимодействие
▸REST с OpenFeign
1@FeignClient(name = "user-service")2public interface UserServiceClient {34 @GetMapping("/api/users/{id}")5 UserDto getUser(@PathVariable Long id);67 @PostMapping("/api/users")8 UserDto createUser(@RequestBody CreateUserRequest request);9}
▸Message Broker (Kafka)
1// Producer2@Service3@RequiredArgsConstructor4public class EventPublisher {5 private final KafkaTemplate<String, Object> kafkaTemplate;67 public void publishOrderCreated(OrderCreatedEvent event) {8 kafkaTemplate.send("order-events", event);9 }10}1112// Consumer13@Service14public class OrderEventHandler {1516 @KafkaListener(topics = "order-events", groupId = "inventory-service")17 public void handleOrderCreated(OrderCreatedEvent event) {18 // Обработка события19 inventoryService.reserveItems(event.getItems());20 }21}
Централизованное управление логами
▸ELK Stack интеграция
1# logback-spring.xml2<configuration>3 <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">4 <destination>logstash:5000</destination>5 <encoder class="net.logstash.logback.encoder.LogstashEncoder"/>6 </appender>78 <root level="INFO">9 <appender-ref ref="LOGSTASH"/>10 </root>11</configuration>
Мониторинг
▸Spring Boot Actuator
1management:2 endpoints:3 web:4 exposure:5 include: health,info,metrics,prometheus6 metrics:7 export:8 prometheus:9 enabled: true10`istributed-tracing11### Distributed Tracing с Micrometer Tracing
// Автоматическая трассировка через Sleuth/Micrometer
@GetMapping("/api/orders")
public List
// Каждый запрос автоматически получает trace ID
return orderService.getAllOrders();
}
12## Паттерны проектирования34### Saga Pattern
// Оркестрация через Saga
@Service
public class OrderSaga {
@SagaStep(order = 1)
public void reserveInventory(Order order) {
inventoryClient.reserve(order.getItems());
}
@SagaStep(order = 2, compensating = true)
public void releaseInventory(Order order) {
inventoryClient.release(order.getItems());
}
}
12### API Composition
@RestController
@RequestMapping("/api/composite")
@RequiredArgsConstructor
public class CompositeController {
private final UserServiceClient userClient;
private final OrderServiceClient orderClient;
@GetMapping("/users/{id}")
public UserComposite getUserComposite(@PathVariable Long id) {
UserDto user = userClient.getUser(id);
List
return new UserComposite(user, orders);
}
}