Rubin's Blog

  • 首页
  • 关于作者
  • 隐私政策
享受恬静与美好~~~
分享生活的点点滴滴~~~
  1. 首页
  2. SpringCloud
  3. 正文

SpringCloud Alibaba之Nacos

2021年 10月 24日 1019点热度 0人点赞 0条评论

Nacos介绍

Nacos (Dynamic Naming and Configuration Service)是阿里巴巴开源的一个针对微服务架构中服务发现、配置管理和服务管理平台。

Nacos就是注册中心 + 配置中心的组合(Nacos = Eureka + Config + Bus)。官网:https://nacos.io 。下载地址:https://github.com/alibaba/Nacos。

Nacos功能特性有以下几点:

  • 服务发现与健康检查
  • 动态配置管理
  • 动态DNS服务
  • 服务和元数据管理(管理平台的⻆度,nacos也有一个ui⻚面,可以看到注册的服务及其实例信息(元数据信息)等),动态的服务权重调整、动态服务优雅下线,都可以去做

Nacos Server单例服务部署

下载解压安装包,执行命令启动(我们使用最近比较稳定的版本 nacos-server-1.4.2.tar.gz)

linux/mac:sh startup.sh -m standalone 
windows:cmd startup.cmd

访问Nacos管理界面:http://127.0.0.1:8848/nacos/#/login(默认端口8848, 账号和密码 nacos/nacos)。

Nacos Server集群

Nacos Server集群我们要安装3个及以上的实例。首先,我们复制解压后的nacos文件夹,分别命名为nacos-01、nacos-02、nacos-03。

我们使用同一台机器模拟,将上述三个文件夹中application.properties中的 server.port分别改为 8848、8849、8850,同时给当前实例节点绑定ip,因为服务器可能绑定多个ip:

nacos.inetutils.ip-address=127.0.0.1

接下来,我们复制一份conf/cluster.conf.example文件,命名为cluster.conf。在配置文件中设置集群中每一个节点的信息:

# 集群节点配置 
127.0.0.1:8848 
127.0.0.1:8849 
127.0.0.1:8850

最后,我们使用脚本启动每一个实例即可。需要注意的是:默认每一个Nacos Server需要至少2G的内存,生产环境下适当调整该参数。

sh startup.sh -m cluster

Nacos Server数据持久化

Nacos 默认使用嵌入式数据库进行数据存储,它支持改为外部Mysql存储:

  1. 新建数据库 nacos_config,数据库初始化脚本文件。文件位置在 ${nacoshome}/conf/nacos-mysql.sql
  2. 修改${nacoshome}/conf/application.properties,增加Mysql数据源配置如下
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?
characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456

Nacos 数据模型

Namespace命名空间、Group分组、集群这些都是为了进行归类管理,把服务和配置文件进行归类,归类之后就可以实现一定的效果,比如隔离。

举例来说,对于服务来说,不同命名空间中的服务不能够互相访问调用。

  • Namespace:命名空间,对不同的环境进行隔离,比如隔离开发环境、测试环境和生产环境
  • Group:分组,将若干个服务或者若干个配置集归为一组,通常习惯一个系统归为一个组
  • Service:某一个服务,比如简历微服务
  • DataId:配置集或者可以认为是一个配置文件

Namespace + Group + Service 如同 Maven 中的GAV坐标,GAV坐标是为了锁定 Jar,而这里是为了锁定服务。

Namespace + Group + DataId 如同 Maven 中的GAV坐标,GAV坐标是为了锁定 Jar,二这里是为了锁定配置文件。

最佳实践

Nacos抽象出了Namespace、Group、Service、DataId等概念,具体代表什么取决 于怎么用(非常灵活),推荐用法如下:

概念描述
Namespace代表不同的环境,如开发dev、测试test、生产环境prod
Group代表某项目
Service某个项目中具体xxx服务
DataId某个项目中具体的xxx配置文件

服务注册到Nacos注册中心上

我们以网关服务为例,我们在spring-cloud-demo模块中添加SCA的依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!--spring boot 父启动器依赖-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>

    <groupId>com.rubin</groupId>
    <artifactId>spring-cloud-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>scn</module>
        <module>sca</module>
        <module>gateway</module>
        <module>stream</module>
        <module>config-server</module>
        <module>zipkin-server</module>
        <module>authorization-server</module>
    </modules>
    <packaging>pom</packaging>

    <dependencies>
        <!--日志依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>
        <!--测试依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--lombok⼯具-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.4</version>
            <scope>provided</scope>
        </dependency>
        <!-- Actuator可以帮助你监控和管理Spring Boot应⽤-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--SCA -->
            <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>
            <!--SCA -->
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <!--编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
            <!--打包插件-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

网关服务pom添加以下依赖(注释eureka客户端依赖):

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

修改配置文件如下:

server:
  port: 9200
spring:
  application:
    name: gateway
  rabbitmq:
    host: rabbitmq-host
    port: 5672
    username: root
    password: 123456
  zipkin:
    # zipkin-server的请求地址
    base-url: http://zipkin-host:9500
    sender:
      # web 客户端将踪迹日志数据通过网络请求的方式传送到服务端,另外还有配置
      # kafka/rabbit 客户端将踪迹日志数据传递到mq进行中转
      type: web
  sleuth:
    sampler:
      # 采样率 1 代表100%全部采集 ,默认0.1 代表10% 的请求踪迹数据会被采集
      # 生产环境下,请求量非常大,没有必要所有请求的踪迹数据都采集分析,对于网络包括server端压力都是比较大的,可以配置采样率采集一定比例的请求的踪迹数据进行分析即可
      probability: 1
  cloud:
    nacos:
      discovery:
        # 配置nacos server地址
        server-addr: nacos-host:8848
        # 不配置默认注册到public命名空间
        namespace: 651d1e6f-4bf4-46b9-b5b0-1885a215dc12
    gateway:
      routes:
        - id: service-resume-router
          uri: lb://scn-service-resume
          predicates:
            - Path=/api-resume/**
          filters:
            - StripPrefix=1
        - id: service-auto-deliver-router
          uri: lb://scn-service-auto-deliver
          predicates:
            - Path=/api-auto-deliver/**
            # 详情参考:https://docs.spring.io/spring-cloud-gateway/docs/2.2.10.BUILD-SNAPSHOT/reference/html/#configuring-route-predicate-factories-and-gateway-filter-factories
            # 时间点后匹配
            # - After=2017-01-20T17:42:47.789-07:00[America/Denver]
            # 时间点前匹配
            # - Before=2017-01-20T17:42:47.789-07:00[America/Denver]
            # 时间区间匹配
            # - Between=2017-01-20T17:42:47.789-07:00[America/Denver],2017-01-21T17:42:47.789-07:00[America/Denver]
            # 指定Cookie正则匹配指定值
            # - Cookie=chocolate, ch.p
            # 指定Header正则匹配指定值
            # - Header=X-Request-Id, \d+
            # 请求Host匹配指定值
            # - Host=**.somehost.org,**.anotherhost.org
            # 请求Method匹配指定请求⽅式
            # - Method=GET,POST
            # 请求路径正则匹配
            # - Path=/red/{segment},/blue/{segment}
            # 请求包含某参数
            # - Query=green
            # 请求包含某参数并且参数值匹配正则表达式
            # - Query=red, gree.
            # 远程地址匹配
            # - RemoteAddr=192.168.1.1/24
          filters:
            - StripPrefix=1 # 可以去掉api-auto-deliver之后转发 数字代表去掉几层
            - RequestTime=true

# springboot中暴露健康检查等断点接⼝
management:
  endpoints:
    web:
      exposure:
        include: "*"
  # 暴露健康接口的细节
  endpoint:
    health:
      show-details: always

#分布式链路追踪
logging:
  level:
    org.springframework.web.servlet.DispatcherServlet: DEBUG
    org.springframework.cloud.sleuth: DEBUG

重启服务,我们就会在控制台看到我们的服务已经注册到注册中心了。

在这里,我们重点讲解一下服务的一个重要的配置项:保护阈值。保护阈值可以设置为0-1之间的浮点数,它其实是一个比例值(当前服务健康实例 数/当前服务总实例数)。

一般流程下,Nacos是服务注册中心,服务消费者要从Nacos获取某一个服务的可用实例信息。对于服务实例有健康/不健康状态之分,Nacos在返回给消费者实例信息的时候,会返回健康实例。这个时候在一些高并发、大流量场景下会存在一定的问题:如果服务A有100个实例,98个实例都不健康了,只有2个实例是健康的,如果Nacos只返回这两个健康实例的信息的话,那么后续消费者的请求将全部被分配到这两个实例。一旦流量洪峰到来,2个健康的实例也扛不住了,整个服务A 就扛不住,上游的微服务也会导致崩溃,从而产生雪崩效应。

而保护阈值的意义在于:当服务A健康实例数/总实例数 < 保护阈值 的时候,说明健康实例真的不多了,这个时候保护阈值会被触发(状态true)。Nacos将会把该服务所有的实例信息(健康的 + 不健康的)全部提供给消费者,消费者可能访问到不健康的实例,请求失败,但这样也比造成雪崩要好,牺牲了一些请求,但保证了整个系统的一个可用。

Nacos配置中心

之前我们的配置中心使用的技术是:SpringCloud Config + Bus。这种方式还是有一定的不方便的:1、配置文件需要单独的地方存储(Git、SVN)2、刷新配置文件还要继承MQ中间件,增加了项目的部署成本。

我们使用Nacos作为配置中心就简单很多了,

Github不需要了(配置信息直接配置在Nacos server中),Bus也不需要了(依然可以完成动态刷新)。

我们再来改造一下我们的网关服务,在其pom中添加配置中心的依赖(注释掉原来的配置中心和Bus):

 
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

将bootstrap.yml的配置文件改成以下内容:

spring:
  profiles:
    active: nacos

新建bootstrap-nacos.yml,内容如下:

spring:
  cloud:
    nacos:
      discovery:
        # 配置nacos server地址
        server-addr: nacos-host:8848
        namespace: 651d1e6f-4bf4-46b9-b5b0-1885a215dc12
      config:
        server-addr: nacos-host:8848
        namespace: 651d1e6f-4bf4-46b9-b5b0-1885a215dc12
        prefix: gateway
        group: DEFAULT_GROUP
        file-extension: yaml
        ext-config[0]:
          data-id: zipkin-client.yaml
          group: DEFAULT_GROUP
          refresh: true
        ext-config[1]:
          data-id: actuator.yaml
          group: DEFAULT_GROUP
          refresh: true
        ext-config[2]:
          data-id: logging.yaml
          group: DEFAULT_GROUP
          refresh: true

我们在Nacos Server上新建了一个叫做rubin的命名空间,服务的注册于配置都在此命名空间上。那么,微服务中如何锁定 Nacos Server 中的配置文件(dataId)呢?微服务是通过 Namespace + Group + dataId 来锁定配置文件,Namespace不指定就默认public,Group不指定就默认 DEFAULT_GROUP。

dataId 的完整格式如下:

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

所以,我们在rubin的命名空间下创建以下几个配置文件:

gateway-nacos.yaml:

server:
  port: 9200
spring:
  application:
    name: gateway
  cloud:
    gateway:
      routes:
        - id: sca-service-resume-router
          uri: lb://sca-service-resume
          predicates:
            - Path=/sca-api-resume/**
          filters:
            - StripPrefix=1
        - id: sca-service-auto-deliver-router
          uri: lb://sca-service-auto-deliver
          predicates:
            - Path=/sca-api-auto-deliver/**
          filters:
            - StripPrefix=1    
        - id: scn-service-resume-router
          uri: lb://scn-service-resume
          predicates:
            - Path=/scn-api-resume/**
          filters:
            - StripPrefix=1
        - id: scn-service-auto-deliver-router
          uri: lb://scn-service-auto-deliver
          predicates:
            - Path=/scn-api-auto-deliver/**
            # 详情参考:https://docs.spring.io/spring-cloud-gateway/docs/2.2.10.BUILD-SNAPSHOT/reference/html/#configuring-route-predicate-factories-and-gateway-filter-factories
            # 时间点后匹配
            # - After=2017-01-20T17:42:47.789-07:00[America/Denver]
            # 时间点前匹配
            # - Before=2017-01-20T17:42:47.789-07:00[America/Denver]
            # 时间区间匹配
            # - Between=2017-01-20T17:42:47.789-07:00[America/Denver],2017-01-21T17:42:47.789-07:00[America/Denver]
            # 指定Cookie正则匹配指定值
            # - Cookie=chocolate, ch.p
            # 指定Header正则匹配指定值
            # - Header=X-Request-Id, \d+
            # 请求Host匹配指定值
            # - Host=**.somehost.org,**.anotherhost.org
            # 请求Method匹配指定请求⽅式
            # - Method=GET,POST
            # 请求路径正则匹配
            # - Path=/red/{segment},/blue/{segment}
            # 请求包含某参数
            # - Query=green
            # 请求包含某参数并且参数值匹配正则表达式
            # - Query=red, gree.
            # 远程地址匹配
            # - RemoteAddr=192.168.1.1/24
          filters:
            - StripPrefix=1 # 可以去掉api-auto-deliver之后转发 数字代表去掉几层
            - RequestTime=true

zipkin-client.yaml:

spring:
  zipkin:
    # zipkin-server的请求地址
    base-url: http://zipkin-host:9500
    sender:
      # web 客户端将踪迹日志数据通过网络请求的方式传送到服务端,另外还有配置
      # kafka/rabbit 客户端将踪迹日志数据传递到mq进行中转
      type: web
  sleuth:
    sampler:
      # 采样率 1 代表100%全部采集 ,默认0.1 代表10% 的请求踪迹数据会被采集
      # 生产环境下,请求量非常大,没有必要所有请求的踪迹数据都采集分析,对于网络包括server端压力都是比较大的,可以配置采样率采集一定比例的请求的踪迹数据进行分析即可
      probability: 0.1    

actuator.yaml:

# springboot中暴露健康检查等断点接口
management:
  endpoints:
    web:
      exposure:
        include: "*"
  # 暴露健康接口的细节
  endpoint:
    health:
      show-details: always

logging.yaml:

#分布式链路追踪
logging:
  level:
    org.springframework.web.servlet.DispatcherServlet: DEBUG
    org.springframework.cloud.sleuth: DEBUG

优先级:根据规则生成的dataId > 扩展的dataId(对于扩展的dataId,[n] n越大优 先级越高)。

至此,我们的Nacos相关内容就讲完了。欢迎小伙伴们积极留言交流~~~

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: SpringCloud
最后更新:2022年 6月 9日

RubinChu

一个快乐的小逗比~~~

打赏 点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复
文章目录
  • Nacos介绍
  • Nacos Server单例服务部署
  • Nacos Server集群
  • Nacos Server数据持久化
  • Nacos 数据模型
    • 最佳实践
  • 服务注册到Nacos注册中心上
  • Nacos配置中心
最新 热点 随机
最新 热点 随机
问题记录之Chrome设置屏蔽Https禁止调用Http行为 问题记录之Mac设置软链接 问题记录之JDK8连接MySQL数据库失败 面试系列之自我介绍 面试总结 算法思维
Redis之扩展功能 Redis之Codis集群搭建 JVM之GC日志分析 自定义简单的RPC框架 java并发编程之Lock与Condition 算法思维

COPYRIGHT © 2021 rubinchu.com. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

京ICP备19039146号-1