在微服务构架中,集群服务间的需要调用时就需要知道各个服务的IP和提供服务的端口等信息,如果每个部署一个服务就配置一次,那么必然时非常麻烦的,因此我们需要一个能够统一管理的东西来解决这个问题,由此诞生了注册中心。
每个服务启动后都向注册中心发送自己的服务信息,在需要调用其他服务的时候直接从注册中心里面去获取集群的服务信息。spring-cloud中很多使用的是Eureka来作为注册中心,不过在2018年7月的时候Netflix就宣布停止维护Eureka了。
在spring-cloud-alibaba的套装中我们使用Nacos来替换掉Eureka这个组件。 需要注意的是Nacos不仅有注册中心的功能,同时还具备配置中心的功能,支持将配置加密。在公司中若不想自己搭建,可以使用阿里云提供的ACM配置中心服务,功能更丰富,目前是免费提供使用,可以节约搭建配置中心的成本。
相关文档
Nacos注册中心的使用
首先我们需要安装Nacos,安装步骤可以参考Nacos安装和配置 ; 下面是使用方式:
- 在项目中添加如下依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
这个依赖用于替换eureka的客户端依赖包
spring-cloud-starter-netflix-eureka-client
在启动类上添加
@EnableDiscoveryClient
注解;其实使用eureka做注册中心时,也建议使用此注解,方便后期更换注册中心不用修改代码。在application配置文件中添加nacos的配置
spring:
cloud:
nacos:
discovery:
# nacos的地址
server-addr: 127.0.0.1:8848
成功后即可在nacos控制台中查看。
Nacos配置中心的使用
首先说明下使用配置中心有利的地方;1.保护铭感配置信息,我们项目中大部分配置其实都是固定的,比如数据库、项目端口、路径、第三方API的开发配置等等的配置;但是如果直接这些直接配置在项目中,在代码泄漏的同时这些配置的机密信息也就泄漏了。 2.可以方便的配置一些需要的动态配置,虽然现在的自动化部署很方便了,但是机器多的话还是会花费少时间的。3.集中化管理配置,公共配置的重复利用,避免同样的配置重复写入。4.配置的历史版本管理,方便一键回滚。
- 添加配置中心的依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
- 创建
bootstrap.properties
配置文件,也可以是bootstrap.yml
(不建议使用这种,因为可能会识别不到);在里面添加如下配置(bootstrap.properties示例):
# 配置文件名称前缀,使用的是服务名称
spring.application.name=nacos-config
# 分组
spring.cloud.nacos.config.group=DEFAULT_GROUP
# nacos 配置中心地址
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
# 配置文件后缀
spring.cloud.nacos.config.file-extension=yml
# 激活文件,这个配置可以通过启动参数指定 -Dspring.profiles.active=dev来切换环境, 实现打一次包就可以了
spring.profiles.active=dev
原理说明:spring-boot启动的时候其实会加载所有的配置文件,最终合并为一份,最终符合激活文件的会最后加载,依此来覆盖其他配置;spring会以这个bootstrap配置文件的优先;
配置文件命名说明:最终组装的DataID = spring.application.name + ‘-‘ + spring.profiles.active + spring.cloud.nacos.config.file-extension
- 在nacos控制台上配置相关配置。
将各个组件的配置拆分
将redis、MySQL的等公共基础组件的配置拆分到单个文件中,如在nacos控制台创建一个名为db-config-dev.yml
的MySQL的配置; 项目中bootstrap配置的信息如下(bootstrap.properties示例):
spring.application.name=nacos-config-demo
spring.cloud.nacos.server-addr=192.168.56.102:8848
spring.cloud.nacos.config.file-extension=yml
spring.cloud.nacos.config.group=DEFAULT_GROUP
# 附加配置文件
spring.cloud.nacos.config.extension-configs[0].data-id=db-config-${spring.profiles.active}.yml
spring.cloud.nacos.config.extension-configs[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.extension-configs[0].refresh=true
记得在启动参数中添加
spring.profiles.active=dev
db-config-dev.yml
的MySQL的配置:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/demo?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
username: root
password: 123456
这拆分后其他微服务需要相关的基础组件,直接添加即可,无需再在自己的配置文件中单独去写这些配置,若需要特殊配置单独配置即可。
关于动态刷新配置: 需要在类上添加
@RefreshScope
注解才能实现动态刷新
Nacos原理简析
nacos作为注册中心:其实就是实现了spring-cloud定义的ServerRegistry
接口NacosServerRegistry
;在系统启动后会去监听spring的启动事件然后自动装配相关配置;进行服务的注册,同时会通过schedule线程池提交定时调度任务,向nacos服务端发送心跳(其实就是定时调用http接口)。
nacos服务端会通过ConcurrentHashMap来记录注册的服务信息,同时服务端会定时去检查这些注册服务的心跳;如果是集群部署会进行数据同步。
由于客户端会定时向nacos服务发送心跳,同时获取注册表信息;为了支持高并发,Nacos采用多级缓存策略来实现注册表的读写,不同于eureka的方式,nacos使用的copyWrite思想,它是先拷贝一份内存中的配置,然后在这份拷贝内存里面进行更新相关操作,之后再将这个复制回去。
nacos作为配置中心:nacos客户端会做一个超时时间为30s的长轮询的http请求,nacos服务端收到请求后会判断配置是否更新过,如果更新过那么就会立即返回结果,否则会一直等待30s左右(在这个等待期间如果发现配置更新了也会立即将更新结果返回给客户端)才会返回结果告知客户端配置没有更新;注意如果配置没有更新那么才会等待30s,否则是直接拿到返回结果的。
高可用性:nacos集群部署时会基于raft算法(就是在leader机器挂了后,follower的机器会选举新的leader,其规则就是这些follower通过投票,得到票数过半的机器成功新的leader)来保证集群的高可用性。