Nacos全称是动态命名和配置服务,Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos主要用于发现、配置和管理微服务。
Nacos支持几乎所有主流类型的服务的发现、配置和管理。Nacos的关键特性包括:
服务发现和服务健康监测
动态配置服务
动态DNS
服务及其元数据管理
物理的数据中心,资源创建后不能更换。
同一个地域内,电力和网络互相独立的物理区域。同一个可用区内,实例的网络延迟较低。
地域的某个服务的入口域名。
用来进行租户粒度的配置隔离。不同命名空间下,可以存在相同的Group或Data ID的配置。命名空间可以用来实现不同环境的配置区分隔离,例如开发测试环境和生产环境的资源隔离等。
在系统开发过程中,通常会将一些需要变更的参数、变量等从代码中分离出来独立管理,以独立的配置文件的形式存在。
系统配置的编辑、存储、分发、变更管理、历史版本管理、变更审计等所有与配置相关的活动。
一个具体的可配置的参数与其值域。
一组相关或者不相关的配置项的集合称为配置集。在系统中,一个配置文件通常就是一个配置集,包含了系统各个方面的配置。
Nacos中的某个配置集的ID。配置集ID是组织划分配置的维度之一。Data ID通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。Data ID通常采用类似Java包的命名规则保证全局唯一性。
Nacos中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串对配置集进行分组,从而区分Data ID相同的配置集。默认分组的名称是DEFAULT_GROUP。
Nacos的客户端SDK会在本地生成配置的快照。当客户端无法连接到Nacos Server时,可以使用配置快照显示系统的整体容灾能力。配置快照类似于Git的本地提交,会在适当的时机更新。
通过预定义接口网络访问的提供给客户端的软件功能。
服务提供的标识,通过该标识可以唯一确定其指代的服务。
存储服务实例和服务负载均衡策略的数据库。
在计算机网络上,对服务下的实例的地址和元数据进行探测,并以预先定义的接口提供给客户端进行查询。
Nacos数据描述信息,如服务版本、权重、容灾策略、负载均衡策略、鉴权配置。
用于标识服务提供方的服务的属性。
不同的服务可以归类到同一分组。
同一个服务下的所有服务实例组成一个默认集群,集群可以被进一步按需求划分,划分的单位可以是虚拟集群。
提供一个或多个服务的具有可访问网络地址的进程。
实例级别的配置。权重为浮点数。权重越大,分配给该实例的流量越大。
以指定方式检查服务下挂载的实例的健康度,从而确定该实例能否提供服务。
为了防止因过多实例不健康导致流量全部流向实例,继而造成流量压力把健康实例压垮并型号才能雪崩效应,应该健康保护域值定义为一个0到1之间的浮点数。

服务指的是一个或一组软件功能,目的是不同的客户端可以为不同的目的重用。
服务注册中心是服务、其实例及元数据的数据库。服务实例在启动时注册到服务注册表,并在关闭时注销。服务和路由器的客户端查询服务注册表以查找服务的可用实例。服务注册中心可能会调用服务实例的健康检查API来验证它是否能够处理请求。
服务元数据是指包括服务端点、服务标签、服务版本号、服务实例权重、路由规则、安全策略等描述服务的数据。
提供可复用和可调用服务的应用方。
发起对某个服务调用的应用方。

Nacos数据模型Key由三元组唯一确定,Namespace默认是空串,公共命名空间,分组默认是DEFAULT_GROUP。
Nacos服务的分级存储模型。
服务:健康检查开关、元数据、路由机制、保护域值;
集群:健康检查模式、元数据、同步机制;
实例:IP、端口、权重、健康状态、下线状态、元数据、响应时间。
围绕配置主要有两个关联实体,一个是配置变更历史,一个是服务标签,由ID关联。

Nacos支持将数据中心与配置中心在一个进程合并部署或者将两者分离部署的两种模式。
Nacos支持公有云模式。
64位操作系统,JDK1.8+,Maven 3.2.x+,Nacos的运行需要至少2C4g60g*3的机器
# 从Github上下载源码
git clone https://github.com/alibaba/nacos.git
cd nacos/
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U ls -al distribution/target/
cd distribution/target/nacos-server-$version/nacos/bin
# 下载编译后压缩包方式
# 在Github项目地址下载
# Linux/Unix/Mac
# 启动命令,单机模式运行
sh startup.sh -m standalone
# Windows
startup.cmd -m standalone
curl -X POST "http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.10&port=8080"
curl -X GET "http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName"
curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=HelloWorld"
curl -X GET "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test"
# Linux/Unix/Mac
sh shutdown.sh
# Windows
shutdown.cmd
nacos-spring-boot-configmaven依赖:
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>com.alibaba.bootgroupId>
<artifactId>nacos-config-spring-boot-starterartifactId>
<version>0.2.1version>
dependency>
<dependency>
<groupId>com.alibaba.bootgroupId>
<artifactId>nacos-config-spring-boot-actuatorartifactId>
<version>0.2.1version>
dependency>
dependencies>
application.yml配置文件:
nacos:
config:
server-addr: 127.0.0.1:8848 #配置Nacos Server地址
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
创建控制器ConfigController.class,提供访问点:
package org.lxx.nacos.spring.boot.config.controller;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("config")
public class ConfigController {
//设置属性值,默认不会自动更新
@NacosValue(value = "${useLocalCache:false}", autoRefreshed = true)
private boolean useLocalCache;
@RequestMapping(value = "/get", method = RequestMethod.GET)
@ResponseBody
public boolean get() {
return useLocalCache;
}
}
创建启动类NacosConfigApplication.java:
package org.lxx.nacos.spring.boot.config;
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Nacos控制台添加配置
*/
@SpringBootApplication
//加载dataId为test的数据源,并开启自动更新
@NacosPropertySource(dataId = "test", autoRefreshed = true)
public class NacosConfigApplication {
public static void main(String[] args) {
SpringApplication.run(NacosConfigApplication.class, args);
}
}
curl http://localhost:8080/config/get,返回内容是 false。通过调用Nacos Open API向Nacos Server发布配置,再次访问接口,内容被动态更新了。curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=test&group=DEFAULT_GROUP&content=useLocalCache=true"
nacos-spring-boot-discoverymaven依赖:
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>com.alibaba.bootgroupId>
<artifactId>nacos-discovery-spring-boot-starterartifactId>
<version>0.2.1version>
dependency>
dependencies>
application.yml:
nacos:
discovery:
server-addr: 127.0.0.1:8848
创建控制器DiscoveryController.class:
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
@RequestMapping("discovery")
public class DiscoveryController {
//注入Nacos的命名服务
@NacosInjected
private NamingService namingService;
@RequestMapping(value = "/get", method = RequestMethod.GET)
@ResponseBody
public List<Instance> get(@RequestParam String serviceName)
throws NacosException {
return namingService.getAllInstances(serviceName);
}
}
创建启动类NacosDiscoveryApplication.class:
package org.lxx.nacos.spring.boot.discovery;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class NacosDiscoveryApplication {
public static void main(String[] args) {
SpringApplication.run(NacosDiscoveryApplication.class, args);
}
}
NacosDiscoveryApplication,调用 curl http://localhost:8080/discovery/get?serviceName=example,此时返回为空 JSON 数组[]。通过调用 Nacos Open API 向 Nacos server 注册一个名称为 test 服务,再次访问接口返回了接口信息。curl -X POST "http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=test&ip=127.0.0.1&port=8080"
创建数据表:
CREATE TABLE `user` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci;
INSERT INTO `user` VALUES (1, '张三');
maven依赖:
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.46version>
dependency>
<dependency>
<groupId>com.alibaba.bootgroupId>
<artifactId>nacos-config-spring-boot-starterartifactId>
<version>0.2.1version>
dependency>
dependencies>
application.yml:
nacos:
config:
server-addr: 127.0.0.1:8848
添加模型类User.class:
package org.lxx.nacos.spring.boot.config.mysql.model;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Data
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
}
添加DAO层接口UserRepository.java:
package org.lxx.nacos.spring.boot.config.mysql.dao;
import org.lxx.nacos.spring.boot.config.mysql.model.User;
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<User, Integer> {
}
添加Service层实现UserService.java:
package org.lxx.nacos.spring.boot.config.mysql.service;
import org.lxx.nacos.spring.boot.config.mysql.dao.UserRepository;
import org.lxx.nacos.spring.boot.config.mysql.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User findById(Integer id) {
return userRepository.findById(id).orElse(null);
}
}
添加控制器UserController.java:
package org.lxx.nacos.spring.boot.config.mysql.controller;
import org.lxx.nacos.spring.boot.config.mysql.model.User;
import org.lxx.nacos.spring.boot.config.mysql.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController("user")
public class UserController {
private final UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping
public User get(@RequestParam int id) {
return userService.findById(id);
}
}
添加启动类SpringBootMySQLApplication.java:
package org.lxx.nacos.spring.boot.config.mysql;
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@NacosPropertySource(dataId = "mysql")
public class SpringBootMySQLApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootMySQLApplication.class, args);
}
}
在Nacos控制台配置mysql数据集:
Data ID: mysql, GROUP: DEFAULT_GROUP。
spring.datasource.url=jdbc:mysql://localhost:3306/mytest?serverTimezone=GMT%2B8&characterEncoding=UTF-8&useSSL=false
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
http://127.0.0.1:8080/user?id=1可以读取到数据库中的数据。