Java学习笔记

个人技术成长之路

微服务架构简介

微服务架构是一种将应用程序构建为一系列小型服务的方法,每个服务运行在自己的进程中,通过轻量级机制(通常是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为例)的基本步骤:

  1. 安装Kubernetes集群
  2. 安装Istio
  3. 部署应用程序并注入Envoy代理
  4. 配置流量规则、安全策略和监控
# 安装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之前,应该评估其是否适合你的项目规模和团队能力。