9--SpringCloud Alibaba:Nacos周阳老师
2021:9--SpringCloud Alibaba:Nacos
https://www.cnblogs.com/coderD/p/14350076.html SpringCloud
https://www.cnblogs.com/coderD/p/14350073.html SpringCloud 和 Eureka
https://www.cnblogs.com/coderD/p/14350082.html SpringCloud 和 Zookeeper
https://www.cnblogs.com/coderD/p/14350086.html SpringCloud-Ribbon/OpenFeign
https://www.cnblogs.com/coderD/p/14350091.html SpringCloud:Hystrix 断路器
https://www.cnblogs.com/coderD/p/14350097.html SpringCloud:服务网关 gateway
https://www.cnblogs.com/coderD/p/14350099.html SpringCloud:Config/Bus
https://www.cnblogs.com/coderD/p/14350103.html SpringCloud:Stream/Sleuth
https://www.cnblogs.com/coderD/p/14350110.html SpringCloud Alibaba:Nacos
https://www.cnblogs.com/coderD/p/14350114.html SpringCloud Alibaba:Sentinel
https://www.cnblogs.com/coderD/p/14350119.html SpringCloud Alibaba:Seata
代码:https://gitee.com/xue--dong/spring-cloud
阳哥脑图:https://gitee.com/xue--dong/spring-cloud
SpringCloudAlibaba 简介
1. 为什么出现 SpringCloud Alibaba
因为Spring Cloud NetFlix很多项目进入维护模式:
复制代码
维护模式:
意味着SpringCloud 团队将不会再向模块添加新的功能,只会修复打的bug。
而且在Greenwich版本普及一年后,将不再支持这些模块。
复制代码
2. SpringCloud Alibaba 带来了什么
诞生:
2018.10.31,Spring Cloud Alibaba 正式入驻了Spring Cloud 官方孵化器,并在Maven中央
仓库发布了第一个版本。
复制代码
<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. SpringCloud Alibaba 学习资料获取
Spring Cloud Alibaba Nacos 服务注册和配置中心
对应着我们前面学的:Eureka/Consul/Zookeeper Config+Bus
复制代码
1 Nacos 简介
前4个字母分别为Naming和Configuration的前两个字母,最后的s为service
复制代码
1.1 是什么
一个更易于构建云原生应用的动态服务发现,配置管理和服务管理平台。
Nacos:Dynamic Naming and Configuration Service
Nacos就是注册中心+配置中心的组合。
等价于:Eureka + Config + Bus
复制代码
1.2 能干嘛
替代Eureka做服务注册中心
替代Config做服务配置中心
复制代码
2 Nacos 的安装
本地Java8+Maven环境已经OK
下载完成后,解压安装包,直接运行bin目录下的startup.cmd
复制代码
命令运行成功后直接访问:
http://localhost:8848/nacos
http://localhost:8848/nacos/#login
复制代码
成功安装:
用户名/密码:nacos/nacos
复制代码
Nacos 作为服务注册中心演示
1. 基于 Nacos 的服务提供者
1.1 新建 Module
cloudalibaba-provider-payment9001
复制代码
1.2 POM
1. 父POM
复制代码
<!--spring cloud 阿里巴巴-->
<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>
复制代码
2. 子POM
复制代码
<dependencies>
<!--spring cloud alibaba nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--web/actuator这两个一般一起使用,写在一起-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--监控-->
<dependency>
<groupId>
org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
复制代码
1.3 yml
server:
port: 9001
spring:
application:
name: naocs-payment-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848
# 做监控的话:要把这个全部暴露出来
management:
endpoints:
web:
exposure:
include: "*" # 注意是双引号
复制代码
1.4 主启动类
@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain9001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain9001.class, args);
}
}
复制代码
1.5 业务类
@RestController
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/payment/nacos/{id}")
public String getPayment(Integer id){
return "nacos registry, serverPort: "+ serverPort+"\t id"+id;
}
}
复制代码
1.6 测试
这里不像eureka还要写注册中心微服务,直接安装打开nacos即可。
启动9001:成功注册
复制代码
测试成功:
nacos服务注册中心+服务提供者9001都OK了。
复制代码
1.7 相同的配置再新建一个 module 9002
1. 步骤略...
2. 这里可以有一个取巧的方法:
虚拟映射一个和9001配置相同的9011微服务,端口是9011
复制代码
2. 基于 Nacos 的服务消费者
Nacos天生就支持负载均衡。
复制代码
2.1 新建 Module
cloudalibaba-consumer-nacos-order83
复制代码
2.2 pom
nacos天生就支持负载均衡的
复制代码
Ribbo:支持负载均衡,自带RestTemplate
复制代码
<dependencies>
<!--spring cloud alibaba nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--引入我们自定义的公共api jar包-->
<dependency>
<groupId>com.atguigu.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--web/actuator这两个一般一起使用,写在一起-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--监控-->
<dependency>
<groupId>
org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
复制代码
2.3 yml
server:
port: 83
spring:
application:
name: naocs-order-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848 # 配置nacos注册中心地址
# 消费者将要去访问的微服务名称(成功注册进nacos的微服务提供者)
server-url:
nacos-user-service: http://nacos-payment-provider
复制代码
2.3 主启动类
@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain83 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain83.class, args);
}
}
复制代码
2.4 业务类
@Configuration
public class ApplicationContextConfig {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
@RestController
@Slf4j
public class OrderNacosController {
@Value("${server-url.nacos-user-service}")
private String serverURL;
@Resource
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/nacos/{id}")
public String paymentInfo(@PathVariable("id") Long id){
return restTemplate.getForObject(serverURL+"/payment/nacos/"+id, String.class);
}
}
复制代码
2.5 启动测试
测试请求:http://localhost:83/consumer/payment/nacos/1
单纯测试:没有查数据库。
复制代码
报错1:
发生在我们根据微服务名http://nacos-payment-provider,去调用微服务。
抛出一个UnknownHostException:未知的主机名异常。
因为这个主机名nacos-payment-provider对应的微服务有两个实例,他不知道用哪个,所以会报错。
复制代码
解决:
加上负载均衡注解:@LoadBalanced
复制代码
再次报错2:
复制代码
分析:
9001/9002自测都成功,而且也都注册了进去。
但是通过服务名找不到服务实例?
仔细看了看发现服务名写错了:
复制代码
再次测试:
测试成功,而且默认带有负载均衡。
复制代码
Nacos 注册中心 -- 基础配置
Nocas支持模式是可以切换的:AP/CP
复制代码
Nacos与其他注册中心特性对比:
复制代码
Nacos 支持 AP 和 CP 模式的切换
C: 所有节点在同一时间看到的数据是一致的。强一致性
A: 定义是所有的请求都可以被响应,最起码回复一个兜底的回复。高可用性
何时使用何种模式:
AP模式:
如果不需要存储服务级别的信息且服务实例是通过nacos-client注册,并能够保持心跳上限,那么就
可以选择AP模式。
当前主流的服务如Spring Cloud和Dubbo服务,都是用于AP模式。
AP模式为了服务的可能性而减弱了一致性,因此AP模式下只支持注册临时实例。
CP:
如果需要在服务级别编辑或存储配置信息,那么CP是必须的,K8S服务和DNS服务则适用于CP模式。
CP模式下则支持注册持久化实例,此时则是以Raft协议为集群运行模式,该模式下注册实例之前
必须先注册服务,如果服务不存在,则会返回错。
怎么切换:
curl -X PUT '$NACOS_SERVER:8848/nacos/vi/ns/operator/switches?entry=serverMode&value=CP'
复制代码
Nacos 作为 Config 服务注册中心
所有的配置信息,以前我们写到了GitHub上,用Config+Bus来进行自动刷新和动态的更新。
现在我们可以直接把配置文件写进nacos,然后再用nacos做类似于config这样的功能。
从nacos上抓取我们的配置信息。
复制代码
1. Nacos 作为配置中心 -- 基础配置
主要添加一个:nacos-config
复制代码
<!--nacos-config-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
复制代码
1.1 新建 mudole:作为服务配置客户端
cloudalibaba-config-nacos-client3377
复制代码
1.2 POM
<dependencies>
<!--nacos-config-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--nacos-discovery-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--web/actuator这两个一般一起使用,写在一起-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--监控-->
<dependency>
<groupId>
org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
复制代码
1.3 主配置类
@SpringBootApplication
@EnableDiscoveryClient
public class NacosConfigClientMain3377 {
public static void main(String[] args) {
SpringApplication.run(NacosConfigClientMain3377.class, args);
}
}
复制代码
1.4 yml
Nacos同springcloud-config一样,在项目初始化时,要保证先从配置中心进行配置拉取。
拉去配置后,才能保证项目的正常启动。
springboot中配置文件的加载是存在优先级顺序的:bootstrap优先级高于application
全局的放在:bootstrap.yml
自己的放在:application.yml
1. bootstrap.yml
微服务端口:3377,服务名nacos-config-client,
注册进localhost:8848
作为配置客户端
再去服务注册中心读一个yaml的配置文件
复制代码
server:
port: 3377
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848 # Nacos服务注册中心地址
config:
server-addr: localhost:8848 # Nacos作为配置中心地址
file-extension: yaml # 指定yaml格式的配置
复制代码
2. application.yml
复制代码
spring:
profiles:
active: dev # 表示找一个开发环境的配置文件
复制代码
1.5 业务类
@RestController
@RefreshScope //支持Nacos的动态刷新功能
public class ControllerClientController {
@Value("${config.info}") //在Nacos配置中心的配置文件内容
private String configInfo;
@GetMapping("/config/info")
public String getConfigInfo(){
return configInfo;
}
}
复制代码
1.6 在 Nacos 中添加配置信息
Nacos中的匹配规则:
1. 理论:Nacos中的Data Id的组成格式及与SpringBoot配置文件中的匹配规则
复制代码
在Nacos Spring Cloud中,Data Id的完整格式如下:
${prefix}-${spring.profile.active}.${file-extension}
其中:
${prefix}:为spring.application.name 的值
${spring.profile.active}:
即为当前环境对应的profile
当为空时,- 也将不存在,拼接格式变成:${prefix}.${file-extension}
${file-extension}:配置文件的数据格式,一般是 properties/yaml
注意:nacos没有yml,只识别yaml。
最终的公式:
复制代码
${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
结果:nacos-config-client-dev.yaml 这也是我们要在nacos中配置的文件名。
对应着配置文件上的这些:
复制代码
规则图:
复制代码
2. 配置新增
复制代码
1.7 测试
1. 发送请求:http://localhost:3377/config/info
测试成功:
复制代码
2. 自带刷新功能
修改Nacos中的yaml配置文件,再次调用查看配置的接口,就会发现配置刷新了
复制代码
2. Nacos 作为配置中心 -- 分类配置
2.1 分布式开发中的:多环境多项目管理
问题1:
实际开发中,通常一个系统会准备:
dev 开发环境
test 测试环境
prod 生产环境
如何保证指定环境启动时服务能正确读取到Nacos上相应环境的配置文件呢?
问题2:
一个大型分布式微服务系统会有很多微服务子项目
每个微服务项目又都会有相应的开发环境,测试环境,预发环境,正式环境......
那怎么对这些微服务配置进行管理呢?
复制代码
2.2 Namespace+Group_Data ID 三者关系?
最外层的namespace用于区分部署环境的
Group和Data ID逻辑上区分两个目标对象
复制代码
默认情况:
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,就是微服务实例。
复制代码
2.3 案例 1:DataID 方案
指定spring.profile.active和配置文件的DataID来使不同环境下读取不同的配置
默认空间+默认分组+新建dev和test两个DataID
通过spring.profile.active属性就能进行多环境下配置文件的读取
1. 新建dev配置DataID
复制代码
2. 新建test配置DataID
复制代码
3. 默认的名称空间:public
复制代码
4. 通过spring.profile.active属性就能进行多环境下配置文件的读取
想加载那个DataID就配置哪个
复制代码
为什么可以这样映射:因为DataID的命名规则和Nacos进行文件匹配的规则
复制代码
5. 测试:
复制代码
测试成功
复制代码
2.4 案例 1:DataID 方案 小结
只通过Data ID 就可以切换加载不同的配置文件。
主要原因是Data ID命名组成规则:
在配置文件中进行相关配置即可。
复制代码
2.5 案例 2:分组 Group 方案
通过Group实现环境分区
1. 新建一个配置文件,添加分组DEV_GROUP
复制代码
2. 新建一个配置文件,添加分组TEST_GROUP
复制代码
3. 此时我们的DataID一样,但是Group不一样。
复制代码
4. bootstrap+application操作
在config下增加一条group的配置即可,可配置为DEV_GROUP或TEST_GROUP
复制代码
5. 测试:http://localhost:3377/config/info
复制代码
2.6 案例 2:分组 Group 方案 小结
案例一,是在默认名称空间namespace下,创建的两个不同的DataID,都在默认的分组下。
我们也可以新建DataID两个相同的配置文件,但是指定不同的分组(环境),再通过在配置
文件中添加相关的配置,即可指定。
复制代码
2.7 案例 7:分组 Namespace 方案
1. 新建dev/test的Namespace:
复制代码
2. 回到服务管理-服务列表查看
复制代码
3. 在这两个新建的namespace中分别新建三个不同分组的配置文件
复制代码
4. 在配置文件中指定Namespace
复制代码
5. 测试:报错
复制代码
只要是这种报错,那么一定是对应关系没写好,client在nacos中没找到对应的配置文件,
或者配置文件中没写config.info="xxxxxx"
查错后再测试:测试成功
复制代码
Nacos 集群和持久化配置 --- 很重要
我们之前在学eureka时,配置了两个eureka注册中心微服务。
学些nacos时,不用我们在单独新建注册中心微服务模块了,直接安装使用即可,很方便。
但是:如果这个注册中心挂了怎么办,我们之前就只开了一个nacos程序,也没有配置集群。
显然,实际情况中不可能只有一个nacos注册中心。
复制代码
1. 官网说明
1. 架构图
复制代码
2. 要将配置持久化到数据库中:MySQL
不用它内嵌的数据库
复制代码
3. 通俗易懂的Nacos集群架构图
复制代码
4. 重点说明:
默认Nacos使用嵌入式数据库实现数据存储。
我们重启nacos后,还是有以前的配置文件的。
但是如果启动多个默认配置下的Nacos节点,数据存储是存在一致性问题的。
每个nacos都有自己独立呃嵌入式数据库,存放的数据不一致。
为了解决这个问题,Nacos采用了集中式存储的方式来支持集群化部署,目前只支持MySQL存储。
Nacos支持三种部署模式:
单机模式:用于测试和单机试用
集群模式:用于生产环境,确保高可用
多集群模式:用于多数据中心场景
复制代码
2. Linux 版 Nacos+MySQL 生产环境配置
Nacos默认自带的是嵌入式数据局 derby,那么如果做集群时每个Nacos都带一个derby,那么就有三个
存储配置文件的数据库,显然数据的统一性会有问题。
复制代码
2 derby 切换到 mysql 配置步骤
1. nacos-server-1.2.0\nacos\conf目录下找到sql脚本:
nacos-mysql.sql
执行脚本
注意:库自己创建 naocs_config
2. nacos-server-1.2.0\nacos\conf目录下找到application.properties
将derby中的配置文件迁到mysql中
复制代码
修改:注意端口,用户名和密码
复制代码
3. 启动nacos,可以看到是个全新的空记录界面,记录进derby的迁移了:
复制代码
刷新之后,以前的配置都没了,说明我们数据库迁移成功了。
4. 在nacos新建配置文件时,会自动保存到mysql数据库中
复制代码
3. Linux 版 Nacos+MySQL 生产环境配置
注意注意注意:!!!!!!!!!
一定要先把环境准备好:
centos7 + maven3.2(以上) + mysql5.7 + JDK 1.8
docker装的mysql,我的nacos连不上去,怎么操作我不会。重新自己手动装了一个mysql后,好了。
建议上述软件全部用tar.gz包安装到centos7上。
具体安装步骤可以百度。
复制代码
3.1 linux 版 nacos 安装
大概:一个Nginx+3个nacos注册中心+1个Mysql
Nacos下载linux版安装:
复制代码
启动:进入bin目录,启动startup.sh
复制代码
3.2 集群配置步骤
1. Linux服务器上mysql数据库配置
执行:nacos-mysql.sql
远程连接该数据库,执行脚本
我将该脚本下载到windows上在sqlyog中执行的。
2. 修改pplication.properties配置文件
修改之前先备份一个
复制代码
修改,在复制到linux上:
复制代码
3. Linux服务器上nacos的集群配置cluster.conf
梳理出一个nacos集群中的3台nacos服务的端口号
hostname -I 或者 ip addr 查看ens33网卡的地址:注意是 I
复制代码
4. 编辑Nacos的启动脚本startup.sh,使他能够用接受不同的启动端口。
我们希望传递不同的端口号启动不同的nacos实例
注意是:O 不是0
复制代码
5. 测试是否配置好nacos
同时通过window浏览器访问:
http://192.168.111.130:3333/nacos/#/login
http://192.168.111.130:4444/nacos/#/login
http://192.168.111.130:5555/nacos/#/login
复制代码
6. Nginx的配置,由它作为负载均衡器
注意:Nginx的安装要先安装3个环境,参考web笔记
1. 所有的请求先访问1111,然后再从 / 目录下分流。
复制代码
2. 将这些注释掉走我们自己的代理
复制代码
3. upstream:
注意这里配置的是127.0.0.1:3333
复制代码
7. 1个Nginx+3个Nacos注册中心+1个Mysql
还要装一个JAVA,注意我的centos7是mimn版,所以里面里面没有自带的jdk,直接安装。
安装JDK1.8,参考web笔记。
1. 先启动nacos
[root@localhost bin]# ./startup.sh -p 3333
报错
复制代码
还要先装一个java
2. 启动nacos集群
[root@localhost bin]# ./startup.sh -p 3333
复制代码
启动成功。
[root@localhost bin]# ./startup.sh -p 4444
[root@localhost bin]# ./startup.sh -p 5555
ps -ef|grep nacos|grep -v grep|wc -l
3. 启动Nginx
[root@localhost sbin]# ./nginx -c /usr/local/nginx/conf/nginx.conf
查看一下:[root@localhost sbin]# ps -ef|grep nginx
成功启动
复制代码
nginx的关闭:
./nginx -s stop
./nginx -s quit
7. 测试通过Nginx访问nacos
关闭防火墙:sudo systemctl stop firewalld.service
一定要启动mysql,否则会报错:
http://192.168.92.130:1111/nacos/#/login
复制代码
测试成功!!!!!!
复制代码
3.3 nacos 集群部署成功
说明通过我们的1111端口,nginx成功的访问到我们的nacos服务器。nginx转发到这三个结点。
1. 新建一个配置文件
复制代码
2. 数据库查询
复制代码
3. 持久化成功!!
复制代码
3.4 微服务 cloudalibaba-provider-payment9002 启动注册进 nacos 集群
1. 修改yml
复制代码
server:
port: 9002
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
# server-addr: localhost:8848 # 配置nacos注册中心地址
# 注册进nacos集群
server-addr: 192.168.92.130:1111
# 做监控的话:要把这个全部暴露出来
management:
endpoints:
web:
exposure:
include: "*" # 注意是双引号
复制代码
2. 启动9002威武
3. 注册成功
复制代码
4 . 小结
到此为止,我们nacos在linux下的集群部署和持久化配置文件都弄好了。
复制代码