自学内容网 自学内容网

【热门主题】000063 Spring Cloud 微服务全攻略:从基础到实战

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕

共同探索软件研发!敬请关注【宝码香车】
关注描述

csdngif标识


📚📗📕📘📖🕮💡📝🗂️✍️🛠️💻🚀🎉🏗️🌐🖼️🔗📊👉🔖⚠️🌟🔐⬇️·正文开始⬇️·🎥😊🎓📩😺🌈🤝🤖📜📋🔍✅🧰❓📄📢📈 🙋0️⃣1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣8️⃣9️⃣🔟🆗*️⃣#️⃣

【热门主题】000063 Spring Cloud 微服务全攻略:从基础到实战

📚一、Spring Cloud 简介

Spring Cloud 是一套用于构建微服务架构应用的 Java 框架,通过封装微服务设计模式,提供众多功能和工具,简化了微服务开发过程。

Spring Cloud 利用 Spring Boot 的开发便利性,巧妙地简化了分布式系统基础设施的开发。它将各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过 Spring Boot 风格进行再封装,屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

Spring Cloud 的起源与发展

随着互联网的快速发展,软件系统的规模和复杂性不断增加,传统的单体架构已经难以满足需求。微服务架构应运而生,它将一个大型的应用程序拆分成多个小型的、独立的服务,每个服务都可以独立部署、扩展和维护。Spring Cloud 正是在这样的背景下诞生的,它基于 Spring Boot 构建,为微服务架构提供了一站式的解决方案。

📘Spring Cloud 的特点

耦合度低:各个微服务之间相互独立,不会影响其他模块的开发。
降低团队成本:可以并行开发,不用关注其他人的开发方式,专注于自己的任务。
配置简单:基本用注解就能实现,无需使用过多的配置文件。
跨平台性:微服务可以用任何一种语言开发。
灵活的数据库选择:每个微服务可以有自己独立的数据库,也可以使用公共的数据库。
专注后端开发:直接写后端代码,不用关注前端开发,通过组件进行服务通信。

📘Spring Cloud 的优势与不足

优势:

对于想研究微服务架构的同学来说,学习 Spring Cloud 是一个不错的选择。它是一套非常完善的分布式框架,目前很多企业开始采用微服务架构,Spring Cloud 的优势显而易见。
Spring Cloud 提供了一系列框架的有序集合,如服务发现注册、配置中心、智能路由、消息总线、负载均衡、断路器、数据监控等功能,可以用 Spring Boot 的开发风格做到一键启动和部署。

不足:

部署比较麻烦,给运维工程师带来一定的挑战。
针对数据的管理比较麻烦,因为微服务可以每个微服务使用一个数据库。
系统集成测试比较麻烦。
性能的监控比较麻烦,最好开发一个大屏监控系统。
Spring Cloud 与 Spring Boot 的关系
Spring Boot 专注于快速方便的开发单个个体微服务,而 Spring Cloud 是关注全局的微服务协调整理治理框架。Spring Boot 可以离开 Spring Cloud 独立使用开发项目,但是 Spring Cloud 离不开 Spring Boot,属于依赖的关系。
Spring Cloud 的版本对应关系
Spring Cloud Version SpringBoot Version
Hoxton 2.2.x
Greenwich 2.1.x
Finchley 2.0.x
Edgware 1.5.x
Dalston 1.5.x
Spring Cloud 的组成
Spring Cloud 由众多框架组成,其中开发中最重要的几个框架包括:
Spring Cloud Eureka:服务注册与发现。
Spring Cloud Zuul:服务网关。
Spring Cloud Ribbon:客户端负载均衡。
Spring Cloud Feign:声明性的 Web 服务客户端。
Spring Cloud Hystrix:断路器。
Spring Cloud Config:分布式统一配置管理等。
使用 Spring Boot 开发分布式微服务面临的问题
与分布式系统相关的复杂性,包括网络问题、延迟开销、带宽问题、安全问题等。
服务发现问题,需要管理群集中的流程和服务如何查找和互相交谈,涉及服务目录的注册和查找。
冗余问题,分布式系统中的冗余管理。
负载平衡问题,改善跨多个计算资源的工作负荷。
性能问题,由于各种运营开销导致的性能问题。
Spring Cloud 和 Dubbo 的区别
服务调用方式:Dubbo 是 RPC,Spring Cloud 是 Rest Api。
注册中心:Dubbo 是 zookeeper,Spring Cloud 是 eureka,也可以是 zookeeper。
服务网关:Dubbo 本身没有实现,Spring Cloud 有 Zuul 等实现。

📚二、Spring Cloud 的核心组件

📘1. 服务发现(Eureka)

服务注册中心的作用:维护所有服务实例的信息。
在微服务架构中,由于服务数量众多,服务发现成为了关键组成部分。服务注册中心就像是一个服务的 “电话簿”,它维护着所有服务实例的信息,包括服务的 IP 地址、端口号、服务名称等。这样,当一个服务需要调用另一个服务时,它可以通过服务注册中心获取目标服务的位置信息,从而实现服务之间的通信。
服务提供者和消费者的注册与发现流程。
首先,服务提供者在启动时,会将自己的信息注册到服务注册中心。以 Spring Cloud Eureka 为例,服务提供者会在 pom.xml 文件中添加 spring-cloud-starter-netflix-eureka-client 依赖项,然后在主要应用类中启用 Eureka 客户端。最后,在 application.properties 文件中定义 Eureka 服务器的 URL,当此服务启动时,会向 Eureka 服务器注册自身。
对于服务消费者,它可以从服务注册中心查询服务提供者的网络地址。在使用 Spring 的 RestTemplate 和 @LoadBalanced 注解时,Eureka 和 Ribbon 将共同处理服务发现和负载均衡。@LoadBalanced 将集成 Ribbon 负载均衡器,当服务消费者使用该服务的逻辑名称而不是硬编码 URL 时,Eureka 和 Ribbon 会发现服务并负载均衡任何请求。

📘2. 负载均衡(Ribbon)

从服务发现组件获取可用服务实例列表。
Ribbon 是 Spring Cloud 中的负载均衡器,它从服务发现组件(如 Eureka)获取可用服务实例列表。在初始化时,LoadBalancerClient(RibbonLoadBalancerClient 是实现类)会通过 ILoadBalance(BaseLoadBalancer 是实现类)向 Eureka 注册中心获取服务注册列表,并且每 10 秒钟向 EurekaClient 发送一次 “ping”,来判断服务的可用性。如果服务的可用性发生了改变或者服务数量和之前的不一致,则从注册中心更新或者重新拉取。
支持的负载均衡策略及工作原理。
ILoadBalance 接口代表负载均衡器的操作,它有多种负载均衡策略的实现类。例如:
随机策略(RandomRule):从服务器中随机选择一个服务器。在 RandomRule 的 choose 方法中,通过随机 Random 对象,在所有服务实例数量中随机找一个服务的索引号,然后从上线的服务中获取对应的服务。
轮询策略(RoundRobinRule):每次都取下一个服务器。在 RoundRobinRule 的 choose 方法中,通过 incrementAndGetModulo 方法以线性轮询方式获取服务。在 incrementAndGetModulo 中,实际上在类中维护了一个原子性的 nextServerCyclicCounter 成员变量作为当前服务的索引号,每次在所有服务数量的限制下,将服务的索引号加 1,到达服务数量限制时再从头开始。
加权策略(WeightedResponseTimeRule):响应时间作为选取权重的负载均衡策略。其含义就是,响应时间越短的服务被选中的可能性大。它继承自 RoundRobinRule 类,开始的时候还没有权重列表,采用父类的轮询方式,有一个默认每 30 秒更新一次权重列表的定时任务,该定时任务会根据实例的响应时间来更新权重列表。
最佳可用策略(BestAvailableRule):用来选取最少并发量请求的服务器。

📘3. 断路器(Hystrix)

防止服务故障传播的机制。
在 Spring Cloud 微服务架构中,断路器(Hystrix)是一种用于处理分布式系统中服务间调用故障和延迟的机制。它通过隔离、熔断和降级等操作来防止单个服务的故障对整个系统造成灾难性的影响,避免出现雪崩效应。
熔断器的工作原理及监控指标。
服务调用隔离:
线程池隔离:Hystrix 为每个依赖的服务调用创建一个独立的线程池。当服务 A 调用服务 B 时,请求会在为服务 B 创建的线程池中执行。这种隔离方式的好处是,当某个服务出现故障,其对应的线程池被耗尽或者阻塞时,不会影响服务 A 对其他服务的调用。
信号量隔离:信号量是一种轻量级的并发控制机制。当使用信号量隔离时,Hystrix 会对每个服务调用设置一个信号量的数量。如果超过这个数量,后续的请求会被拒绝,从而实现了服务调用的隔离。
熔断机制:
熔断器状态:Hystrix 熔断器有三种状态,关闭(Closed)、打开(Open)和半开(Half - Open)。在正常情况下,熔断器处于关闭状态。当服务调用的失败率达到一定的阈值时,熔断器会从关闭状态切换到打开状态,阻止对该服务的进一步调用。在熔断器打开一段时间后,会进入半开状态,允许少量的请求通过,来试探被熔断的服务是否已经恢复正常。
降级逻辑:当熔断器处于打开状态或者服务调用超时时,Hystrix 会执行降级逻辑。开发人员可以为每个服务调用定义一个降级方法,例如返回一个缓存中的数据,或者是一个默认的响应值。
请求缓存和请求合并:Hystrix 支持请求缓存和请求合并功能。请求缓存可以缓存第一次请求的结果,并直接返回给后续的相同请求。请求合并可以将多个相同的请求合并成一个请求,然后对服务进行一次调用,再将结果分发到各个请求上。

📘4. 分布式追踪(Sleuth)

为分布式系统中的请求生成唯一跟踪 ID。
在 Spring Boot 应用程序中,Spring Cloud Sleuth 会自动为每个请求生成一个唯一的跟踪 ID,并将跟踪 ID 添加到日志信息中。例如,在控制器类中添加日志输出代码,在日志输出中可以看到 Sleuth 自动为这个请求生成的唯一跟踪 ID。
记录请求传播路径及定位问题的方法。
Spring Cloud Sleuth 基于 OpenTracing 和 Zipkin 实现,可以跟踪分散在不同微服务中的请求,生成一条完整的分布式事务链路。为了实现分布式链路跟踪和日志聚合,可以使用 Zipkin 服务器。在 Spring Boot 应用程序中,需要添加 spring-cloud-starter-zipkin 依赖,然后在应用程序的配置文件中添加 Zipkin 服务器的地址和采样率等配置。启动 Zipkin 服务器后,可以通过访问 Zipkin 服务器的 Web 界面,查看到分布式链路跟踪信息。

📘 5. API 网关(Spring Cloud Gateway)

路由匹配和请求转发的流程。
Spring Cloud Gateway 作为 API 网关组件,其调用流程大致可以分为以下几个步骤:
客户端发起请求:客户端向 Spring Cloud Gateway 发送 HTTP 请求,请求中包含目标服务的路径信息。
路由匹配:Spring Cloud Gateway 首先根据配置的路由规则对请求的 URL 进行匹配。如果开启了基于 Nacos 的服务发现,它会根据服务名自动创建路由规则。每个路由规则都关联了一系列谓词,用于进一步细化匹配条件,比如基于路径、请求方法、主机名等。只有当所有关联的谓词都匹配时,请求才会被路由到相应的微服务。
Filter(过滤器)链执行:在路由匹配之后,请求会经过一系列的全局过滤器和特定路由的过滤器。过滤器可以分为预处理(Pre)过滤器、路由(Route)过滤器和后处理(Post)过滤器,它们分别在路由前、路由期间和路由响应后执行,可以用来实现鉴权、日志记录、请求 / 响应修改等功能。
服务发现与负载均衡:当路由的目标是微服务时,Spring Cloud Gateway 会利用 Spring Cloud Alibaba 的负载均衡组件(通常是 Ribbon 或 Sentinel,具体取决于配置),结合 Nacos 服务发现来选择一个合适的微服务实例。例如,如果目标 URI 以 lb:// 开头,表示使用负载均衡器。
请求转发:经过上述处理后,Spring Cloud Gateway 将请求转发到选定的微服务实例。这一步可能包括协议转换、请求头处理等操作。
微服务处理请求:目标微服务接收到请求后,进行业务逻辑处理,并准备响应数据。
响应返回:微服务处理完毕后,响应通过 Spring Cloud Gateway 返回给客户端。在这个过程中,Gateway 的后处理过滤器可能会对响应进行额外的处理,如日志记录、结果修改等。
过滤器处理请求和响应的作用。
从过滤器生命周期的角度来说,主要有两个 pre 和 post:
pre:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。
post:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的 HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
从过滤器类型的角度,Spring Cloud Gateway 的过滤器分为 GateWayFilter 和 GlobalFilter 两种。GateWayFilter 应用到单个路由路由上,GlobalFilter 全局过滤器、应用到所有的路由上。

📘6. 声明式 HTTP 客户端(Feign)

定义接口描述服务 API 的方法。
Feign 是一个声明式的 Web 服务客户端,它通过定义接口来描述服务 API。在接口中,可以使用注解来定义请求的方法、路径、参数等信息。例如,可以使用 @FeignClient 注解来指定服务的名称,然后在接口方法中使用 Spring MVC 的注解来定义请求的细节。
动态代理对象的创建和调用流程。
当应用启动时,Feign 会扫描带有 @FeignClient 注解的接口,并为这些接口创建动态代理对象。在运行时,当调用这些接口的方法时,Feign 会根据接口上的注解信息,将请求转换为 HTTP 请求,并发送到目标服务。Feign 会集成 Ribbon 负载均衡器,实现对服务的负载均衡调用。如果目标服务出现故障,Feign 还可以结合 Hystrix 断路器,执行降级逻辑,返回预设的默认值或执行备用逻辑。

📚三、Spring Cloud 的优势

📘1. 微服务架构的优势

服务独立部署,耦合性低。
在 Spring Cloud 微服务架构中,各个服务可以独立进行部署。这意味着当对一个服务进行修改或升级时,不会影响到其他服务的正常运行。例如,一个电商系统中的商品服务和订单服务是独立的微服务,当商品服务需要进行功能扩展时,只需对商品服务进行部署更新,而订单服务不受任何影响。这种低耦合性使得系统的维护和升级更加容易,降低了因一个服务的问题导致整个系统崩溃的风险。
快速启动,适合敏捷开发。
由于微服务架构将一个大型应用拆分成多个小型服务,每个服务的代码量相对较少,启动速度较快。开发团队可以更加快速地进行开发、测试和部署,适应敏捷开发的需求。在开发过程中,开发人员可以专注于单个服务的功能实现,无需等待整个系统的启动。例如,在一个新功能的开发过程中,开发人员可以快速启动相关的微服务进行调试,提高开发效率。
职责专一,便于团队分工。
每个微服务都有明确的职责和功能边界,这使得团队可以根据服务的功能进行分工。不同的团队可以负责不同的微服务开发,提高开发效率和质量。例如,在一个金融系统中,可以将用户管理、交易处理、风险评估等功能分别拆分成不同的微服务,由不同的团队进行开发和维护。这样可以充分发挥团队成员的专业技能,提高开发效率。
可动态按需扩容。
当系统的负载增加时,可以根据实际需求动态地对某个微服务进行扩容。例如,在电商促销活动期间,订单服务的负载可能会大幅增加,可以通过增加订单服务的实例数量来提高系统的处理能力。Spring Cloud 提供了一系列的工具和技术,如服务注册与发现、负载均衡等,可以方便地实现微服务的动态扩容。
代码复用。
在微服务架构中,一些通用的功能可以封装成独立的微服务,供其他服务复用。例如,用户认证和授权功能可以作为一个独立的微服务,被多个其他服务调用。这样可以避免重复开发,提高代码的复用性和可维护性。

📘2. 在微服务架构中的作用

服务治理方面,如服务注册与发现、配置管理。
服务注册与发现:Spring Cloud 中的 Eureka 组件提供了服务注册与发现的功能。服务提供者在启动时会将自己的信息注册到 Eureka 服务器上,服务消费者可以从 Eureka 服务器获取服务提供者的地址信息,从而实现服务之间的通信。例如,在一个分布式系统中,有多个服务提供者提供相同的服务,服务消费者可以通过 Eureka 服务器自动发现这些服务提供者,并根据负载均衡策略选择一个进行调用。
配置管理:Spring Cloud Config 提供了集中式的配置管理功能。可以将不同环境下的配置文件集中存储在远程 Git 仓库中,微服务在启动时从配置中心获取相应的配置信息。这样可以方便地进行配置的管理和更新,避免了在每个微服务中单独管理配置文件的繁琐。例如,当系统需要切换到不同的环境时,只需在配置中心修改相应的配置,微服务会自动获取新的配置信息,无需重新部署。
客户端负载均衡。
Spring Cloud 中的 Ribbon 组件实现了客户端负载均衡。它从服务发现组件获取可用服务实例列表,并根据一定的负载均衡策略选择一个服务实例进行调用。例如,Ribbon 支持随机策略、轮询策略、加权策略等多种负载均衡策略。在随机策略中,从服务器中随机选择一个服务器进行调用;在轮询策略中,每次都取下一个服务器进行调用;在加权策略中,根据服务器的响应时间等因素为服务器分配不同的权重,响应时间越短的服务器被选中的可能性越大。
容错处理,包括断路器模式和监控管理。
断路器模式:Spring Cloud 中的 Hystrix 组件实现了断路器模式。当某个服务出现故障时,断路器会自动打开,阻止对该服务的进一步调用,从而防止故障扩散。例如,当一个电商系统中的商品服务出现故障时,Hystrix 会自动打开断路器,阻止订单服务对商品服务的调用,避免因商品服务的故障导致订单服务也出现故障。
监控管理:Hystrix 还提供了监控管理功能,可以实时监控服务的调用情况,包括请求次数、失败次数、延迟时间等。通过监控数据,可以及时发现系统中的问题,并采取相应的措施进行处理。例如,可以根据监控数据调整负载均衡策略,或者对出现故障的服务进行扩容或修复。
分布式链路追踪。
Spring Cloud Sleuth 和 Zipkin 实现了分布式链路追踪功能。可以为分布式系统中的请求生成唯一跟踪 ID,并记录请求的传播路径,方便在出现问题时进行定位。例如,在一个复杂的微服务架构中,一个请求可能会经过多个微服务的处理,通过分布式链路追踪可以清晰地看到请求在各个微服务之间的调用关系,以及每个微服务的处理时间和状态。当出现问题时,可以根据跟踪 ID 快速定位问题所在的微服务,提高问题解决的效率。
API 网关的作用。
路由匹配和请求转发:Spring Cloud Gateway 作为 API 网关组件,负责接收客户端的请求,并根据配置的路由规则将请求转发到相应的微服务。例如,当客户端发送一个请求到 API 网关时,网关会根据请求的 URL、请求方法等信息进行路由匹配,找到对应的微服务,并将请求转发给该微服务进行处理。
过滤器处理请求和响应:API 网关可以通过过滤器对请求和响应进行处理。过滤器可以在请求被路由之前或之后执行,实现鉴权、日志记录、请求 / 响应修改等功能。例如,可以在请求被路由之前通过过滤器进行身份验证,确保只有合法的用户才能访问系统;在响应返回给客户端之前,可以通过过滤器对响应进行格式转换或添加额外的信息。
与其他技术的集成,如与 Spring Boot 的无缝集成、对多种数据存储和消息中间件的支持。
与 Spring Boot 的无缝集成:Spring Cloud 基于 Spring Boot 构建,两者之间无缝集成。Spring Boot 提供了快速开发单个微服务的能力,Spring Cloud 则在微服务架构层面提供了一系列的工具和框架,使得开发分布式系统更加容易。例如,可以使用 Spring Boot 的开发风格快速开发一个微服务,并通过 Spring Cloud 的服务注册与发现、负载均衡等功能将其集成到分布式系统中。
对多种数据存储和消息中间件的支持:Spring Cloud 可以与多种数据存储和消息中间件进行集成,满足不同业务场景的需求。例如,可以使用 MySQL、Oracle、MongoDB 等多种数据库作为微服务的存储介质;可以使用 RabbitMQ、Kafka 等消息中间件实现微服务之间的异步通信。这样可以根据实际情况选择最适合的技术方案,提高系统的灵活性和可扩展性。

📚四、Spring Cloud 的应用场景

📘1. 不同系统架构的演变

单体应用架构、垂直应用架构、分布式架构、SOA 架构、微服务架构的特点和优缺点。

单体应用架构:
特点:将所有业务功能都部署在一起,部署在一台服务器上,一个进程包含了所有的业务逻辑。
优点:部署简单,技术单一,用人成本低。由于是完整的结构体,可以直接部署在一个服务器上即可;项目不需要复杂的技术栈,往往一套熟悉的技术栈就可以完成开发;单个程序员可以完成业务接口到数据库的整个流程。
缺点:系统启动慢,一个进程包含了所有的业务逻辑,涉及到的启动模块过多,导致系统的启动、重启时间周期过长;系统错误隔离性差、可用性差,任何一个模块的错误均可能造成整个系统的宕机;可伸缩性差,系统的扩容只能只对这个应用进行扩容,不能做到对某个功能点进行扩容;线上问题修复周期长,任何一个线上问题修复需要对整个应用系统进行全面升级。

垂直应用架构:
特点:将原来的一个应用拆成互不相干的几个应用,以提升效率。
优点:系统拆分实现了流量分担,解决了并发问题,可以针对不同模块进行优化和水平扩展,一个系统的问题不会影响到其他系统,提高容错率。
缺点:系统之间相互独立,无法进行相互调用,会有重复的开发任务。
分布式架构:
特点:将核心业务抽取出来,作为独立的服务,来提供给要用到这些服务的应用,逐渐形成稳定的服务中心。
优点:抽取公共的功能为服务层,提高代码复用性;将基础服务进行了抽取,系统间相互调用,提高了代码复用和开发效率。
缺点:系统间耦合度变高,调用关系错综复杂,难以维护;业务服务可以使用 HTTP 客户端工具访问基础服务,从而获取数据。但是在服务的消费方,把 url 地址硬编码到了代码中,不方便后期维护。服务的消费方需要记忆服务提供方的地址,如果地址出现变更,可能得不到通知,地址将失效。服务的消费方不清楚服务提供方的状态,服务宕机也不知道。服务提供方只有 1 台服务,不具备高可用性。即便服务提供方形成集群,服务的消费方还需自己实现负载均衡。

SOA 架构:
特点:面向服务的架构,它是一种设计方法,其中包含多个服务,服务之间通过相互依赖最终提供一系列的功能。一个服务通常以独立的形式存在于操作系统进程中。各个服务之间通过网络调用,通过 ESB(企业服务总线)进行连接。
优点:抽取公共的功能为服务,提高开发效率;对不同的服务进行集群化部署解决系统压力;基于 ESB/Dubbo 减少系统耦合;使用注册中心解决了服务间调用关系的自动调节。
缺点:抽取服务的粒度较大;服务提供方与调用方接口耦合度较高;服务间会有依赖关系,一旦某个环节出错会影响较大(服务雪崩);服务关系复杂,运维、测试部署困难。

微服务架构:
特点:将单体应用进一步拆分,拆分成更小的服务,每个服务都是一个可以独立运行的项目。
优点:服务原子化拆分,独立打包、部署和升级,保证每个微服务清晰的任务划分,利于扩展;微服务之间采用 Restful 等轻量级 http 协议相互调用;通过服务的原子化拆分,以及微服务的独立打包、部署和升级,小团队的运营成本将缩短,运维成本也将大幅度下降;微服务遵循单一原则,微服务之间采用 restful 等轻量协议传输;可动态按需扩容;代码复用。

缺点:分布式系统开发的技术成本高(容错、分布式事务等);微服务过多,服务治理成本高,不利于系统维护。

📘2. 微服务架构的常见问题

管理小服务、服务通讯、客户端访问、自处理和排错等问题的解决方案。

管理小服务:通过服务治理来管理小服务,服务治理的核心是服务的自动注册与发现。服务注册是服务实例将自身服务信息注册到注册中心;服务发现是服务实例通过注册中心,获取到注册到其中的服务实例的信息,通过这些信息去请求它们提供的服务;服务剔除是服务注册中心将出问题的服务自动剔除到可用列表之外,使其不会被调用到。

服务通讯:在微服务架构中,通常存在多个服务之间的远程调用的需求。目前主流的远程调用技术有基于 HTTP 的 RESTful 接口以及基于 TCP 的 RPC 协议。

客户端访问:通过 API 网关来实现客户端访问,API 网关负责接收客户端的请求,并根据配置的路由规则将请求转发到相应的微服务。

自处理:当出现问题时,微服务可以通过断路器模式进行自处理。当某个服务出现故障时,断路器会自动打开,阻止对该服务的进一步调用,从而防止故障扩散。同时,开发人员可以为每个服务调用定义一个降级方法,例如返回一个缓存中的数据,或者是一个默认的响应值。

排错:通过分布式链路追踪来实现排错,Spring Cloud Sleuth 和 Zipkin 实现了分布式链路追踪功能。可以为分布式系统中的请求生成唯一跟踪 ID,并记录请求的传播路径,方便在出现问题时进行定位。

📚五、Spring Cloud 的实战

📘1. 安装 Spring Cloud

Spring Cloud 的安装可以通过依赖管理工具(如 Maven 或 Gradle)进行。以 Maven 为例,在项目的 pom.xml 文件中添加相应的 Spring Cloud 依赖。
例如,如果要使用 Spring Cloud Hoxton.SR8 版本,可以添加以下依赖:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR8</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

这样就可以在项目中引入 Spring Cloud 的相关组件了。

📘2. 构建 RESTful 服务

使用 Spring Boot 和 Spring Cloud 创建服务的基本步骤。
首先,创建一个 Spring Boot 项目,可以通过 Spring Initializr 在线生成或者使用 IDE(如 IntelliJ IDEA)创建。在创建项目时,添加所需的依赖,如 Web 和 Eureka Discovery。
然后,创建一个控制器类,用于处理 HTTP 请求。例如:

@RestController
public class HelloWorldController {
    @GetMapping("/hello")
    public String sayHello() {
        return "Hello, World!";
    }
}

最后,在主类上添加注解,开启服务注册功能。例如:

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

API 文档生成与使用。
可以使用 Swagger 来生成 API 文档。首先,在项目中添加 Swagger 的依赖:

<!-- swagger2 -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.8.0</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.8.0</version>
</dependency>

然后,创建一个配置类,描述文档的一些信息:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
                // 扫包的范围,也就是把哪些包生成 api 文档.
               .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
               .paths(PathSelectors.any()).build();
    }

    private ApiInfo apiInfo() {
        // title 文档标题
        // description 文档描述
        // termsOfServiceUrl 自定义地址
        // version 版本号
        return new ApiInfoBuilder().title("微服务电商系统").description("微服务 swagger")
               .termsOfServiceUrl("http://www.example.com").version("1.0").build();
    }
}

在控制器类的方法上添加注解,描述方法和参数:

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Api("aaa")
@Controller
public class SwaggerController {
    // 描述方法的
    @ApiOperation("方法一描述")
    // 描述参数的 name 参数名 value 描述信息 required 是否必填 dataType 参数类型
    @ApiImplicitParam(name = "userName", value = "用户名参数", required = true, dataType = "String")
    @GetMapping("/swaggerIndex")
    public String swaggerIndex(String userName) {
        System.out.println(userName);
        return "index";
    }
}

启动项目后,访问 http://localhost: 端口号 /swagger-ui.html 即可查看 API 文档。

📘3. 服务发现与配置管理

集成 Eureka 和 Spring Cloud Gateway 的方法。
Spring Cloud Gateway 可以与 Eureka 集成,实现服务的自动发现和路由转发。首先,在项目中添加依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

在 application.yml 文件中进行配置:

server:
  port: 7888
spring:
  application:
    name: gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:7887/eureka/
  instance:
    prefer-ip-address: true

这样,Spring Cloud Gateway 就可以自动发现注册在 Eureka 中的服务,并根据配置的路由规则进行转发。例如,当访问 http:// 网关地址 / 服务名称(小写)/** 时,就会转发到对应的服务。

📘4. 实践与案例

异步消息处理,如使用 RabbitMQ。
在 Spring Cloud 中,可以使用 RabbitMQ 实现异步消息处理。首先,在项目中添加依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

然后,进行配置:

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest

创建消息接收方:

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class ReceiveMessage {
    @RabbitListener(queues = "myqueue")
    public void receive(String messge) {
        System.out.println("message=" + messge);
    }
}

消息发送测试:

import org.junit.runner.RunWith;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ReceiveMessageTest {
    @Autowired
    private AmqpTemplate amqpTemplate;

    @Test
    public void send() throws Exception {
        amqpTemplate.convertAndSend("myqueue", "now : " + new Date());
    }
}

自动创建队列:

@RabbitListener(queuesToDeclare = @Queue("myQueue"))
public class ReceiveMessage {
    //...
}

如果有多个服务需要交互,可以使用交换机和队列进行分组:
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class ReceiveMessage {
    @RabbitListener(bindings = @QueueBinding(exchange = @Exchange("myOrder"), key = "computer", value = @Queue("computerOrder")))
    public void processComputer(String messge) {
        System.out.println("computer MqReceive: " + messge);
    }

    @RabbitListener(bindings = @QueueBinding(exchange = @Exchange("myOrder"), key = "fruit", value = @Queue("fruitOrder")))
    public void fruitComputer(String messge) {
        System.out.println("computer MqReceive: " + messge);
    }
}

消息发送方:

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SendMessageTest {
    @Autowired
    private AmqpTemplate amqpTemplate;

    @Test
    public void sendOrder() throws Exception {
        amqpTemplate.convertAndSend("myOrder", "computer", "now : " + new Date());
    }
}

选择行业相关场景进行微服务架构开发的实践建议和常见问题排查。

实践建议:

在选择行业相关场景进行微服务架构开发时,可以先进行需求分析,确定系统的功能模块和业务流程。
然后,根据业务需求选择合适的微服务架构模式,如单体应用架构、垂直应用架构、分布式架构、SOA 架构或微服务架构。
在开发过程中,要注重服务的独立性和可扩展性,遵循单一职责原则,每个服务只负责一个特定的业务功能。
同时,要合理使用 Spring Cloud 的各种组件,如服务发现、负载均衡、断路器、分布式链路追踪和 API 网关等,提高系统的可靠性和性能。
对于 API 文档的生成,可以使用 Swagger 等工具,方便前后端开发人员进行接口对接和调试。

常见问题排查:

服务发现与注册问题:确保服务能够正确注册到注册中心,并能够通过服务名发现其他服务。可以检查服务的配置文件是否正确,服务是否正常启动,以及注册中心的状态是否正常。
服务间通信问题:如果服务间通信出现问题,可以检查网络连接是否正常,服务的端口是否开放,以及服务的调用方式是否正确。可以使用分布式链路追踪工具,如 Spring Cloud Sleuth 和 Zipkin,来定位问题所在。
配置管理问题:如果配置文件无法正确加载,可以检查配置中心的地址是否正确,配置文件的格式是否正确,以及服务是否有权限访问配置中心。
性能问题:如果系统性能出现问题,可以检查服务的负载情况,是否存在性能瓶颈。可以使用性能监控工具,如 Prometheus 和 Grafana,来监控系统的性能指标,并进行优化。

到此这篇文章就介绍到这了,更多精彩内容请关注本人以前的文章或继续浏览下面的文章,创作不易,如果能帮助到大家,希望大家多多支持宝码香车~💕,若转载本文,一定注明本文链接。


整理不易,点赞关注宝码香车

更多专栏订阅推荐:
👍 html+css+js 绚丽效果
💕 vue
✈️ Electron
⭐️ js
📝 字符串

✍️ 时间对象(Date())操作


原文地址:https://blog.csdn.net/qq_33650655/article/details/144016080

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!