Spring Boot微服务架构详解
文章目录
- 1. 微服务架构概述
- 1.1 微服务架构特点
- 1.2 微服务技术栈
- 1.3 核心依赖
- 2. 服务注册与发现
- 2.1 Eureka服务端
- 2.2 Eureka客户端
- 3. 服务间通信
- 3.1 OpenFeign客户端
- 3.2 服务调用
- 4. 服务网关
- 4.1 Gateway配置
- 4.2 自定义过滤器
- 5. 配置中心
- 5.1 Config Server
- 5.2 Config Client
- 6. 熔断器
- 6.1 Resilience4j配置
- 6.2 熔断器使用
- 7. 消息队列
- 7.1 RabbitMQ配置
- 7.2 消息生产者
- 7.3 消息消费者
- 8. 分布式追踪
- 8.1 Sleuth配置
- 8.2 追踪配置
- 9. 服务监控
- 9.1 Actuator配置
- 9.2 健康检查
- 10. 容器化部署
- 10.1 Dockerfile
- 10.2 Docker Compose
- 11. 总结
1. 微服务架构概述
微服务架构是一种将单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,并通过轻量级机制(通常是HTTP API)进行通信。Spring Boot为微服务架构提供了完整的解决方案。
1.1 微服务架构特点
- 服务拆分:按业务功能拆分服务
- 独立部署:每个服务独立部署和扩展
- 技术多样性:不同服务可以使用不同技术栈
- 容错性:单个服务故障不影响整体系统
- 可扩展性:可以独立扩展高负载服务
1.2 微服务技术栈
- Spring Cloud:微服务开发框架
- 服务注册与发现:Eureka、Consul、Nacos
- 配置中心:Spring Cloud Config、Nacos
- 服务网关:Spring Cloud Gateway、Zuul
- 负载均衡:Ribbon、LoadBalancer
- 熔断器:Hystrix、Resilience4j
- 消息队列:RabbitMQ、Kafka
1.3 核心依赖
<dependencies><!-- Spring Boot Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Cloud Starter --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter</artifactId></dependency><!-- Eureka Client --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!-- Spring Cloud Config Client --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId></dependency><!-- Spring Cloud Gateway --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!-- OpenFeign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- Resilience4j --><dependency><groupId>io.github.resilience4j</groupId><artifactId>resilience4j-spring-boot2</artifactId></dependency>
</dependencies>
2. 服务注册与发现
2.1 Eureka服务端
package com.example.eureka;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {public static void main(String[] args) {SpringApplication.run(EurekaServerApplication.class, args);}
}
application.yml
server:port: 8761eureka:instance:hostname: localhostclient:register-with-eureka: falsefetch-registry: falseservice-url:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
2.2 Eureka客户端
package com.example.userservice;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication
@EnableEurekaClient
public class UserServiceApplication {public static void main(String[] args) {SpringApplication.run(UserServiceApplication.class, args);}
}
application.yml
server:port: 8081spring:application:name: user-serviceeureka:client:service-url:defaultZone: http://localhost:8761/eureka/instance:prefer-ip-address: true
3. 服务间通信
3.1 OpenFeign客户端
package com.example.userservice.client;import com.example.userservice.dto.OrderDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.List;@FeignClient(name = "order-service")
public interface OrderServiceClient {@GetMapping("/orders/user/{userId}")List<OrderDto> getUserOrders(@PathVariable Long userId);@GetMapping("/orders/{orderId}")OrderDto getOrderById(@PathVariable Long orderId);
}
3.2 服务调用
package com.example.userservice.service;import com.example.userservice.client.OrderServiceClient;
import com.example.userservice.dto.OrderDto;
import com.example.userservice.dto.UserDto;
import com.example.userservice.entity.User;
import com.example.userservice.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;@Service
public class UserService {@Autowiredprivate UserRepository userRepository;@Autowiredprivate OrderServiceClient orderServiceClient;public UserDto getUserWithOrders(Long userId) {User user = userRepository.findById(userId).orElseThrow(() -> new RuntimeException("用户不存在"));List<OrderDto> orders = orderServiceClient.getUserOrders(userId);UserDto userDto = new UserDto();userDto.setId(user.getId());userDto.setUsername(user.getUsername());userDto.setEmail(user.getEmail());userDto.setOrders(orders);return userDto;}
}
4. 服务网关
4.1 Gateway配置
package com.example.gateway;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication
@EnableEurekaClient
public class GatewayApplication {public static void main(String[] args) {SpringApplication.run(GatewayApplication.class, args);}
}
application.yml
server:port: 8080spring:application:name: api-gatewaycloud:gateway:routes:- id: user-serviceuri: lb://user-servicepredicates:- Path=/api/users/**filters:- StripPrefix=2- id: order-serviceuri: lb://order-servicepredicates:- Path=/api/orders/**filters:- StripPrefix=2globalcors:cors-configurations:'[/**]':allowedOrigins: "*"allowedMethods: "*"allowedHeaders: "*"eureka:client:service-url:defaultZone: http://localhost:8761/eureka/
4.2 自定义过滤器
package com.example.gateway.filter;import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalGatewayFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;@Component
public class AuthFilter implements GlobalGatewayFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String token = exchange.getRequest().getHeaders().getFirst("Authorization");if (token == null || !token.startsWith("Bearer ")) {exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}// 验证token逻辑if (!isValidToken(token)) {exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}return chain.filter(exchange);}private boolean isValidToken(String token) {// 实现token验证逻辑return true;}@Overridepublic int getOrder() {return -1;}
}
5. 配置中心
5.1 Config Server
package com.example.configserver;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {public static void main(String[] args) {SpringApplication.run(ConfigServerApplication.class, args);}
}
application.yml
server:port: 8888spring:cloud:config:server:git:uri: https://github.com/your-repo/config-reposearch-paths: config
5.2 Config Client
# bootstrap.yml
spring:application:name: user-servicecloud:config:uri: http://localhost:8888fail-fast: true
6. 熔断器
6.1 Resilience4j配置
resilience4j:circuitbreaker:instances:orderService:failure-rate-threshold: 50wait-duration-in-open-state: 30ssliding-window-size: 10minimum-number-of-calls: 5retry:instances:orderService:max-attempts: 3wait-duration: 1stimelimiter:instances:orderService:timeout-duration: 3s
6.2 熔断器使用
package com.example.userservice.service;import com.example.userservice.client.OrderServiceClient;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.retry.annotation.Retry;
import io.github.resilience4j.timelimiter.annotation.TimeLimiter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.CompletableFuture;@Service
public class ResilientUserService {@Autowiredprivate OrderServiceClient orderServiceClient;@CircuitBreaker(name = "orderService", fallbackMethod = "getUserOrdersFallback")@Retry(name = "orderService")@TimeLimiter(name = "orderService")public CompletableFuture<List<OrderDto>> getUserOrders(Long userId) {return CompletableFuture.supplyAsync(() -> orderServiceClient.getUserOrders(userId));}public CompletableFuture<List<OrderDto>> getUserOrdersFallback(Long userId, Exception ex) {// 返回默认订单或缓存数据return CompletableFuture.completedFuture(List.of());}
}
7. 消息队列
7.1 RabbitMQ配置
spring:rabbitmq:host: localhostport: 5672username: guestpassword: guestvirtual-host: /
7.2 消息生产者
package com.example.userservice.messaging;import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class UserEventPublisher {@Autowiredprivate RabbitTemplate rabbitTemplate;public void publishUserCreatedEvent(UserCreatedEvent event) {rabbitTemplate.convertAndSend("user.exchange", "user.created", event);}public void publishUserUpdatedEvent(UserUpdatedEvent event) {rabbitTemplate.convertAndSend("user.exchange", "user.updated", event);}
}
7.3 消息消费者
package com.example.orderservice.messaging;import com.example.orderservice.service.OrderService;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class UserEventConsumer {@Autowiredprivate OrderService orderService;@RabbitListener(queues = "user.created.queue")public void handleUserCreated(UserCreatedEvent event) {// 处理用户创建事件orderService.createUserProfile(event.getUserId());}@RabbitListener(queues = "user.updated.queue")public void handleUserUpdated(UserUpdatedEvent event) {// 处理用户更新事件orderService.updateUserProfile(event.getUserId(), event.getUserData());}
}
8. 分布式追踪
8.1 Sleuth配置
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
8.2 追踪配置
spring:sleuth:sampler:probability: 1.0zipkin:base-url: http://localhost:9411
9. 服务监控
9.1 Actuator配置
management:endpoints:web:exposure:include: "*"endpoint:health:show-details: alwaysmetrics:export:prometheus:enabled: true
9.2 健康检查
package com.example.userservice.health;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;@Component
public class DatabaseHealthIndicator implements HealthIndicator {@Autowiredprivate UserRepository userRepository;@Overridepublic Health health() {try {userRepository.count();return Health.up().withDetail("database", "Available").build();} catch (Exception e) {return Health.down().withDetail("database", "Unavailable").withDetail("error", e.getMessage()).build();}}
}
10. 容器化部署
10.1 Dockerfile
FROM openjdk:17-jdk-slimWORKDIR /appCOPY target/user-service-1.0.0.jar app.jarEXPOSE 8081ENTRYPOINT ["java", "-jar", "app.jar"]
10.2 Docker Compose
version: '3.8'services:eureka-server:image: eureka-server:latestports:- "8761:8761"environment:- SPRING_PROFILES_ACTIVE=dockeruser-service:image: user-service:latestports:- "8081:8081"environment:- SPRING_PROFILES_ACTIVE=docker- EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://eureka-server:8761/eureka/depends_on:- eureka-serverorder-service:image: order-service:latestports:- "8082:8082"environment:- SPRING_PROFILES_ACTIVE=docker- EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://eureka-server:8761/eureka/depends_on:- eureka-serverapi-gateway:image: api-gateway:latestports:- "8080:8080"environment:- SPRING_PROFILES_ACTIVE=docker- EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://eureka-server:8761/eureka/depends_on:- eureka-server
11. 总结
Spring Boot微服务架构提供了完整的微服务开发解决方案:
- 服务注册与发现:Eureka、Consul等服务注册中心
- 服务间通信:OpenFeign、RestTemplate等通信方式
- 服务网关:Spring Cloud Gateway统一入口
- 配置中心:Spring Cloud Config集中配置管理
- 熔断器:Resilience4j、Hystrix容错处理
- 消息队列:RabbitMQ、Kafka异步通信
- 分布式追踪:Sleuth、Zipkin链路追踪
- 服务监控:Actuator、Micrometer监控
- 容器化部署:Docker、Kubernetes部署
通过合理使用这些技术,可以构建出高可用、可扩展的微服务系统。