Nacos是什么

Nacos提供了统一配置管理、服务发现与注册。 其中服务注册和发现的功能,相当于dubbo里面使用到
的zookeeper、 或者spring cloud里面应用到的consoul以及eureka。

Nacos的特性

服务发现和服务健康监测

Nacos提供了基于RPC的服务发现,服务提供者可以将自身的服务通过原生API或者openApi来实现服务
的注册,服务消费者可以使用API或者Http来查找和发现服务
同时,Nacos提供了对服务的实时监控检查,当发现服务不可用时,可以实现对服务的动态下线从而阻
止服务消费者向不健康的服务发送请求。

配置管理

传统的配置管理,是基于项目中的配置文件来实现,当出现配置文件变更时需要重新部署,而动态配置
中心可以将配置进行统一的管理,是的配置变得更加灵活以及高效。
动态配置中心可以实现路由规则的动态配置、限流规则的动态配置、动态数据源、开关、动态UI等场景
国内比较有名的开源配置中心: Aollo / diamond / disconf

简述服务配置中心和注册中心

服务注册中心
image.png
服务配置中心

image.png

Ncos的基本应用

Nacos的下载

首先,我们需要先启动Nacos服务,启动服务有两种方式,一种是直接下载已经编译好的包直接运行。
另一种是通过源码来构建。

从github上下载源码

  1. git clone https://github.com/alibaba/nacos.git
  2. cd nacos/
  3. mvn -Prelease-nacos clean install -U
  4. ls -al distribution/target/
  5. cd distribution/target/nacos-server-$version/nacos/bin

启动服务

linux系统下: sh startup.sh -m standalone
window系统: cmd startup.cmd

docker下启动

Nacos也可以直接通过docker安装。

  1. docker run -d --name nacos-server-8848 -p 8848:8848 --privileged=true -v
  2. /opt/nacos/init.d/custom.properties:/home/nacos/init.d/custom.properties -v
  3. /opt/nacos/logs:/home/nacos/logs --restart=always -e MODE=standalone -e
  4. PREFER_HOST_MODE=hostname nacos/nacos-server

访问nacos

http://localhost:8848/nacos
默认的帐号密码是:nacos/nacos

Nacos注册中心实战

创建一个项目

  • 创建一个spring-cloud-nacos的maven工程
  • 分别添加三个模块

    • spring-cloud-dubbo-sample-api
    • spring-cloud-dubbo-sample-provider
    • spring-cloud-dubbo-sample-consumer

      其中后面两个模块都是spring boot的应用。

  • 修改 spring-cloud-dubbo-sample-provider这个模块中。

  • 将dependencyManagement部分的依赖移动到parent pom.xml

    1. <properties>
    2. <java.version>11</java.version>
    3. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    4. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    5. <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
    6. <spring-cloud-alibaba.version>2.2.2.RELEASE</spring-cloud-alibaba.version>
    7. </properties>
    8. <dependencyManagement>
    9. <dependencies>
    10. <dependency>
    11. <groupId>org.springframework.boot</groupId>
    12. <artifactId>spring-boot-dependencies</artifactId>
    13. <version>${spring-boot.version}</version>
    14. <type>pom</type>
    15. <scope>import</scope>
    16. </dependency>
    17. <dependency>
    18. <groupId>com.alibaba.cloud</groupId>
    19. <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    20. <version>${spring-cloud-alibaba.version}</version>
    21. <type>pom</type>
    22. <scope>import</scope>
    23. </dependency>
    24. </dependencies>
    25. </dependencyManagement>
    26. <build>
    27. <plugins>
    28. <plugin>
    29. <groupId>org.apache.maven.plugins</groupId>
    30. <artifactId>maven-compiler-plugin</artifactId>
    31. <version>3.8.1</version>
    32. <configuration>
    33. <source>11</source>
    34. <target>11</target>
    35. <encoding>UTF-8</encoding>
    36. </configuration>
    37. </plugin>
    38. <plugin>
    39. <groupId>org.springframework.boot</groupId>
    40. <artifactId>spring-boot-maven-plugin</artifactId>
    41. <version>2.3.7.RELEASE</version>
    42. <configuration>
    43. <mainClass>com.yehui.springclouddubbosampleconsumer.SpringCloudDubboSampleConsumerApplication
    44. </mainClass>
    45. </configuration>
    46. <executions>
    47. <execution>
    48. <id>repackage</id>
    49. <goals>
    50. <goal>repackage</goal>
    51. </goals>
    52. </execution>
    53. </executions>
    54. </plugin>
    55. </plugins>
    56. </build>
  • 修改spring-cloud-dubbo-sample-provider中的pom.xml,增加parent模块的依赖

    1. <parent>
    2. <artifactId>spring-cloud-nacos</artifactId>
    3. <groupId>com.yehui</groupId>
    4. <version>1.0-SNAPSHOT</version>
    5. </parent>
    6. <dependencies>
    7. <dependency>
    8. <groupId>org.springframework.boot</groupId>
    9. <artifactId>spring-boot-starter</artifactId>
    10. </dependency>
    11. <dependency>
    12. <groupId>com.alibaba.cloud</groupId>
    13. <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    14. </dependency>
    15. <dependency>
    16. <groupId>com.alibaba.cloud</groupId>
    17. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    18. </dependency>
    19. <dependency>
    20. <groupId>com.alibaba.cloud</groupId>
    21. <artifactId>spring-cloud-starter-dubbo</artifactId>
    22. </dependency>
    23. <dependency>
    24. <groupId>com.yehui</groupId>
    25. <artifactId>spring-cloud-dubbo-sample-api</artifactId>
    26. <version>1.0-SNAPSHOT</version>
    27. </dependency>
    28. <dependency>
    29. <groupId>org.springframework.boot</groupId>
    30. <artifactId>spring-boot-starter-web</artifactId>
    31. </dependency>
    32. <dependency>
    33. <groupId>org.springframework.boot</groupId>
    34. <artifactId>spring-boot-starter-test</artifactId>
    35. <scope>test</scope>
    36. <exclusions>
    37. <exclusion>
    38. <groupId>org.junit.vintage</groupId>
    39. <artifactId>junit-vintage-engine</artifactId>
    40. </exclusion>
    41. </exclusions>
    42. </dependency>
    43. </dependencies>

定义服务接口

在spring-boot-dubbo-sample-api模块中,定义接口

  1. public interface IHelloService {
  2. String sayHello();
  3. }

实现服务

在spring-boot-dubbo-sample-provider中,实现IHelloService接口

  1. public class HelloServiceImpl implements IHelloService {
  2. @Override
  3. public String sayHello() {
  4. return "hello yehui";
  5. }
  6. }

添加 @EnableDiscoveryClient注解

  1. @SpringBootApplication
  2. @EnableDiscoveryClient
  3. public class SpringCloudDubboSampleProviderApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(SpringCloudDubboSampleProviderApplication.class, args);
  6. }
  7. }

配置dubbo服务发布

在服务实现类中添加 @DubboService注解

  1. @DubboService
  2. public class HelloServiceImpl implements IHelloService {
  3. @Override
  4. public String sayHello() {
  5. return "hello yehui";
  6. }
  7. }

配置dubbo提供方信息

bootstrap.properties

  1. # Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html
  2. # Nacos认证信息
  3. spring.cloud.nacos.config.username=nacos
  4. spring.cloud.nacos.config.password=nacos
  5. spring.cloud.nacos.config.contextPath=/nacos
  6. # 设置配置中心服务端地址
  7. spring.cloud.nacos.config.server-addr=localhost:8848
  8. # Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可
  9. # spring.cloud.nacos.config.namespace=
  10. # Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口
  11. spring.cloud.nacos.discovery.server-addr=localhost:8848

application.properties

  1. # 应用名称
  2. spring.application.name=spring-cloud-dubbo-sample-provider
  3. # dubbo 协议
  4. dubbo.protocol.id=dubbo
  5. dubbo.protocol.name=dubbo
  6. # dubbo 协议端口( -1 表示自增端口,从 20880 开始)
  7. dubbo.protocol.port=-1
  8. # Dubbo 消费端订阅服务端的应用名,多个服务提供者用逗号分隔
  9. # 这里订阅"自己",会被忽略掉,请根据实际情况添加
  10. dubbo.cloud.subscribed-services=spring-cloud-dubbo-sample-provider
  11. # dubbo 服务扫描基准包
  12. dubbo.scan.base-packages=com.yehui.springclouddubbosampleprovider
  13. # 注册到 nacos 的指定 namespace,默认为 public
  14. spring.cloud.nacos.discovery.namespace=public
  15. server.port=8001

版本发布

项目的版本号格式为 x.x.x 的形式,其中 x 的数值类型为数字,从 0 开始取值,且不限于 0~9 这个范
围。项目处于孵化器阶段时,第一位版本号固定使用 0,即版本号为 0.x.x 的格式。
由于 Spring Boot 1 和 Spring Boot 2 在 Actuator 模块的接口和注解有很大的变更,且 spring-cloud
commons 从 1.x.x 版本升级到 2.0.0 版本也有较大的变更,因此我们采取跟 SpringBoot 版本号一致的版本:

  • 1.5.x 版本适用于 Spring Boot 1.5.x
  • 2.0.x 版本适用于 Spring Boot 2.0.x
  • 2.1.x 版本适用于 Spring Boot 2.1.x
  • 2.2.x 版本适用于 Spring Boot 2.2.x

    构建服务消费者

  • 加jar包依赖

    1. <parent>
    2. <artifactId>spring-cloud-nacos</artifactId>
    3. <groupId>com.yehui</groupId>
    4. <version>1.0-SNAPSHOT</version>
    5. </parent>
    6. <dependencies>
    7. <dependency>
    8. <groupId>org.springframework.boot</groupId>
    9. <artifactId>spring-boot-starter</artifactId>
    10. </dependency>
    11. <dependency>
    12. <groupId>com.alibaba.cloud</groupId>
    13. <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    14. </dependency>
    15. <dependency>
    16. <groupId>com.alibaba.cloud</groupId>
    17. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    18. </dependency>
    19. <dependency>
    20. <groupId>com.alibaba.cloud</groupId>
    21. <artifactId>spring-cloud-starter-dubbo</artifactId>
    22. </dependency>
    23. <dependency>
    24. <groupId>org.springframework.boot</groupId>
    25. <artifactId>spring-boot-starter-test</artifactId>
    26. <scope>test</scope>
    27. <exclusions>
    28. <exclusion>
    29. <groupId>org.junit.vintage</groupId>
    30. <artifactId>junit-vintage-engine</artifactId>
    31. </exclusion>
    32. </exclusions>
    33. </dependency>
    34. <dependency>
    35. <groupId>com.yehui</groupId>
    36. <artifactId>spring-cloud-dubbo-sample-api</artifactId>
    37. <version>1.0-SNAPSHOT</version>
    38. </dependency>
    39. <dependency>
    40. <groupId>org.springframework.boot</groupId>
    41. <artifactId>spring-boot-starter-web</artifactId>
    42. </dependency>
    43. </dependencies>
  • 添加配置文件

bootstrap.properties

  1. spring.application.name=spring-cloud-dubbo-sample-consumer
  2. dubbo.application.name=spring-cloud-dubbo-sample-consumer
  3. spring.cloud.nacos.discovery.server-addr=localhost:8848
  4. server.port=8003

application.properties

  1. # dubbo 协议
  2. dubbo.protocol.id=dubbo
  3. dubbo.protocol.name=dubbo
  4. # dubbo 协议端口( -1 表示自增端口,从 20880 开始)
  5. dubbo.protocol.port=-1
  6. # Dubbo 消费端订阅服务端的应用名,多个服务提供者用逗号分隔
  7. # 这里订阅"自己",会被忽略掉,请根据实际情况添加
  8. dubbo.cloud.subscribed-services=spring-cloud-dubbo-sample-provider
  9. # dubbo 服务扫描基准包
  10. dubbo.scan.base-packages=com.yehui.springclouddubbosampleconsumer
  11. # Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html
  12. # Nacos认证信息
  13. spring.cloud.nacos.discovery.username=nacos
  14. spring.cloud.nacos.discovery.password=nacos

除应用名称 spring.application.name 存在差异外, spring-cloud-dubbo-client-sample 新增了属性 dubbo.cloud.subscribed-services 的设置。并且该值为服务提供方应用 “spring-cloud-dubbo-sample-provider”。它的主要作用是服务消费方订阅服务提供方的应用名称的列表,若需订阅多应用,使用 “,” 分割。不推荐使用默认值为 “*”,它将订阅所有应用。

编写测试代码

  1. @RestController
  2. @EnableDiscoveryClient
  3. @SpringBootApplication
  4. public class SpringCloudDubboSampleConsumerApplication {
  5. public static void main(String[] args) {
  6. SpringApplication.run(SpringCloudDubboSampleConsumerApplication.class, args);
  7. }
  8. @DubboReference
  9. IHelloService helloService;
  10. @GetMapping("/say")
  11. public String say(){
  12. return helloService.sayHello();
  13. }
  14. }

Nacos配置中心实战

添加jar包依赖

  1. <dependency>
  2. <groupId>com.alibaba.cloud</groupId>
  3. <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  4. </dependency>

bootstrap.properties

需要注意,配置中心的ip,需要放在bootstrap.properties文件中,因为需要保证优先级。

  1. spring.cloud.nacos.config.server-addr=localhost:8848

NacosConfigController

创建一个controller,用来测试从nacos配置中心获取数据的场景
dataId 可以认为是一个配置集,一个系统可以有多个配置集,一般我们可以使用包名来命名,从而很好
的达到数据分类的目的, 测试的话配置的是应用的名称
groupId 配置分组,这个和dataId类似,但是它的纬度更高一些,可能是基于项目层面进行划分
autoRefreshed 自动更新配置

  1. @RefreshScope
  2. @RestController
  3. public class NacosCongController {
  4. @Value("${info:hello Nacos}")
  5. private String info;
  6. @GetMapping("/get")
  7. public String get(){
  8. return info;
  9. }
  10. }

测试过程

启动服务,访问http://localhost:8080/get ,浏览器会显示info的默认值,因为这个时候nacos还没有配置info的key进入控制台,增加配置,dataid=spring-cloud-dubbo-sample-consumer,groupid=spring-cloud-dubbo-sample-provider, 并且增加 info = xx的value属性再次刷新url,就可以读取到值的变化
image.png

关于Nacos Config配置解释

在 Nacos Spring Cloud 中, dataId 的完整格式如下:

  1. ${prefix}-${spring.profiles.active}.${file-extension}

prefix 默认为spring.application.name 的值,也可以通过配置项

  • spring.cloud.nacos.config.prefix来配置。
  • spring.profiles.active即为当前环境对应的 profifile,详情可以参考 。 注意:当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file**-**extension}
  • file-exetension为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。

Spring Boot集成Nacos

通过上面两个案例,我们了解了Nacos作为服务注册中心以及配置中心的基本使用。从使用过程中不难发现,它的整体部署和使用比Spring Cloud Netflix的Config以及Eureka要方便很多。另外,Nacos它是一个独立组件,不一定要集成到Spring Cloud中。有些公司没有采用spring cloud alibaba,而是直接把nacos作为一个独立组件使用也是可以的,再给大家演示一个Spring Boot集成Nacos实现动态配置和服务注册,虽然本质上是一样,但是在配置上会有一些细微的差异。

Spring Boot集成Nacos实现动态配置

创建spring boot应用
添加nacos配置中心的依赖

  1. <dependency>
  2. <groupId>com.alibaba.boot</groupId>
  3. <artifactId>nacos-config-spring-boot-starter</artifactId>
  4. <version>0.2.7</version>
  5. </dependency>

创建一个controller作为测试

  1. @RestController
  2. @NacosPropertySource(dataId = "spring-cloud-dubbo-sample-
  3. provider",autoRefreshed = true)
  4. public class TestController {
  5. @NacosValue(value = "${info:defailt value}",autoRefreshed = true)
  6. private String info;
  7. @GetMapping("/get")
  8. public String get(){
  9. return info;
  10. }
  11. }

修改application.properties文件

  1. nacos.config.server-addr=192.168.216.128:8848

Spring Boot集成Nacos实现注册中心

添加jar包依赖

  1. <dependency>
  2. <groupId>com.alibaba.boot</groupId>
  3. <artifactId>nacos-discovery-spring-boot-starter</artifactId>
  4. <version>0.2.7</version>
  5. </dependency>

创建一个测试类,用户返回当前nacos服务器上注册的服务列表

  1. @RestController
  2. public class ServiceController {
  3. @NacosInjected
  4. private NamingService namingService;
  5. @GetMapping("/discovery")
  6. public List<Instance> get(@RequestParam String serviceName) throws
  7. NacosException {
  8. return namingService.getAllInstances(serviceName);
  9. }
  10. @PostMapping("/registry")
  11. public void registry() throws NacosException {
  12. namingService.registerInstance("example","192.168.1.1",8888,"Test");
  13. }

修改aplication.properties文件

  1. nacos.discovery.server-addr=192.168.216.128:8848

先调用registry这个接口,向nacos注册服务
再访问 http://localhost:8080/discovery?serviceName=example获取指定服务的实例信息
也可以通过直接调用nacos server的服务注册接口进行服务注册

  1. http://127.0.0.1:8848/nacos/v1/ns/instance?
  2. serviceName=example&ip=127.0.0.1&port=8080

Nacos的整体架构

Nacos的整体架构还是比较清晰的,我们可以从下面这个官方提供的架构图进行简单分析。
image.png
Nacos的集群搭建
在前面的课程讲解过程中,我们部署的Nacos是一个standalone的模式。Nacos是可以支持集群部署
的,我们可以配置三台服务器做一个简单的测试
环境准备
准备三台服务器
192.168.216.128
192.168.216.129
192.168.216.130
下载编译好的包
https://github.com/alibaba/nacos/releases/download/1.3.2/nacos-server-1.3.2.tar.gz
配置数据源


需要注意的是,Nacos默认采用的是一个derby的内置数据库,在实际过程中,不建议使用这种数据
源。建议采用高可用数据库,比如我们使用mysql构建主从。
那我们可以使用mysql作为数据源来进行服务的配置。
导入mysql数据库脚本
修改nacos中application.properties文件内容

  1. #*************** Config Module Related Configurations ***************#
  2. ### If use MySQL as datasource:
  3. spring.datasource.platform=mysql
  4. ### Count of DB:
  5. db.num=1
  6. ### Connect URL of DB:
  7. db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?
  8. characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=
  9. true&useUnicode=true&useSSL=false&serverTimezone=UTC
  10. db.user=nacos
  11. db.password=nacos

启动nacos服务

启动nacos服务之前,需要配置集群
在nacos/conf目录下,有一个cluster.conf配置文件,在这个配置文件中配置这三个节点的ip和端口

  1. 192.168.216.128:8848
  2. 192.168.216.129:8848
  3. 192.168.216.130:8848

使用如下脚本分别启动这三台服务器
sh startup.sh