spring cloud alibaba -- 初识Nacos

前言
最近公司小组内在流行做技术分享,于是自己就找了下之前学习的Nacos,整理了下资料,跟大家做了下简单的分享实践,由于自己也没有在项目中真实实操过,所以也不是很熟悉,只是作为Nacos入门跟大家作下分享。


本文针对最新版Nacos做了一些入门介绍,以及基于spring cloud 实现的简单demo示例,文末会贴出示例源码地址(如果没有,那一定是我懒,还没来得及放上去)。

概述

官网概述的是“一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。”
Nacos 是阿里开源项目 spring cloud alibaba 的服务注册发现组件,支持AP/CP 模式的动态切换,服务注册发现与配置中心二合一的一个开源中间件。经历过阿里大厂的高并发大流量、海量数据的业务洗礼,目前已经有多家科技公司接入使用Nacos作为服务注册发现和配置管理服务。

Nacos的基础架构图:

Nacos的基础架构图

Nacos地图:

Nacos地图

启动安装

官网地址

下载地址

方式一:github下载地址
可直接下载安装部署包
下载页面
在这里插入图片描述

方式二:gitee下载地址
下载完后 需要本地编译打包

mvn -Prelease-nacos -DskipTests clean install -U

打包后的文件在Nacos\distribution\target目录下。

方式一解压包目录:
解压目录

启动服务(本文以windows上启动集群示例)

将解压目录拷贝出三份,起名nacos1、nacos2、nacos3
在这里插入图片描述

配置

1- 进入\nacos1\conf目录下
修改application.properties文件

# 修改节点暴露的端口号 分别是8847、8848、8849
### Default web server port:
server.port=8847

#*************** Config Module Related Configurations ***************#
# 配置此处是防止本机启动服务,服务自动获取局域网IP 造成阶段混乱
nacos.inetutils.ip-address=127.0.0.1

# 修改数据源信息(单机模式下,nacos会利用内嵌数据库做数据持久化,由于集群是多节点的,所以需要配置统一数据源)
### If use MySQL as datasource:
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?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=root
db.password=123456

2- 添加集群配置文件
从cluster.conf.example拷贝出一份文件取名cluster.conf
配置如下

127.0.0.1:8847
127.0.0.1:8848
127.0.0.1:8849

3- nacos2和nacos3相同配置 节点端口号不同而已

启动

windows下 双击startup.cmd(默认启动模式是cluster模式)
如果启动单机模式需要修改启动文件startup.cmd

set MODE="cluster"
-->修改为单机模式
set MODE="standalone"

也可以加参数 -m “standalone” 指定单机模式启动
lunix下直接sh startup.sh

下个阶段启动完毕
在这里插入图片描述
这里我有启动了一个Nginx服务,用于做三个Nacos服务节点访问的负载
Nginx配置:

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    #gzip  on;

	upstream nacos-server {
	  server 127.0.0.1:8847;
	  server 127.0.0.1:8848;
	  server 127.0.0.1:8849;
	}

    server {
        listen       80;
        server_name  localhost;

        location / {
            proxy_pass http://nacos-server;
			index  index.html;
        }
		
		# 作为图片服务器放开
		#location / {
        #    root   E:\\Nginx\\static;
		#	index  index.html index.htm;
        #}

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

}

然后又在hosts文件下配置了本地IP映射

127.0.0.1 nacos.qrainly.top

启动Nginx
浏览器输入http://nacos.qrainly.top/nacos 默认登录账号:nacos/nacos
如下图所示,可以看到三个节点已经都部署成功了
在这里插入图片描述

功能特点

服务注册与发现(作为服务注册发现中心)

在demo项目中新增服务提供方module nacos-provider
pom配置

<dependencies>
   <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.springframework.boot</groupId>
       <artifactId>spring-boot-starter-test</artifactId>
       <scope>test</scope>
   </dependency>
</dependencies>

配置文件application.yml

server:
  port: 7090

spring:
  application:
    name: nacos-provider
  cloud:
    nacos:
      discovery:
#        server-addr: 127.0.0.1:8848 #单机配置Nacos地址
        server-addr: 127.0.0.1:8847,127.0.0.1:8848,127.0.0.1:8849 #集群配置Nacos地址

management:
  endpoints:
    web:
      exposure:
        include: '*'  #监控

新建一个controller

/**
 * @author v_liuwen
 * @date 2020/9/1 0:06
 */
@RestController
@Slf4j
public class ProviderController {

    private AtomicInteger count = new AtomicInteger(0);

    @Value("${server.port}")
    private String serverPort;

    @GetMapping("/sayHi")
    public String sayHi(@RequestParam(value = "name",defaultValue = "liuwen",required = false)String name){
        log.info("HI "+name+"! Port: "+ serverPort);
        log.info("Hi {},port->{},连续收到请求第{}次!",name,serverPort,count.incrementAndGet());
        return "HI "+name+"!  Nacos registry,serverPort: "+ serverPort;
    }
}

启动类添加服务发现注解

/**
 * @author v_liuwen
 */
@SpringBootApplication
@EnableDiscoveryClient
@Slf4j
public class NacosProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(NacosProviderApplication.class, args);
        log.info("************************NacosProviderApplication is successful!************************");
    }

}

在IDEA中启动端口号为7070、7080、7090三个服务提供方实例
启动完后观察Nacos控制台
在这里插入图片描述
可以看到服务列表已经有三台服务提供方实例注册进入了,点击详情可查看,优雅编辑服务上下线,权重流量分发控制等操作
在这里插入图片描述
在新建一个服务调用方nacos-consumer
pom配置

<dependencies>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
        <version>2.2.4.RELEASE</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-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

配置文件application.yml

server:
  port: 9090

spring:
  application:
    name: nacos-consumer
  cloud:
    nacos:
      discovery:
#        server-addr: 127.0.0.1:8848
        server-addr: 127.0.0.1:8847,127.0.0.1:8848,127.0.0.1:8849

新建Feign接口(ProviderFeignImpl为熔断处理类)

/**
 * @author v_liuwen
 * @date 2020/9/1 0:10
 */
@FeignClient(value = "nacos-provider",fallback = ProviderFeignImpl.class)
public interface ProviderFeign {

    @GetMapping("/sayHi")
    String sayHi(@RequestParam(value = "name",defaultValue = "liuwen",required = false)String name);
}

新建controller请求入口

@RestController
@Slf4j
public class ConsumerController {

    @Autowired
    ProviderFeign providerFeign;

    /**
     * http://localhost:9090/hi-feign
     * @return
     */
    @RequestMapping(value = "/hi-feign",method = RequestMethod.GET)
    public String hiFeign(@RequestParam(value = "name",defaultValue = "feign",required = false)String name){
        return providerFeign.sayHi(name);
    }
}

启动服务,观察Nacos
可以看到调用方已经成功注册到Nacos
在这里插入图片描述
用postman并发100个请求
http://localhost:9090/hi-feign?name=liuwen
在这里插入图片描述
查看IDEA控制台
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到请求是均匀的达到三个服务节点上去的
有关权重修改以及优雅上下线的操作,这里就不做过大描述,大家感兴趣可以本机测试一下

动态配置服务(作为配置中心)

新建配置demo module nacos-config
pom配置

<dependencies>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    <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.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

由于项目的启动配置在容器启动时就需要,所以添加了bootstrap.yml配置文件
这里直接配置的是加载多配置文件的方法
Nacos的配置服务可以通过三种方案分服务分环境配置
1.DataID方案配置:指定spring.profile.active和配置文件的DataID来使不同环境下读取不同的配置默认空间 + 默认分组 + 新建dev和test两个DataID
2.Group方案:通过Group实现环境区分
3.Namespace方案:新建dev/test的Namespace

server:
  port: 6060

# DataID方案配置
#spring:
#  application:
#    name: nacos-config
#  cloud:
#    nacos:
#      config:
##        server-addr: 127.0.0.1:8848 #Nacos作为配置中心地址
#        server-addr: 127.0.0.1:8847,127.0.0.1:8848,127.0.0.1:8849 #集群配置Nacos地址
#        file-extension: yaml
#        prefix: nacos-config
#  profiles:
#    active: dev
#    # active: test

# ${prefix}-${spring.profile.active}.${file-extension}
# ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file.extension}
# nacos-config-dev.yaml




# Group方案
#spring:
#  application:
#    name: nacos-config
#  cloud:
#    nacos:
#      config:
#        server-addr: 127.0.0.1:8848 #Nacos作为配置中心地址
#        file-extension: yaml
#        group: TEST_GROUP
#        #group: DEV_GROUP
#  profiles:
#    active: info



# Namespace方案
#spring:
#  application:
#    name: nacos-config
#  cloud:
#    nacos:
#      config:
#        server-addr: 127.0.0.1:8848 #Nacos作为配置中心地址
#        file-extension: yaml
#        group: DEV_GROUP
#        namespace: 9b984ac7-5d8e-4d25-a1de-1490847d0430
#  profiles:
#    active: dev


# 同时加载多个配置集
spring:
  application:
    name: nacos-config
  cloud:
    nacos:
      config:
#        server-addr: 127.0.0.1:8848 #Nacos作为配置中心地址
        server-addr: 127.0.0.1:8847,127.0.0.1:8848,127.0.0.1:8849 #集群配置Nacos地址
        file-extension: yaml
        group: DEV_GROUP
        namespace: 9b984ac7-5d8e-4d25-a1de-1490847d0430
        extension-configs[0]: # 拓展配置 - 数据源
          data-id: datasource.yml
          group: dev
          refresh: true
        extension-configs[1]: # 拓展配置 - mybatis
          data-id: mybatis.yml
          group: dev
          refresh: true
#        shared-dataids: datasource.yml,mybatis.yml,common.yml
#        refreshable-dataids: datasource.yml,mybatis.yml,common.yml
  profiles:
    active: dev

application.yml配置

spring:
  cloud:
    nacos:
      discovery:
        # server-addr: 127.0.0.1:8848 #Nacos服务注册中心地址
        server-addr: 127.0.0.1:8847,127.0.0.1:8848,127.0.0.1:8849 #集群配置Nacos地址

新建controller测试入口(这里commonInfo的配置会加载不到,是因为不在同一个namespace)

/**
 * @author v_liuwen
 * @date 2020/9/1 1:25
 */
@RestController
@RefreshScope
public class ConfigController {

    @Value("${datasource.url:}")
    private String datasourceUrl;
    @Value("${mybatis.info:}")
    private String mybatisInfo;
    @Value("${common.info:}")
    private String commonInfo;

    @GetMapping("/multi_config/info")
    public String getMultiConfigInfo(){
        return "datasourceUrl -> "+datasourceUrl + "  mybatis -> "+ mybatisInfo + " commonInfo -> "+commonInfo;
    }

}

启动项目,观察Nacos服务列表
在这里插入图片描述
事先配置好的配置内容
项目配置的namespace就是命令空间ID
在这里插入图片描述

postman测试
在这里插入图片描述
可以正常加载配置里的内容

动态DNS服务(负载均衡服务)

Nacos的这点特性主要是加速了客户端域名解析的速度,并不能真正意义的作为独立的DNS服务使用
DNS-F落地的技术价值

  • 填补了内部微服务业务没有全局动态调度能力的空白
  • 解决了服务端:时延大、解析不准、故障牵引慢
  • 支持服务端多种调度需要
  • 加速外部域名解析
  • 服务故障牵引秒级生效
  • 提供专线流量牵引能力

Nacos Sync机制

Nacos Sync真大的意义在于支持跨注册中心同步数据,这在服务转移切换过程中有着很大的作用和效果!

总结

对比注册中心Eureka
在这里插入图片描述
相比与Eureka:
(1)Nacos具备服务优雅上下线和流量管理(API+后台管理页面),而Eureka的后台页面仅供展示,需要使用api操作上下线且不具备流量管理功能。
(2)从部署来看,Nacos整合了注册中心、配置中心功能,把原来两套集群整合成一套,简化了部署维护
(3)从长远来看,Eureka2.x后续不再有更新和维护,而Nacos在以后的版本会支持SpringCLoud+Kubernetes的组合,填补 2 者的鸿沟,在两套体系下可以采用同一套服务发现和配置管理的解决方案,这将大大的简化使用和维护的成本。同时来说,Nacos 计划实现 Service Mesh,是未来微服务的趋势
(4)从伸缩性和扩展性来看Nacos支持跨注册中心同步,而Eureka不支持,且在伸缩扩容方面,Nacos比Eureka更优(nacos支持大数量级的集群)。
(5)Nacos具有分组隔离功能,一套Nacos集群可以支撑多项目、多环境。

对比配置中心Apollo
在这里插入图片描述
相比于apollo
(1) Nacos部署简化,Nacos整合了注册中心、配置中心功能,且部署相比apollo简单,方便管理和监控。
(2) apollo容器化较困难,Nacos有官网的镜像可以直接部署,总体来说,Nacos比apollo更符合KISS原则
(3)性能方面,Nacos读写tps比apollo稍强一些

Nacos目前开源时间不久,版本还在不断迭代中,依然存在很多问题需要解决,不过其优秀的性能也得到了很多科技公司的认可和使用。目前还处于推广阶段,但毕竟是阿里出品,其生态还是有很大的空间。相信之后也会得到越来越多程序开发者的肯定的认同。


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