SpringClound 微服务分布式Nacos学习笔记
SpringClound 微服务分布式Nacos学习笔记
原创 已于 2025-10-14 01:08:25 修改 · 粉丝可见 · 1.1k 阅读 · 26 · 21 GEO检测 · 编辑
文章链接:https://blog.csdn.net/hacker_51/article/details/147235033
基本概述
在实际项目中,选择哪种架构需要根据具体的需求、团队能力和技术栈等因素综合考虑。
单体架构(Monolithic Architecture)
单体架构是一种传统的软件架构风格,将整个应用程序构建为一个单一的、不可分割的单元。在这种架构中,所有的功能模块(如用户管理、订单处理、支付等)都打包在一个大型的、统一的代码库中,并且部署为一个单独的进程。
微服务架构(Microservices Architecture)
微服务架构是一种将复杂应用程序分解为一组小型、独立服务的架构风格。每个微服务都围绕特定的业务功能构建,运行在其独立的进程中,并通过轻量级的通信机制(通常是HTTP/RESTful API、消息队列等)协同工作。例如,一个电商系统可以被拆分为用户服务(处理用户注册、登录等功能)、订单服务(负责订单创建、查询等)、库存服务(管理商品库存)等多个微服务。
总结
单体架构 适用于小型或简单的应用程序,开发团队规模较小,且对系统的扩展性和灵活性要求不高。
微服务架构 适用于复杂、大型的应用程序,特别是需要高可扩展性、灵活性和快速迭代的场景。开发团队需要具备分布式系统的开发和运维能力。
一、单体架构(Monolithic Architecture)
(一)定义
单体架构是一种传统的软件架构风格,将整个应用程序构建为一个单一的、不可分割的单元。在这种架构中,所有的功能模块(如用户管理、订单处理、支付等)都打包在一个大型的、统一的代码库中,并且部署为一个单独的进程。
(二)特点
集中式开发
单体架构的代码通常集中在一个大型的代码库中,所有功能模块共享相同的代码库。开发团队需要在同一个代码库中协作,进行功能开发、修改和维护。
统一部署
整个应用程序作为一个整体进行部署。每次更新或修复任何功能模块时,都需要重新打包并部署整个应用程序。例如,如果只是修复了一个小的用户界面问题,也需要重新部署整个系统。
紧密耦合
功能模块之间通常存在紧密的依赖关系。一个模块的变更可能会影响到其他模块,因此在修改代码时需要非常谨慎,以避免引入新的问题。
可扩展性有限
单体架构的扩展通常是通过增加服务器的性能(如CPU、内存)来实现的,这种扩展方式称为垂直扩展。当系统负载增加时,垂直扩展的代价会越来越高,且存在硬件资源的瓶颈。
(三)优点
简单易理解
对于小型或简单的应用程序,单体架构的结构相对简单,开发和部署过程也较为直观。开发人员可以快速上手,不需要复杂的架构设计和分布式系统的知识。
开发工具友好
大多数开发工具(如IDE)对单体架构的支持较好,调试和测试也相对容易。开发人员可以在一个统一的环境中进行开发,不需要考虑跨服务的调试问题。
事务管理简单
在单体架构中,事务管理相对简单,因为所有的功能模块都在同一个进程中运行,可以通过传统的数据库事务来保证数据的一致性。
(四)缺点
可维护性差
随着应用程序的规模增大,代码库会变得庞大且复杂,开发和维护成本会急剧上升。新功能的添加或现有功能的修改可能会引入新的问题,影响整个系统的稳定性。
部署困难
由于每次更新都需要重新部署整个应用程序,部署过程可能会变得繁琐且耗时。同时,频繁的部署也可能对系统的稳定性产生影响。
技术栈受限
单体架构通常使用单一的技术栈,很难引入新的技术或框架。一旦选择了某种技术,后续很难进行技术的替换或升级。
二、微服务架构(Microservices Architecture)
(一)定义
微服务架构是一种将复杂应用程序分解为一组小型、独立服务的架构风格。每个微服务都围绕特定的业务功能构建,运行在其独立的进程中,并通过轻量级的通信机制(通常是HTTP/RESTful API、消息队列等)协同工作。
(二)特点
- 独立性
独立开发 :每个微服务可以由不同的团队独立开发,团队之间只需要通过定义好的接口进行协作。例如,用户服务团队和订单服务团队可以分别开发和维护自己的服务,而不需要相互干扰。
独立部署 :每个微服务可以独立部署,更新或扩展一个微服务不会影响到其他微服务。例如,当订单服务需要更新订单处理逻辑时,只需要重新部署订单服务相关的代码和配置。
独立扩展 :可以根据每个微服务的负载情况独立扩展。如果用户服务的访问量突然增加,可以单独增加用户服务的实例数量,而不需要对其他服务进行扩展。
容错性
单个微服务的故障不会导致整个系统崩溃。例如,如果库存服务暂时不可用,订单服务仍然可以正常接收订单,只是可能无法实时更新库存信息,但系统可以设计为在这种情况下记录订单并等待库存服务恢复后再处理库存更新。
可维护性高
由于每个微服务都相对独立,代码库较小,开发和维护成本相对较低。新功能的添加或现有功能的修改不会对整个系统产生太大的影响。
(三)优点
敏捷开发
微服务架构支持敏捷开发,不同的团队可以并行开发不同的微服务,加快开发速度。同时,独立部署的特点也使得新功能可以快速上线。
可扩展性强
微服务架构支持水平扩展,可以根据每个微服务的负载情况独立扩展。例如,通过增加微服务实例的数量来应对高并发场景。
技术灵活性
开发团队可以自由选择最适合的技术栈来开发每个微服务,便于引入新技术和框架。
容错性好
单个微服务的故障不会导致整个系统崩溃,系统的整体可用性更高。
(四)缺点
分布式系统复杂性
微服务架构本质上是一个分布式系统,需要处理分布式事务、服务间通信、数据一致性等问题。例如,一个业务流程可能涉及多个微服务的调用,需要解决分布式事务问题。
部署和运维复杂
微服务架构需要管理多个独立的服务,部署和运维的复杂度会增加。例如,需要管理每个微服务的配置、监控、日志等。
性能开销
由于微服务之间通过网络通信(如HTTP/RESTful API、消息队列),可能会引入额外的性能开销。例如,服务间的调用延迟可能会比单体架构中的方法调用延迟更高。
数据一致性挑战
微服务架构中,数据通常分散在不同的微服务中,需要解决数据一致性问题。例如,订单服务和库存服务可能分别存储订单信息和库存信息,需要通过分布式事务或事件驱动的方式来保证数据的一致性。
三、单体架构与微服务架构的对比
| 特点 | 单体架构 | 微服务架构 |
|---|---|---|
| 开发方式 | 集中式开发,所有功能模块在同一个代码库中 | 分布式开发,每个微服务独立开发 |
| 部署方式 | 统一部署,更新需要重新部署整个应用程序 | 独立部署,更新或扩展一个微服务不影响其他微服务 |
| 技术栈 | 通常使用单一技术栈 | 可以使用多种技术栈 |
| 可维护性 | 小型应用简单,大型应用复杂且难以维护 | 可维护性高,每个微服务相对独立 |
| 扩展性 | 垂直扩展,受限于硬件资源 | 水平扩展,可以根据负载独立扩展每个微服务 |
| 容错性 | 一个模块的故障可能导致整个系统崩溃 | 单个微服务的故障不会影响整个系统 |
| 事务管理 | 传统数据库事务管理简单 | 需要分布式事务管理 |
| 性能开销 | 方法调用性能高,没有额外的网络通信开销 | 服务间通信可能引入额外的性能开销 |
| 开发工具 | 开发工具友好,调试和测试简单 | 开发工具支持有限,调试和测试复杂 |
| 适用场景 | 小型或简单的应用程序 | 复杂、大型的应用程序,需要高可扩展性和灵活性 |
SpringClound
官网地址: Spring Cloud
SpringCloud是目前国内使用最广泛的微服务框架。集成了各种微服务功能组件,并基于SpringBoot实现了这些组件的自动装配,从而提供了良好的开箱即用体验。
微服务拆分
原则:


微服务通信
当我们将微服务拆分后,各自的资源会存在独立管理的状态,当某个服务需要调用另一个服务的资源的时候。我们可以通过 网络通信 的方式,进行各自的资源交互。
SpringRestTemplate工具
Spring给我们提供了一个RestTemplate工具,可以方便的实现Http请求的发送。使用步骤如下:
1、注入RestTemplate到Spring容器
1 | |
2、简单的Get引用获取交换资源
1 | |
服务治理-nacos
微服务远程通信问题
当我们多个服务运行后,其中某个服务挂机,而我们写的请求URL写死了,导致获取不到资源。又亦或重启服务后,端口方面有变动,我们又得要从源码中更改,这是不理想的情况的。

注册中心原理
什么是注册中心
在分布式系统中,服务会有很多实例,这些实例分布在不同的机器上。注册中心就像是一个“服务中心”,它记录了所有服务实例的信息,包括服务名称、实例的地址(IP和端口)等。当一个服务(客户端)需要调用另一个服务(服务提供者)时,它会先去注册中心查询服务提供者的地址,然后才能进行通信。

Nacos 注册中心
Nacos是目前国内企业中占比最多的注册中心组件。它是阿里巴巴的产品,目前已经加入SpringCloud Alibaba中。(官网: Nacos官网| Nacos 配置中心 | Nacos 下载| Nacos 官方社区 | Nacos 官网 )
Nacos搭建步骤
1、配置MySQL表
我们基于Docker来部署Nacos的注册中心,首先我们要准备MySQL数据库表,用来存储Nacos的数据。官方Nacos-SQL表( mysql-schema.sql )
这里注意执行脚本前,自定义一个自己的数据库,同时添加用户信息(密码:nacos)
1 | |
2、dockers部署
- 拉取镜像
1 | |
- 通过 SSL 执行生成随机base64的 NACOS_AUTH_TOKEN
1 | |
- 一键命令创建并启动镜像( 系统参数 | Nacos 官网 )
1 | |
启动成功后,通过 logs 可以看到

访问 http://localhost:8848/nacos/ ,就进入到需要登录的页面。

根据我们配置的MySQL默认账号密码都为:Nacos。登录即可看到页面

服务注册
1、引入依赖
父工程:
1 | |
子工程:
1 | |
2、配置 yaml 文件
1 | |
3、启动服务

可以看到服务注册成功。

服务发现
1 | |
通过测试可以发现,实现了负载均衡。

OpenFeign
Openfeign是一个声明式的http客户端,是SpringCloud在Eureka公司开源的Feign基础上改造而来。官方地址: https://github.com/openFeign/feign
其作用就是基于SpringMVC的常见注解,帮我们优雅的实现http请求的发送。

快速入门
微服务通信刨析

引入依赖
1 | |
通过@EnableFeignClients注解,启用OpenFeign功能
1 | |
编写FeignClient
1 | |
调用
1 | |
连接池
OpenFeign对Http请求做了优雅的伪装,不过其底层发起http请求,依赖于其它的框架。这些框架可以自己选择,包括以下三种:
HttpURLconnection:默认实现,不支持连接池
Apache HttpClient:支持连接池
OKHttp:支持连接池
具体源码可以参考 FeignBlockingLoadBalancerClient 类中的 delegate 成员变量。
引入依赖
这里使用 OKhttp
1 | |
启动连接池
yaml配置
1 | |
最佳实践
方案一:

优点:
模块化 :每个服务模块独立开发、部署和扩展,便于维护和升级。
解耦 :服务之间通过定义好的接口进行通信,降低了耦合度。
可扩展性 :可以根据需要独立扩展各个服务模块,提高系统的可扩展性。
灵活性 :可以根据业务需求灵活组合不同的服务模块,实现复杂的业务逻辑。
缺点:
复杂性 :
管理多个服务增加了系统的复杂性。
需要额外的工具和服务来管理服务间的通信和数据一致性。
这种微服务架构适用于大型分布式系统,可以提高系统的可维护性、可扩展性和灵活性。
方案二:

优点:
- 集中化API管理
hm-api作为API网关,统一管理对外的API接口,简化了客户端与后端服务的交互。
- 解耦:
服务之间通过API网关进行通信,降低了服务之间的直接依赖,提高了系统的灵活性和可维护性。
缺点:
- 复杂性增加:
引入API网关增加了系统的复杂性,需要额外的配置和管理。
- 性能开销:
API网关可能会引入额外的网络延迟,影响系统性能。
- 单点故障:
如果API网关设计不当,可能会成为系统的单点故障,影响整体可用性。
总的来说,引入API网关可以带来许多好处,如集中化管理、解耦,但也需要注意其带来的复杂性和性能开销。在设计和实施API网关时,需要权衡这些因素,确保系统的稳定性和可维护性。
扫描包问题
当定义的FeignClient不在SpringBootApplication的扫描包范围时,这些FeignClient无法使用。有两种方式解决。
方式一:指定FeignClient所在包
1 | |
方式二:指定Feignclient字节码
1 | |
日志输出
Openfeiqn只会在FeignClient所在包的日志级别为 DEBUG 时,才会输出日志。而且其日志级别有4级:
ONONE:不记录任何日志信息,这是默认值。
BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
HEADERS:在BASI℃的基础上,额外记录了请求和响应的头信息
FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据,
由于Feign默认的日志级别就是NONE,所以默认我们看不到请求日志。
要自定义日志级别需要声明一个类型为Logger.Level的Bean,在其中定义日志级别。
1 | |
局部声明
1 | |
全局声明
1 | |

Spring gateway 网关
在Java微服务架构中,网关路由是实现服务间通信和请求管理的关键组件。它作为微服务架构的入口,接收外部请求并根据请求的特征(如URL、HTTP方法、参数等)将请求转发到对应的服务实例。网关路由不仅负责请求的转发,还承担了诸如身份验证、授权、限流、熔断、日志记录等多种职责,从而为微服务提供统一的接入点和安全控制,简化了客户端与服务之间的交互复杂性,提高了系统的可维护性和可扩展性。 简要概述:就是网络的关口,负责请求的路由、转发、身份校验。
快速入门
引入依赖
1 | |
yaml配置
1 | |
路由属性
网关路由 对应的Java类型是RouteDefinition,其中常见的属性有:
id:路由唯一标识
uri:路由目标地址
predicates:路由断言,判断请求是否符合当前路由
filters:路由过滤器,对请求或响应做特殊处理
路由断言

路由过滤器

Ncos配置中心
由于工作原因,大概学习了基础使用,另写了一篇文章,可以到这里去看一下: Nacos配置中心
服务保护和分布式事务
雪崩问题
微服务调用链路中的某个服务故障,引起整个链路中的所有微服务都不可用,这就是雪崩

雪崩问题产生的原因是什么?
微服务相互调用,服务提供者出现故障或阻塞。
服务调用者没有做好异常处理,导致自身故障。
调用链中的所有服务级联失败,导致整个集群故障
解决问题的思路有哪些?
尽量避免服务出现故障或阻塞。
保证代码的健壮性;
保证网络畅通
能应对较高的并发请求
服务调用者做好远程调用异常的后备方案,避免故障扩散
服务保护方案-请求限流
请求限流:限制访问微服务的请求的并发量,避免服务因流量激增出现故障

服务保护方案-线程隔离
线程隔离:也叫做舱壁模式,模拟船舱隔板的防水原理。通过限定每个业务能使用的线程数量而将故障业务隔离,避免故障扩散。

服务保护方案-服务熔断
服务熔断:由断路器统计请求的异常比例或慢调用比例,如果超出阈值则会熔断该业务,则拦截该接口的请求。
熔断期间,所有请求快速失败,全都走fallback逻辑。

总结
解决雪崩问题的常见方案有哪些?
请求限流: 限制流量在服务可以处理的范围,避免因突发流量而故障
线程隔离: 控制业务可用的线程数量,将故障隔离在一定范围
服务熔断: 将异常比例过高的接口断开,拒绝所有请求,直接走fallback
失败处理: 定义fallback逻辑,让业务失败时不再抛出异常,而是返回默认数据或友好提示
服务保护技术

觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭
wechat pay
ali pay