[02] Spring Cloud Alibaba 入门_Nacos 服务注册和配置中心

一、SpringCloud Alibaba Nacos 介绍

Nacos 全名为 Naming Configuration Service ,取 NamingConfiguration 的前两个字母和 Services,是配置管理和服务管理中心。

简单来说 Nacos = Eureka + Config + Bus,即 注册中心+配置中心的组合。替代 Eureka 做服务注册中心,替代 Config 做服务配置中心。

Nacos 下载及启动报错处理方式

各种注册中心比较

在这里插入图片描述

在这里插入图片描述

CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。

  • 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
  • 可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
  • 分区容忍性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。

例如:
如果在某个分布式系统中数据无副本, 那么系统必然满足强一致性条件, 因为只有独一数据,不会出现数据不一致的情况,此时C和P两要素具备,但是如果系统发生了网络分区状况或者宕机,必然导致某些数据不可以访问,此时可用性条件就不能被满足,即在此情况下获得了CP系统,但是CAP不可同时满足。

因此在进行分布式架构设计时,必须做出取舍。当前一般是通过分布式缓存中各节点的最终一致性来提高系统的性能,通过使用多节点之间的数据异步复制技术来实现集群化的数据一致性。

二、 当前项目结构介绍

当前项目中包含九个模块:

在这里插入图片描述

  • 公有API:cloud-api-commons
  • 服务提供者: cloud-provider-payment8001(增加 Sleuth)/8002 (端口号8001 和 8002 )
  • 服务消费者(restTemplate): cloud-consumer-order80 (端口号80 ,增加 Sleuth)
  • 服务消费者(OpenFeign): cloud-consumer-feign-order80(端口号80 )
  • 注册中心 Eureka: cloud-eureka-server7001(端口号7001 )
  • 使用断路器实现的服务提供者 (Hystrix):cloud-provider-hystrix-payment8001(端口号8001)
  • 使用断路器实现的服务消费者(Hystrix):cloud-consumer-feign-hystrix-order80(端口号80)
  • 服务监控(hystrixDashboard):cloud-consumer-hystrix-dashboard9001(端口号9001)
  • 网关(Gateway):cloud-gateway-gateway9527(端口号9527)

前文链接: https://blog.csdn.net/weixin_42547014/article/details/120334570
项目源码: https://gitee.com/zhangchouchou/spring-cloud-demo

三、搭建 Nacos 服务注册中心

查看 Spring Cloud Alibaba 版本

访问 Spring 官网,查看 Spring Cloud Alibaba 版本信息,当前最新的稳定版是 2.2.1

在这里插入图片描述

1. 基于 Nacos 的服务提供者

1). 父项目添加 Alibaba

 <!--spring cloud alibaba 2.2.1.RELEASE-->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-alibaba-dependencies</artifactId>
	<version>2.2.1.RELEASE</version>
	<type>pom</type>
	<scope>import</scope>
</dependency>

2). 新建Module,POM 增加引用

同样以 maven 的方式创建模块 cloudalibaba-provider-payment9001

创建完成后在 pom 中增加引用

	<dependencies>
        <!--alibaba nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <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>

3). 新增 YML

server:
  port: 9001

spring:
  application:
    name: nacos-payment-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #配置Nacos地址

management:
  endpoints:
    web:
      exposure:
        include: '*'  #默认只公开了/health和/info端点,要想暴露所有端点只需设置成星号

4). 添加启动类

包名仍与其余模块相同 org.zjh.springcloud

@EnableDiscoveryClient
@SpringBootApplication
public class AlibabaPaymentApplication {
    public static void main(String[] args) {
        SpringApplication.run(AlibabaPaymentApplication.class,args);
    }
}

5). 新增 Controller

@RestController
public class AlibabaPaymentController {
    @Value("${server.port}")
    private String serverPort;

    @GetMapping(value = "/payment/nacos/{id}")
    public String getPayment(@PathVariable("id") Long id) {
        return "nacos registry, serverPort: "+ serverPort+"\t id"+id;
    }
}

在这里插入图片描述

6). 测试

启动 9001 后访问 Nacos,可以看到刚刚启动的服务。

在这里插入图片描述

查看服务详情

在这里插入图片描述

访问服务 http://localhost:9001/payment/nacos/1,测试通过。

在这里插入图片描述

7). 新建 9002 端口

为了演示负载均衡,参照 9001 端口创建 9002 端口,这里直接采用拷贝虚拟端口映射的方式新建。

在 Services 面板中复制 9001

Services面板打开方式

在这里插入图片描述
修改启动类名称,配置端口号 -DServer.port=9002 ,点击 ok

在这里插入图片描述

在这里插入图片描述

右键启动

在这里插入图片描述
在这里插入图片描述

8). 测试

刷新 Nacos 页面,服务数增加

在这里插入图片描述

在这里插入图片描述

访问 9002 端口 http://localhost:9002/payment/nacos/1

在这里插入图片描述
再查看 9001 端口

在这里插入图片描述

测试通过。

2. 基于 Nacos 的服务消费者

1). 新建 Module

以 maven 形式新建模块 cloudalibaba-consumer-nacos-order83

2). POM 中新增引用

	<dependencies>
        <!--SpringCloud ailibaba nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.zjh.springclouddemo</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <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>

为什么nacos支持负载均衡

在这里插入图片描述

3). 添加 YML

server:
  port: 83

spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
#消费者将要去访问的微服务名称(成功注册进nacos的微服务提供者【可选】,注意:nacos-payment-provider含有IP和端口)
service-url:
  nacos-user-service: http://nacos-payment-provider

4). 新增启动类

包名与其余模块相同

package org.zjh.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@EnableDiscoveryClient
@SpringBootApplication
public class OrderNacosApplication {
    public static void main(String[] args){
        SpringApplication.run(OrderNacosApplication.class,args);
    }
}

5). RestTemplate 方式进行模块间调用

创建配置类

@Configuration   // 声明配置
public class ApplicationContextConfig{
    @Bean
    @LoadBalanced   // 声明使用负载均衡
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

创建 Controller

@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);
    }
}

测试

刷新 Nacos

在这里插入图片描述

访问 http://localhost:83/consumer/payment/nacos/1 进行负载均衡测试

在这里插入图片描述
在这里插入图片描述

四、Nacos 服务配置中心

1. 基础配置

1). 创建 Module,POM 中添加引用

以 Maven 形式创建新模块 cloudalibaba-config-nacos-client3377

<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>

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: yaml #指定yaml格式的配置(yml和yaml都可以)

#${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
#nacos-config-client-dev.yaml  (一定要与file-extension值保持一致)

application.yml

spring:
  profiles:
    active: dev #表示开发环境

3). 添加主启动类

package org.zjh.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@EnableDiscoveryClient
@SpringBootApplication
public class NacosConfigClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(NacosConfigClientApplication.class, args);
    }
}

4). 添加Controller

@RestController
@RefreshScope   //通过SpringCould原生注解@RefreshScope实现配置自动更新
public class ConfigClientController{
    @Value("${config.info}") //从nacos配置中心获取配置信息,对应nacos配置:nacos-config-client-dev.yaml
    private String configInfo;

    @GetMapping("/config/info")
    public String getConfigInfo() {
        return configInfo;
    }
}

5). 添加配置

访问 Nacos 界面,添加配置

在这里插入图片描述

在这里插入图片描述

Nacos Data ID 命名规则

上图中的 Data ID 是配置的标识,需要按照规范进行命名。

命名公式:${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

在这里插入图片描述
在这里插入图片描述
所以最后命名为: nacos-config-client-dev.yaml

Nacos Group

在这里插入图片描述

group表示分组,可以将配置信息根据项目分为不同的组,比如电商项目,医疗项目,在线教育等等。

Nacos 配置格式

Data ID 中是什么格式,配置格式中就选择什么格式

Nacos 配置内容

在之前的 Controller 中已经写好要获取 config.info

在这里插入图片描述

所以在配置内容加入下面内容,注意配置格式

config:
  info: "我是config.info,我来自配置中心"

都填写好以后点击发布

在这里插入图片描述

在这里插入图片描述

6). 测试

启动服务,访问 http://localhost:3377/config/info 进行测试

在这里插入图片描述

7). 自动刷新配置测试

进入 Nacos 对配置进行修改

在这里插入图片描述

在这里插入图片描述
修改完成后刷新访问界面,测试通过。

在这里插入图片描述

2. 分类配置

实际开发过程中可能会遇到很多问题,比如:

  • 通常一个系统会准备——dev开发环境、test测试环境、prod生产环境,那么如何保证指定环境启动时服务能正确读取到 Nacos上相应环境的配置文件呢?
  • 一个大型分布式微服务系统会有很多微服务子项目,每一个微服务项目又会有相应的开发环境、测试环境、预发环境、正式环境….那怎么对这些微服务配置进行管理呢?

为了应付这种情况,Nacos 采用了 Namespace(命名空间)、Group(分组)和 Data ID(配置标识)的方法来进行管理。

在这里插入图片描述

他们之间的关系如下图所示:

在这里插入图片描述

  • Nacos 默认的命名空间是public,主要用来实现隔离。
    比方说我们现在有三个环境:开发、测试、生产环境,我们就可以创建三个Namespace,不同的 Namespace之间是隔离的。

  • Group默认是DEFAULT_GROUP,Group可以把不同的微服务划分到同一个分组里面去。Service就是微服务;一个Service可以包含多个Cluster(集群),Nacos默认Cluster是DEFAULT,Cluster是对指定微服务的一个虚拟划分。
    比方说为了容灾,将Service微服务分别部署在了杭州机房和广州机房,这时就可以给杭州机房的Service微服务起一个集群名称(HZ),给广州机房的Service微服务起一个集群名字(GZ),还可以尽量让同一个机房的微服务互相调用,以提升性能。

  • Instance,就是微服务的实例。

接下来进行测试

1). 创建新的命名空间

在这里插入图片描述

2). 在各自的命名空间中加入新的分组和配置

public 下

在这里插入图片描述

test_dev 下

在这里插入图片描述

3). 切换分组

没有更改命名空间,没有更改部署环境(dev)

在 config 下增加一条 group 的配置即可限定分组。

在这里插入图片描述
重启服务,访问 http://localhost:3377/config/info 进行测试

在这里插入图片描述

4). 切换 Data ID

在限定 Group 的基础上,部署环境切换为 test

通过 spring.profile.active 属性就能进行多环境下配置文件的读取

在这里插入图片描述

在这里插入图片描述

5). 切换 Namespace

现在限定访问 test_dev 空间下的 DEV_GROUP 分组的 dev 开发环境的配置

在配置文件中添加 Namespace ID

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

五、Nacos 集群和持久化配置

1. 集群部署架构图

官网地址

vip : 代理服务器

推荐用户把所有服务列表放到一个vip下面,通过域名绑定这个 vip(代理服务器),并通过这个代理服务器将请求发给 Nacos1、Nacos2、Nacos3

在这里插入图片描述

2. 实际集群部署情况

Nacos 默认使用嵌入式数据库实现数据的存储。所以,如果启动多个默认配置下的Nacos节点,数据存储是存在一致性问题的。
为了解决这个问题,Nacos采用了集中式存储的方式来支持集群化部署,目前只支持MySQL 的存储。 也就是说,Nacos 部署信息持久化只能存到MySQL数据库中

在这里插入图片描述

3. Nacos 持久化配置

将 Nacos 配置信息持久化到 MySQL 数据库的方式在之前的下载安装 Nacos 的连接中已经介绍。具体位置在解决启动时报 Unable to start embedded Tomcat 错误的解决方式里

传送门:Nacos 下载及启动报错处理方式

4. 搭建 Nacos 集群

官方推荐使用 Linux 系统搭建集群

在这里插入图片描述

准备条件

传送门:Linux 系统下搭建Nacos集群详细教程


版权声明:本文为weixin_42547014原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。