Spring Cloud Alibaba Nacos服务注册和配置中心
一、简介
1.1 Spring Cloud alibaba
Spring Cloud Netflix项目进入维护模式
将模块置于维护模式,意味着Spring Cloud团队将不会再向模块添加新功能。我们将修复block级别的bug以及安全问题,我们也会考虑并审查社区的小型pull request.我们打算继续支持这些模块,直到Greenwich版本被普遍采用至少一年。
于是便出现了Spring Cloud alibaba。
功能:
- 服务限流降级:默认支持Servlet、Feign、 RestTemplate、 Dubbo 和RocketMQ限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级Metrics监控。
- 服务注册与发现:适配Spring Cloud服务注册与发现标准,默认集成了Ribbon的支持。
- 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
- 消息驱动能力:基于Spring Cloud Stream为微服务应用构建消息驱动能力。
- 阿里云对象存储:阿里云提供的海量、安全、低成本、可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。
- 分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于Cron表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网
格任务支持海量子任务均匀分配到所有Worker (schedulerx client).上执行。
配置整合技术:
- Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
- Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
- RocketMQ:一款开源的分布式消息系统, 基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。
- Dubbo: Apache Dubbo"M是一款高性能 Java RPC框架。
Seata:阿里巴巴开源产品,一个易 于使用的高性能微服务分布式事务解决方案。 - Alibaba Cloud ACM:一款在分布式架构环境中对应用配置进行集中管理和推送的应用配置中心产品。
- Alibaba Cloud OSS:阿里云对象存储服务(Object Storage Service,简称OSS) , 是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。
- Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于Cron表达式)任务调度服务。
- Alibaba Cloud SMS:覆盖全球的短信服务,友好、效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。
官网:https://spring.io/projects/spring-cloud-alibaba#overview
中文资料:https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
1.2 Nacos简介(Dynamic Naming and Configuration Service)
前四个字母分别为Naming和Configuration的前两个字母,最后的s为Service,故叫Nacos。是一个更易于构建云原生应用的动态服务发现,配置管理和服务管理中心。Nacos就是注册中心+配置中心的组合,等价于Nacos = Eureka+Config+Bus。
作用:
- 替代Eureka做服务注册中心
- 替代Config做服务配置中心
官网介绍:https://nacos.io/zh-cn/index.html
Nacos支持AP和CP模式的切换:
C是所有节点在同一时间看到的数据是一 致的;而A的定义是所有的请求都会收到响应,P即分区容错性。
何时选择使用何种模式?
一般来说,如果不需要存储服务级别的信息且服务实例是通过nacos- client注册, 并能够保持心跳上报,那么就可以选择AP模式。当前主流的服务如Spring cloud和Dubbo服务,都适用于AP模式,AP模式为了服务的可能性而减弱了一 致性,因此AP模式下只支持注册临时实例。如果需要在服务级别编辑或者存储配置信息,那么CP是必须, K8S服务和DNS服务则适用于CP模式。CP模式下则支持注册持久化实例,此时则是以Raft协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。
切换(默认工作于AP模式):
curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
二、安装并运行Nacos
2.1 本地Java8+Maven环境已经OK
2.2 官网下载Nacos
2.3 运行
解压安装包,直接运行bin目录下的startup.cmd
2.4 测试
命令运行成功后直接访问http://localhost:8848/nacos,默认账号密码都是nacos。
结果页面:
三、Nacos作为服务注册中心
参考官方文档配置即可:https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html
3.1 基于Nacos的服务提供者
3.1.1 新建模块,pom文件添加依赖
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
3.1.2 application.yml 配置
server:
port: 9001
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848 #配置Nacos地址
3.1.3 主启动类
因为@SpringBootApplication里面有个@EnableAutoConfiguration
里面有个AutoConfigurationImportSelector会去classpth中找到spring.factory
而nacos的jar中配置了这个值,所以就可以不用加EnableDiscoverClient了
@EnableDiscoveryClient
@SpringBootApplication
public class PaymentMain9001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain9001.class,args);
}
3.1.4 测试业务类
@RestController
public class PaymentController
{
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/payment/nacos/{id}")
public String getPayment(@PathVariable("id") Integer id)
{
return "nacos registry, serverPort: "+ serverPort+"\t id"+id;
}
}
3.1.5 测试
浏览器访问:
http://lcoalhost:9001/payment/nacos/1
Nacos控制台:
可见nacos服务注册中心+服务提供者9001都ok了。
3.2 基于Nacos的服务消费者
3.2.1 新建模块,pom 添加依赖
<dependencies>
<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
spring-cloud-starter-alibaba-nacos-discovery 内部包含Ribbon 依赖故满足负载均衡。
3.2.1 yml配置
server:
port: 83
spring:
application:
name: nacos-order-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848
#消费者需要去访问的微服务名称(注册成功进nacos 的微服务提供者)
service-url:
nacos-user-service: http://nacos-payment-provider
3.2.3 主启动类
@EnableDiscoveryClient
@SpringBootApplication
public class OrderNacosMain83
{
public static void main(String[] args)
{
SpringApplication.run(OrderNacosMain83.class,args);
}
}
3.2.4 业务类
使用RestTemplate 方式访问服务提供者的业务,当然也可以添加OpenFeign依赖,使用接口绑定方式。
配置类,交由Spring 管理RestTemplate及实现负载均衡。
@Configuration
public class ApplicationContextConfig
{
@Bean
@LoadBalanced
public RestTemplate getRestTemplate()
{
return new RestTemplate();
}
}
业务类:
@RestController
@Slf4j
public class OrderNacosController
{
@Resource
private RestTemplate restTemplate;
@Value("${service-url.nacos-user-service}")
private String serverURL;
@GetMapping(value = "/consumer/payment/nacos/{id}")
public String paymentInfo(@PathVariable("id") Long id)
{
return restTemplate.getForObject(serverURL+"/payment/nacos/"+id,String.class);
}
}
3.2.5 新建服务提供者9002
根据服务提供者9001 新建一个类似的模块9002,便于轮询测试。配置都是类似的。
或者取巧不想新建重复体力劳动,直接拷贝虚拟端口映射:
结果:我这里避免和我新建的9002端口冲突,使用的是9011端口,可自行设置。
3.2.6 测试
访问:nacos控制台
http://localhost:8848/nacos
访问:
http://localhost:83/consumer/payment/nacos/13
结果:83访问9001/9002,轮询负载OK
四、Nacos作为服务配置中心
4.1 Nacos作为配置中心-基础配置
4.1.1 新建Module,添加pom依赖
<dependencies>
<!--nacos-config-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
4.1.2 yml 配置文件
Nacos同springcloud-config一样,在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后,才能保证项目的正常启动。
springboot中配置文件的加载是存在优先级顺序的, bootstrap优先级高于application.
bootstrap.yml
server:
port: 3377
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848 #服务注册中心地址
config:
server-addr: localhost:8848 #配置中心地址
file-extension: yml #指定yaml格式的配置
group: DEV_GROUP
namespace: dev_namespace
# ${spring.application.name}-${spring.profile.active}. ${spring.cloud.nacos.config.file-extension}
# nacos-config-client-dev.yml
application.yml
spring:
profiles:
#active: info
#active: test
active: dev
4.1.3 主启动类
@EnableDiscoveryClient
@SpringBootApplication
public class NacosConfigClientMain3377
{
public static void main(String[] args) {
SpringApplication.run(NacosConfigClientMain3377.class, args);
}
}
4.1.4 业务类
通过Spring Cloud原生注解@RefreshScope 实现配置自动更新
@RestController
@RefreshScope //用于刷新配置
public class ConfigClientController
{
@Value("${config.info}")
private String configInfo;
@GetMapping("/config/info")
public String getConfigInfo() {
return configInfo;
}
}
4.1.5 在Nacos中添加配置信息
4.1.5.1 Nacos中的匹配规则
Nacos中的dataid的组成格式与SpringBoot配置文件中的匹配规则:
4.1.5.2 配置新增
设置DataId:
${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
- prefix默认为spring.application.name的值
- spring.profile.active既为当前环境对应的profile,可以通过配置项spring.profile.active
- file-exetension为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension配置
总结:
4.1.6 测试
启动前需要确认在nacos客户端-配置管理栏目下有没有对应的yaml配置文件,若没有启动会报错。
调用接口查看配置信息:
http://localhost:3377/config/info
可以发现能够访问到自己在Nacos刚创建的配置文件中的信息。
自带动态刷新:修改下Nacos中的yaml配置文件,再次调用查看配置的接口,就会发现配置已经刷新。不用像Config一样还要发送一个http请求来通知配置中心发生变化。
1、如何使用Nacos作为配置中心统一管理配置
1)、引入依赖,
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2)、创建一个bootstrap.properties。
spring.application.name=gulimall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
3)、需要给配置中心默认添加一个叫 数据集(DataId)gulimall-coupon.properties。默认规则,应用名.properties
4)、给应用名.properties 添加任何配置
5)、动态获取配置。
@RefreshScope:动态获取并刷新配置
@Value("${配置项的名}"):获取到配置。
如果配置中心和当前应用的配置文件中都配置了相同的项,优先使用配置中心的配置。
2、细节
1)、命名空间:配置隔离; 默认:public(保留空间);默认新增的所有配置都在public空间。
1、开发,测试,生产:利用命名空间来做环境隔离。
注意:在bootstrap.properties;配置上,需要使用哪个命名空间下的配置,
spring.cloud.nacos.config.namespace=9de62e44-cd2a-4a82-bf5c-95878bd5e871
2、每一个微服务之间互相隔离配置,每一个微服务都创建自己的命名空间,只加载自己命名空间下的所有配置
2)、配置集:所有的配置的集合
3)、配置集ID:类似文件名。 Data ID:类似文件名
4)、配置分组:默认所有的配置集都属于:DEFAULT_GROUP;
1111,618,1212
项目中的使用:每个微服务创建自己的命名空间,使用配置分组区分环境,dev,test,prod
3、同时加载多个配置集
1)、微服务任何配置信息,任何配置文件都可以放在配置中心中
2)、只需要在bootstrap.properties说明加载配置中心中哪些配置文件即可
3)、@Value,@ConfigurationProperties
以前SpringBoot任何方法从配置文件中获取值,都能使用。 配置中心有的优先使用配置中心中的
4.2 Nacos作为配置中心-分类配置
问题1:
实际开发中,通常一个 系统会准备
dev开发环境
test测试环境
prod生产环境。
如何保证指定环境启动时服务能正确读取到Nacos.上相应环境的配置文件呢?
问题2:
一个大型分布式微服务系统会有很多微服务子项目,
每个微服务项目又都会有相应的开发环境、测试环境、预发环境、正式环境…
那怎么对这些微服务配置进行管理呢?
4.2.1 Nacos的图形化管理界面
4.2.2 Namespace+Group+Data ID三者关系
类似Java里面的package名和类名
最外层的namespace是可以用于区分部署环境的,Group和DatalD逻辑 上区分两个目标对象。
默认情况:
-
Namespace=public, Group=DEFAULT_GROUP,默认Cluster是DEFAULT
-
Nacos默认的命名空间是public, Namespace主要用来实现隔离。比方说我们现在有三个环境:开发、测试、生产环境,我们就可以创建三个Namespace, 不同的Namespace之间是隔离的。
-
Group默认是DEFAULT_ GROUP, Group可以把不同的微服务划分到同一个分组里面去
-
Service就是微服务; 一个Service可以包含多个Cluster (集群),Nacos默认Cluster是DEFAULT, Cluster是对指定微服务的一个虚拟划分。比方说为了容灾,将Service微服务分别部署在了杭州机房和广州机房,这时就可以给杭州机房的Service微服务起一个集群名称(HZ) ,给广州机房的Service微服务起一个集群名称 (GZ), 还可以尽量让同一个机房的微服务互相调用,以提升性能。
-
最后是Instance,就是微服务的实例。
4.2.3 Data ID方案
指定spring.profile.active和配置文件的DataID来使不同环境下读取不同的配置。
默认空间+默认分组+新建dev和test两个DataID:
通过spring.profile.active属性就能进行多环境下配置文件的读取
测试:
http://localhost:3377/config/info
配置是什么就加载哪个的配置文件。
4.2.4 Group方案
通过Group实现服务分组区分:
4.2.5 Namespace方案
区分开发环境:
结果:
配置文件中指定Namespace 值为对应的 id.
五、Nacos集群和持久化配置(重要)
5.1 官网架构图(写的(┬_┬))
上图官网翻译,真实情况:
5.2 Nacos 配置说明
按照上述,我们需要mysql数据库。
参考:官网说明
5.3 Nacos持久化配置解释
Nacos默认自带的是嵌入式数据库derby,当使用Nacos集群时,每一个Nacos都有一个自己的嵌入式数据库,不易于管理,于是便可使用外部数据库mysql.
derby到mysql切换配置步骤:
- nacos-server-1.1.4\nacos\conf目录下找到sql脚本:nacos-mysql.sql
- 执行脚本
- nacos-server-1.1.4\nacos\conf目录下找到application.properties,添加配置
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=nacos_devtest #用户名
db.password=youdontknow #密码
- 启动nacos,可以看到是个全新的空记录界面,即使用了mysql数据库,作为配置持久化中心,以前是记录进derby
5.4 Linux 上搭建集群
服务器上搭建mysql数据库集群配置,Nginx反向代理集群配置,及Nacos集群实现Nacos集群及持久化操作,可以统一管理配置文件。架构图如上面所介绍,具体配置待续…