文章目录
一、SpringCloud Alibaba
Spring Cloud Alibaba是阿里巴巴提供的一站式微服务解决方案,是Spring Cloud体系中的一个重要分支,它将阿里巴巴在微服务领域的实践经验和开源技术进行了整合,为开发者提供了一系列便捷的工具和组件,用于构建分布式微服务应用。以下是其详细介绍:
1、核心组件
- Nacos:用于服务注册与发现以及配置管理。它可以帮助微服务实例自动注册到注册中心,并能够动态获取配置信息,使应用程序能够灵活地应对配置的变化,无需重启服务。
- Sentinel:主要用于流量控制、熔断降级等功能。它可以保护微服务免受高并发、流量异常等情况的影响,确保系统在压力下能够稳定运行,避免因个别服务出现问题而导致整个系统崩溃。
- RocketMQ:是一款高性能、高可靠的分布式消息队列。它在微服务架构中常用于实现异步消息传递、解耦系统组件之间的依赖关系,从而提高系统的整体性能和可扩展性。
- Seata:致力于提供分布式事务解决方案,确保在分布式系统中数据的一致性。它通过对事务的协调和管理,使得多个微服务之间在进行数据交互时能够遵循ACID原则。
2、优势
- 一站式解决方案:涵盖了微服务架构中的多个关键领域,包括服务治理、配置管理、流量控制、分布式事务等,开发者无需再从多个不同的开源项目中进行整合,大大降低了微服务架构的搭建和维护成本。
- 与Spring Cloud生态的深度集成:基于Spring Cloud的编程模型和规范进行开发,使得熟悉Spring Cloud的开发者能够快速上手并轻松集成到现有的Spring Cloud项目中,充分利用Spring Cloud的各种特性和优势。
- 阿里巴巴的技术实力和实践经验支持:得益于阿里巴巴在大规模分布式系统开发和运营方面的丰富经验,Spring Cloud Alibaba的组件经过了实际生产环境的考验,具有较高的稳定性、性能和可扩展性,能够应对各种复杂的业务场景和高并发流量。
3、应用场景
- 电商系统:在电商业务中,存在多个微服务,如商品服务、订单服务、库存服务等。Spring Cloud Alibaba可以通过Nacos进行服务注册与发现,使用Sentinel对各个服务的流量进行控制,利用RocketMQ实现异步消息通知,比如下单成功后异步通知库存服务扣减库存,通过Seata保证分布式事务的一致性,确保订单和库存等数据的准确性。
- 金融系统:金融领域对数据一致性和系统稳定性要求极高。Spring Cloud Alibaba的Seata可以确保在多个金融业务操作之间的分布式事务一致性,如转账操作涉及到两个不同账户服务之间的资金变动。Nacos可以提供配置管理,方便对金融业务的各种配置参数进行动态调整,Sentinel则可以防止因突发的高并发交易对系统造成冲击。
- 物联网(IoT)平台:物联网场景中,大量的设备会产生实时数据并上传到云端。Spring Cloud Alibaba可以通过Nacos管理各个物联网服务的注册与发现,使用RocketMQ接收和处理大量的设备数据消息,进行异步处理和分发。Sentinel可以对物联网服务的流量进行控制,防止因设备数据突发增长导致系统过载。
二、Nacos作为配置中心源码分析
3、源码分析
3.1 服务启动加载bootstrap.propertis
准备环境加载bootstrap.propertis,这里他会发送事件进行监听,我们可以直接进入 #load我们可以在load打上断点
总结:我们可以根据堆栈信息来发现,它是在准备环境的时候发送一个事件,ConfigFileApplicationListener监听事件,最后调用PropertiesPropertySourceLoader 对资源进行加载
3.2 客户端拉取远程配置进行合并
这里最终会调用用到NacosPropertySourceLocator# ,我们在locate上打上断点可以看一下堆栈信息
好,我们看一下locate方法
记载配置文件后最终会用composite进行合并,那他们无论加载共享配置、扩展配置和当前应用配置最终会调到NacosPropertySourceLocator#loadNacosDatalfPresent
重点我们看一下他的配置加载
key1:从本地获取配置
key2:远程获取配置
总结:这里我们注意Spring的扩展点之一:在我们Bean构建之前加载一些数据,比如配置属性,我们就可以用这个扩展点,这里加载配置中心内容,这个内容用于后面bean对象创建。
例如:
进行配置
3.3 服务端处理配置拉取
客户端请求为ConfigQueryRequest,则从服务端进行搜索找到对应处理类
下面对应的方法比较长,我们可以看一下关键的点
总结:分析我们发送请求是从缓存文件中获取到的,这里带出两个问题,1、因为我们是从缓存中获取的,那我们直接修改数据库应该是不起作用的 2、缓存一定是从数据库中获取的,那什么时候设置进去的呢
3.4 服务启动进行数据库数据加载
服务端启动时就会依赖DumpService的init方法,从数据库中load 配置存储在本地磁盘上,并将一些重要的元信息例如MD5值缓存在内存中。服务端会根据心跳文件中保存的最后一次心跳时间,来判断到底是从数据库dump全量配置数据还是部分增量配置数据(如果机器上次心跳间隔是6h以内的话)。
全量dump当然先清空磁盘缓存,然后根据主键ID每次捞取一千条配置刷进磁盘和内存。增量dump就是捞取最近六小时的新增配置(包括更新的和删除的),先按照这批数据刷新一遍内存和文件,再根据内存里所有的数据全量去比对一遍数据库,如果有改变的再同步一次,相比于全量dump的话会减少一定的数据库IO和磁盘I0次数。
构建bean时候一定初始化@PostConstruct 对应的方法
判断全量和增量获取数据
全量拉取
总结:这里的md5值的我们学习,我们md5算法获取对应文件的值,如果这个值变化说明文件发生了变化,利用这中方式我们可以通过文件md5值来判断其他是否有变化
3.5 加载数据发生变更,发送事件
如果队列写满则如下操作:但是我们上面是服务启动暂时没有新的服务进来,所以这里subscriber是空的也就无法调用
如果正常情况下应该是放到队列里面,那就应该有取的地方,全文搜索对应的queue
哪里调用到这里呢?
从这里我们可以知道DefaultPublisher是一个线程,所有会调用run方法
总结:我们应该学会发布监听事件
3.6 监听配置变更
全文搜索ApplicationReadyEvent,查看NacosContextRefresher
发送RefreshEvent事件后,就是对@RefreshScope标志的实例进行删除,这里可以参考2.7分析失败原因
key1:销毁对应实例
key2:发送事件RefreshScopeRefreshedEvent 这也是我们通过监听这个事件,来实例化对应的实例的
3.7 服务端端更改配置
我们配置中心发布配置,一定是调用SpringMVC中的Controller方法 ,我们进行全文搜索,通过名称进行分析应该是ConfigController
key1: 更新数据库
key2:发布事件,进行客户端通知配置变更,以及集群同步
全文搜索ConfigDataChangeEvent
AsyncRpcTask是一个任务,并向里面传递了rpcQuene的一个任务队列,我看一下他是怎样处理的。
key1:我们看一下数据持久化, key2中集群数据同步就是发送一个rpc请求
我们重点key1:
上面我们解释过这里是异步处理一定有个地方处理他
发布LocalDataChangeEvent事件
全文搜索对应的事件
查看任务RpcPushTask对应的方法:
向客户端发送请求,进行配置变更的通知
3.8 客户端处理事件
我们知道发送请求的是ConfigChangeNotifyRequest,好,我们到客户端全文搜索一下,找对应的处理
我们全文搜索listenExecutebell找对应的处理位置
3.9 客户端定时拉取配置
3.10 于Nacos1.x长轮询做对比