前言
最近公司小组内在流行做技术分享,于是自己就找了下之前学习的Nacos,整理了下资料,跟大家做了下简单的分享实践,由于自己也没有在项目中真实实操过,所以也不是很熟悉,只是作为Nacos入门跟大家作下分享。
目录
本文针对最新版Nacos做了一些入门介绍,以及基于spring cloud 实现的简单demo示例,文末会贴出示例源码地址(如果没有,那一定是我懒,还没来得及放上去)。
概述
官网概述的是“一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。”
Nacos 是阿里开源项目 spring cloud alibaba 的服务注册发现组件,支持AP/CP 模式的动态切换,服务注册发现与配置中心二合一的一个开源中间件。经历过阿里大厂的高并发大流量、海量数据的业务洗礼,目前已经有多家科技公司接入使用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目前开源时间不久,版本还在不断迭代中,依然存在很多问题需要解决,不过其优秀的性能也得到了很多科技公司的认可和使用。目前还处于推广阶段,但毕竟是阿里出品,其生态还是有很大的空间。相信之后也会得到越来越多程序开发者的肯定的认同。