Spring Cloud组件太多,太难学?手把手带你走完整个流程

412 阅读9分钟

引言

毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,它基于 Spring Boot 构建,充分利用了 Spring Boot 的便捷开发特性,如自动配置和起步依赖等,这次我们就基于此设计一个阅读类微服务项目,带你走完整个流程。

微服务整体流程

首先, 我们先回顾一下当一个API来调用时,一个完整的微服务会经过哪些步骤。

  1. 服务注册与发现(以 Eureka为例)
  • 各个微服务在启动时,会将自身的信息(如服务名称、实例地址、端口等)发送给服务发现组件。微服务作为 Eureka Client,会向 Eureka Server 发送一个包含自身信息的注册请求,Eureka Server 接收到注册请求后,会将该微服务的信息存储在其注册表中。
  1. 网关控制(以 Spring Cloud Gateway 为例)
  • 所有外部请求首先进入 Spring Cloud Gateway。Gateway 会根据配置的路由规则,将请求路由到相应的微服务上。在路由请求之前,Gateway 可以对请求进行一系列的前置处理,如身份验证、权限检查等。只有经过前置处理且符合要求的请求才会被路由到相应的微服务进行后续处理。
  1. 断路器保障(以 Hystrix 为例)
  • Hystrix 会监控服务调用的情况,包括调用的成功率、响应时间等指标。当某个服务的失败率达到一定阈值(如 50%)或者响应时间超过设定值(如 1000 毫秒)时,Hystrix 会触发断路器机制。
  1. 服务调用(以 OpenFeign 为例)
  • 服务间通信方式,调用方微服务使用 OpenFeign 来定义一个接口,该接口声明了调用被调用方微服务的方法。OpenFeign 会根据接口的定义自动生成实现类。当调用方微服务需要调用其他微服务时,它首先会从服务发现组件(如 Eureka)获取被调用方微服务的实例列表。然后根据负载均衡策略(如轮询、随机等)选择其中一个实例进行调用。
  1. 配置管理(以 Spring Cloud Config 为例)
  • 配置文件可以存储在多种介质中,如 Git 仓库、本地文件系统等。Spring Cloud Config Server 负责从这些存储介质中获取配置文件。 各个微服务作为 Config Client,会在启动时向 Config Server 请求获取自己所需的配置信息。Config Server 根据微服务的名称和配置文件的规则,将相应的配置信息发送给微服务。

image.png

阅读类微服务实现

主体流程:

这里使用Nacos充当服务注册中心和配置中心,Gateway服务网关,流量入口、权限验证,Hystrix服务容错(限流、降级、熔断),OpenFeign提供微服务的公用客户端,服务就只有一个简单的图书查询服务,来简要描述其中的实现过程。 image.png

模块

模块描述
book-query-service主要为了示例,就只有这一个功能服务模块
common公共模块,通用工具类等
gateway服务网关,权限验证,流量控制等
openFeignFeign客户端

image.png

服务注册发现与配置中心 - Nacos

注册与发现

Nacos 是一个集服务注册中心和配置中心于一体的开源组件。图书查询服务作为一个微服务,在启动时会将自身的信息发送给 Nacos。它会向 Nacos 发送一个包含服务名称(“book-query-service”)、实例地址(如 IP 地址和端口号)等信息的注册请求。使用 Spring Cloud 和 Nacos 进行服务注册时的代码:

import org.springframework.boot.SpringBootApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class BookQueryServiceApplication {
    public static void main(String[] args) {
        SpringBootApplication.run(BookQueryServiceApplication.class, args);
    }
}

在上述代码中,@EnableDiscoveryClient注解用于启用服务发现功能,使得图书查询服务能够在启动时向 Nacos 注册自身信息。

心跳维护机制

图书查询服务会定期(例如每隔 5 秒)向 Nacos 发送心跳包。心跳包用于告知 Nacos 该服务仍然存活。如果Nacos 在一定时间内(如 15 秒)没有收到图书查询服务的心跳包,它会将该服务从服务注册表中移除,标记为下线状态。这样可以确保其他微服务不会调用到已经不可用的实例。

配置管理

图书查询服务的配置文件可以存储在 Nacos 中。例如,配置文件可能包含数据库连接信息、查询参数设置等内容。当图书查询服务启动时,它会作为一个 Nacos 配置客户端向 Nacos 请求获取自己所需的配置信息。Nacos 会根据服务名称和配置文件的规则,将相应的配置信息发送给图书查询服务。以下是配置客户端的代码:

import org.springframework.boot.SpringBootApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.context.config.annotation.EnableConfigServer;

@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigServer
public class BookQueryServiceApplication {
    public static void main(String[] args) {
        SpringBootApplication.run(BookQueryServiceApplication.class, args);
    }
}

@EnableConfigServer注解用于启用配置服务功能,使得图书查询服务能够从 Nacos 获取配置信息。

动态配置更新

当配置文件中的某些参数需要修改时,例如数据库连接地址发生变化,我们可以在 Nacos 中更新配置文件。Nacos 会将配置更新的消息推送给图书查询服务。图书查询服务接收到更新消息后,会重新加载配置信息,确保服务能够按照新的配置运行,而无需重新启动服务。
最后在服务的yml配置文件配置Nacos服务地址:

spring:
  # 服务逻辑名称
  application:
    name: book-query-service

  cloud:
    nacos:
      # 配置中心
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yml
        refresh: true
        shared-dataids: bookQueryService.yml
        namespace: 3m249b4c-d34d-4e86-9e39-d4626db45411

      # 注册中心
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: 3m249b4c-d34d-4e86-9e39-d4626db45411

网关 - Gateway

请求路由

所有外部请求首先进入 Gateway。假设外部请求是查询某本图书的信息,请求的 URL 可能包含特定的路径和参数。Gateway 会根据配置的路由规则来判断该请求应该被路由到图书查询服务。例如,如果请求路径中包含“/book/query” 这样的关键字,Gateway 会将请求路由到图书查询服务。以下是 Gateway 路由配置的代码:

spring:
  cloud:
    gateway:
      routes:
      - id: book-query-route
        uri: lb://book-query-service
        predicates:
        - Path=/book/query/**

在上面代码中,uri: lb://book-query-service表示将请求路由到名为book-query-service的服务,predicates中的Path=/book/query/**表示请求路径需要满足/book/query开头的条件。

前置处理

在路由请求之前,Gateway 可以对请求进行一系列的前置处理。例如,它可以进行身份验证,检查请求中是否包含有效的用户身份信息(如 JWT 令牌)。如果身份验证通过,Gateway 才会将请求路由到图书查询服务。如果身份验证失败,Gateway 可以返回一个错误响应,告知用户身份验证未通过。

服务调用 - OpenFeign

接口定义

在需要调用图书查询服务的其他微服务中(假设存在一个评论微服务需要获取图书信息来展示相关评论),会使用 OpenFeign 来定义一个接口。例如,定义一个接口名为 “BookQueryClient”,其中包含一个方法 “getBookById”,该方法接受一个图书 ID 作为参数,用于获取指定图书的信息。以下是 OpenFeign 接口定义的关键代码:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(name = "book-query-service")
public interface BookQueryClient {
    @GetMapping("/book/{id}")
    Book getBookById(@PathVariable("id") Long id);
}

在以上代码中,@FeignClient(name = "book-query-service")注解用于指定要调用的服务名称,@GetMapping("/book/{id}")Book getBookById(@PathVariable("id") Long id)用于定义获取图书信息的方法。

服务发现与调用

当评论微服务需要调用图书查询服务时,它首先会从 Nacos 获取图书查询服务的实例列表。然后根据负载均衡策略(如轮询)选择其中一个实例。OpenFeign 会根据接口定义自动生成实现类,并将请求发送到所选的图书查询服务实例上,实现服务之间的调用。

断路器 - Hystrix

监控与判断

Hystrix 会监控图书查询服务的调用情况。例如,它会统计调用的成功率、响应时间等指标。当图书查询服务的失败率达到一定阈值(如 20%)或者响应时间超过设定值(如 1000 毫秒)时,Hystrix 会触发断路器机制。以下是 Hystrix 配置的代码:

hystrix:
  command:
    default:
      circuitBreaker:
        enabled: true
        errorThresholdPercentage: 20
        sleepWindowInMilliseconds: 5000
        requestVolumeThreshold: 10

在上述代码中,circuitBreaker中的enabled: true表示启用断路器机制,errorThresholdPercentage: 20表示失败率阈值为 20%,sleepWindowInMilliseconds: 5000表示熔断时间为 5000 毫秒,requestVolumeThreshold: 10表示请求数量阈值为 10。

断路器机制

一旦断路器被触发,后续对该服务的请求会直接进入 Hystrix 的 fallback 逻辑。例如,fallback 逻辑可能会返回一个预设的响应(如一个默认的图书信息表示无法获取真实信息),从而保护了整个系统免受单个服务故障的影响。以下是 Hystrix fallback 方法的代码:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(name = "book-query-service", fallback = BookQueryFallback.class)
public interface BookQueryClient {
    @GetMapping("/book/{id}")
    Book getBookById(@PathVariable("id") Long id);
}

class BookQueryFallback implements BookQueryClient {
    @Override
    public Book getBookById(Long id) {
        // 返回一个默认的图书信息
        return new Book("默认图书名称", "默认作者", "默认简介");
    }
}

在上面代码中,@FeignClient(name = "book-query-service", fallback = BookQueryFallback.class)表示当服务调用失败时,会进入BookQueryFallback类中的方法,BookQueryFallback类实现了BookQueryClient接口,并重写了getBookById方法,返回一个默认的图书信息。

结尾

OK,以上就是基于 Spring Cloud 的阅读类微服务系统中图书查询服务的实现过程,包括服务注册与发现、配置管理、网关、服务调用和断路器等组件的应用,因为只设计到组件的基础部署应用,并没有什么实际的业务处理,这里就不贴完整代码了😜。