微服务架构简介
微服务架构是一种将应用程序构建为一系列小型服务的方法,每个服务运行在自己的进程中,通过轻量级机制(通常是HTTP API)通信。
微服务特点
- 单一职责:每个服务专注于解决特定业务领域的问题
- 独立部署:服务可以独立开发、测试和部署
- 技术多样性:不同服务可以使用不同的技术栈
- 分布式数据管理:每个服务可以有自己的数据存储
- 弹性设计:服务故障不会导致整个系统崩溃
微服务与单体架构对比
特性 | 单体架构 | 微服务架构 |
---|---|---|
开发复杂度 | 低 | 高 |
部署 | 整体部署 | 独立部署 |
扩展性 | 整体扩展 | 按需扩展 |
技术栈 | 单一技术栈 | 多样化技术栈 |
故障隔离 | 差 | 好 |
注意:微服务架构不是银弹,它增加了系统的复杂性,引入了分布式系统的挑战,如网络延迟、消息可靠性、一致性等问题。在选择架构时,应根据业务需求和团队能力进行权衡。
Spring Cloud
Spring Cloud是一系列框架的集合,提供了在分布式系统中快速构建微服务的工具,包括配置管理、服务发现、断路器、智能路由、微代理、控制总线等。
Spring Cloud组件
- Spring Cloud Netflix:集成了Netflix OSS组件,如Eureka、Hystrix、Zuul等
- Spring Cloud Config:提供服务器和客户端支持的外部化配置
- Spring Cloud Bus:用于将服务和服务实例与分布式消息系统链接
- Spring Cloud Sleuth:分布式追踪解决方案
- Spring Cloud Gateway:API网关服务
Spring Cloud项目结构
一个典型的Spring Cloud项目通常包含以下模块:
my-microservices/
├── eureka-server/ # 服务注册中心
├── config-server/ # 配置中心
├── gateway-service/ # API网关
├── user-service/ # 用户服务
├── product-service/ # 产品服务
├── order-service/ # 订单服务
└── common/ # 公共模块
服务注册与发现
服务注册与发现是微服务架构中的关键组件,它允许服务动态地注册自己并发现其他服务的位置。
Eureka服务注册中心
Eureka是Netflix开发的服务发现框架,Spring Cloud集成了Eureka作为服务注册与发现的解决方案。
Eureka Server配置
// 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
// 启动类
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
// application.yml
server:
port: 8761
eureka:
client:
registerWithEureka: false
fetchRegistry: false
server:
waitTimeInMsWhenSyncEmpty: 0
Eureka Client配置
// 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
// 启动类
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
// application.yml
spring:
application:
name: user-service
server:
port: 8081
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
服务发现
服务可以使用DiscoveryClient或负载均衡的RestTemplate来发现和调用其他服务。
// 使用DiscoveryClient
@RestController
public class UserController {
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/service-instances")
public List serviceInstances() {
return discoveryClient.getInstances("product-service");
}
}
// 使用负载均衡的RestTemplate
@Configuration
public class AppConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
@Service
public class ProductService {
@Autowired
private RestTemplate restTemplate;
public Product getProduct(Long id) {
return restTemplate.getForObject("http://product-service/products/" + id, Product.class);
}
}
API网关
API网关是微服务架构中的入口点,负责请求路由、组合、协议转换等功能。Spring Cloud提供了Spring Cloud Gateway和Zuul作为API网关的实现。
Spring Cloud Gateway
Spring Cloud Gateway是Spring Cloud的新一代API网关,基于Spring 5、Spring Boot 2和Project Reactor构建。
// 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
// application.yml
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/users/**
- id: product-service
uri: lb://product-service
predicates:
- Path=/products/**
filters:
- AddRequestHeader=X-Request-Source, gateway
网关功能
- 路由:将请求路由到不同的微服务
- 过滤:在请求前后执行过滤逻辑
- 认证授权:集中处理认证和授权
- 限流:保护微服务免受过多请求的影响
- 监控:收集请求和响应的统计信息
自定义过滤器
@Component
public class LoggingFilter implements GlobalFilter {
private static final Logger log = LoggerFactory.getLogger(LoggingFilter.class);
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("Path requested: {}", exchange.getRequest().getPath());
return chain.filter(exchange);
}
}
服务熔断与降级
在微服务架构中,服务之间的调用可能因为网络问题或服务不可用而失败。服务熔断和降级是处理这些故障的重要机制。
Resilience4j
Resilience4j是一个轻量级的容错库,灵感来自于Hystrix,但专为Java 8和函数式编程设计。
// 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
// 配置
resilience4j:
circuitbreaker:
instances:
productService:
registerHealthIndicator: true
slidingWindowSize: 10
minimumNumberOfCalls: 5
permittedNumberOfCallsInHalfOpenState: 3
automaticTransitionFromOpenToHalfOpenEnabled: true
waitDurationInOpenState: 5s
failureRateThreshold: 50
eventConsumerBufferSize: 10
// 使用
@Service
public class ProductService {
private final RestTemplate restTemplate;
private final CircuitBreakerFactory circuitBreakerFactory;
@Autowired
public ProductService(RestTemplate restTemplate, CircuitBreakerFactory circuitBreakerFactory) {
this.restTemplate = restTemplate;
this.circuitBreakerFactory = circuitBreakerFactory;
}
public Product getProduct(Long id) {
CircuitBreaker circuitBreaker = circuitBreakerFactory.create("productService");
return circuitBreaker.run(
() -> restTemplate.getForObject("http://product-service/products/" + id, Product.class),
throwable -> getDefaultProduct(id)
);
}
private Product getDefaultProduct(Long id) {
// 返回默认产品或从缓存中获取
return new Product(id, "Default Product", "This is a default product when service is down", 0.0);
}
}
服务降级策略
服务降级是在服务不可用时提供备选方案的策略,常见的降级策略包括:
- 返回缓存数据:使用之前缓存的数据
- 返回默认值:提供一个安全的默认响应
- 跳过非关键功能:暂时禁用非核心功能
- 延迟处理:将请求放入队列,稍后处理
Service Mesh
Service Mesh(服务网格)是处理服务间通信的专用基础设施层,负责在现代云原生应用中可靠地传递请求。
Service Mesh架构
Service Mesh通常由两部分组成:
- 数据平面:由与应用服务一起部署的轻量级网络代理(如Envoy)组成,负责处理服务间通信
- 控制平面:管理和配置代理,实现策略和收集遥测数据
Istio
Istio是一个开源的Service Mesh,提供了流量管理、安全性和可观察性等功能。
Istio功能
- 流量管理:控制服务间的流量和API调用
- 安全:提供服务间的认证、授权和加密
- 可观察性:提供服务行为的深入了解
Istio架构
// Istio架构组件
- Envoy:高性能代理,用于调解服务网格中所有服务的入站和出站流量
- Istiod:控制平面,提供服务发现、配置和证书管理
- Ingress/Egress Gateway:管理进入和离开服务网格的流量
Service Mesh与Spring Cloud对比
Service Mesh和Spring Cloud都是实现微服务架构的解决方案,但它们的实现方式不同:
- Spring Cloud:是一个库,需要在应用程序中引入依赖,与应用程序代码耦合
- Service Mesh:是一个基础设施层,与应用程序代码解耦,通过sidecar代理拦截和处理流量
提示:Service Mesh更适合多语言环境和对基础设施有更高控制需求的场景,而Spring Cloud更适合纯Java/Spring环境和快速开发。
Service Mesh入门指南
以下是开始使用Service Mesh(以Istio为例)的基本步骤:
- 安装Kubernetes集群
- 安装Istio
- 部署应用程序并注入Envoy代理
- 配置流量规则、安全策略和监控
# 安装Istio
$ curl -L https://istio.io/downloadIstio | sh -
$ cd istio-*
$ export PATH=$PWD/bin:$PATH
$ istioctl install --set profile=demo
# 为命名空间启用自动注入
$ kubectl label namespace default istio-injection=enabled
# 部署示例应用
$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
# 验证部署
$ kubectl get services
$ kubectl get pods
注意:Service Mesh引入了额外的复杂性和资源开销。在决定采用Service Mesh之前,应该评估其是否适合你的项目规模和团队能力。