什么是Nacos
官方:https://nacos.io/zh-cn/index.html
英文缩写:Name Configurations 表示注册中心和配置中心
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
总结:Nacos就是微服务架构中服务注册中心以及统一配置中心,用来替换原来的(eureka,consul)以及config组件。
安装Nacos
准备环境
Nacos 依赖 Java 环境来运行。如果您是从代码开始构建并运行Nacos,还需要为此配置 Maven环境,请确保是在以下版本环境中安装使用:
- 64 bit OS,支持 Linux/Unix/Mac/Windows,推荐选用 Linux/Unix/Mac。
- 64 bit JDK 1.8+;下载 & 配置。
- Maven 3.2.x+;下载 & 配置。
下载Nacos(1.4.0)
https://github.com/alibaba/nacos/releases
解压缩安装包到指定位置
1 2 3 4 5
| - bin 启动nacos服务的脚本目录 - conf nacos的配置文件目录 - target nacos的启动依赖存放目录 - data nacos启动成功后保存数据的目录(启动后生成) - logs nacos的启动运行日志目录(启动后生成)
|
启动安装服务
1 2 3 4 5 6 7
| - linux/unix/mac启动 打开终端进入nacos的bin目录执行如下命令 ./startup.sh -m standalone
- windows启动 在 cmd中 执行 startup.cmd -m standalone 或者双击startup.cmd运行文件。
|
访问nacos的web服务管理界面
http://localhost:8848/nacos/
用户名 和 密码都是nacos
开发服务注册到Nacos
创建项目并引入依赖
分别创建服务消费者(users)和服务提供着(products)两个项目
1 2 3 4 5
| <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
|
修改配置文件
1 2 3 4 5 6 7 8 9 10
| server.port=9099
spring.application.name=users
spring.cloud.nacos.server-addr=localhost:8848
spring.cloud.nacos.discovery.server-addr=${spring.cloud.nacos.server-addr}
management.endpoints.web.exposure.include=*
|
入口类加入服务注册注解
注意:新版本之后这一步可以省略不写
1 2 3 4 5 6 7 8 9
| @SpringBootApplication @EnableDiscoveryClient public class Springcloudalibaba03Products9098Application {
public static void main(String[] args) { SpringApplication.run(Springcloudalibaba03Products9098Application.class, args); }
}
|
启动项目并查看nacos控制台
Nacos配合OpenFeign进行服务间调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
@RestController @Slf4j public class ProductController {
@Value("${server.port}") private int port;
@GetMapping("/product/find") public Map<String, Object> find(@RequestParam("id") String id) { Map<String, Object> map = new HashMap<>(); log.info("进入傻姑娘片服务,当前接收的商品id为:[{}]", id); map.put("status", true); map.put("msg","当前商品服务调用成功,查询商品id为:"+id+",当前处理服务的端口为:" + port); return map; } }
|
通过restTemplate直接调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
@RestController @Slf4j public class UserController {
@GetMapping("/user/getProductInfo") public String getProductInfo(String productId) {
RestTemplate restTemplate = new RestTemplate(); String forObject = restTemplate .getForObject("http://localhost:9098/product/find?id=" + productId, String.class);
log.info("返回的信息:[{}]", forObject); return forObject; } }
|
DiscoveryClient (restTemplate + ribbon负载均衡客户端)
自定义负载均衡
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
@RestController @Slf4j public class UserController {
@Autowired private DiscoveryClient discoveryClient;
@GetMapping("/user/getProductInfo") public String getProductInfo(String productId) {
List<ServiceInstance> productsServiceInstances = discoveryClient.getInstances("products"); for (ServiceInstance productsServiceInstance: productsServiceInstances){ log.info("服务地址:[{}]",productsServiceInstance.getUri()); }
log.info("返回的信息:[{}]", forObject); return forObject; } }
|
LoadBalancerClient (restTemplate + ribbon负载均衡客户端)
自动负载均衡
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
@RestController @Slf4j public class UserController {
@Autowired private LoadBalancerClient loadBalancerClient;
@GetMapping("/user/getProductInfo") public String getProductInfo(String productId) {
ServiceInstance productServiceInstance = loadBalancerClient.choose("products"); log.info("当前处理服务负载均衡客户端主机为:[{}]",productServiceInstance.getUri()); String forObject = restTemplate .getForObject(productServiceInstance.getUri() + "/product/find?id=" + productId, String.class); log.info("返回的信息:[{}]", forObject); return forObject; } }
|
LoadBalanced注解形式(restTemplate + ribbon负载均衡客户端)
- 首先创建一个具有负载均衡的RestTemplate对象
1 2 3 4 5 6 7 8 9 10 11 12
|
@Configuration public class RestTemplateConfig {
@Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
@RestController @Slf4j public class UserController { @Autowired private RestTemplate restTemplate;
@GetMapping("/user/getProductInfo") public String getProductInfo(String productId) {
String forObject = restTemplate .getForObject("http://products/product/find?id=" + productId, String.class); log.info("返回的信息:[{}]", forObject); return forObject; } }
|
openfeign调用(底层用ribbon做负载均衡)–推荐
1 2 3 4 5 6 7 8 9 10 11
|
@FeignClient("products") public interface ProductClient {
@GetMapping("/product/find") Map<String, Object> find(@RequestParam("id") String id); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
@RestController @Slf4j public class UserController {
@Autowired private ProductClient productClient;
@GetMapping("/user/getProductInfo") public String getProductInfo(String productId) { Map<String, Object> map = productClient.find(productId);
log.info("返回的信息:[{}]", map.toString()); return map.toString(); } }
|
Nacos作为配置中心使用
创建项目并引入依赖
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>
|
修改配置文件
由于要去获取配置中心的配置文件,所有本地的配置文件要改名为:bootstrap.proterties
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
spring.cloud.nacos.server-addr=localhost:8848
spring.cloud.nacos.config.server-addr=${spring.cloud.nacos.server-addr}
spring.cloud.nacos.config.group=DEFAULT_GROUP
spring.application.name=configclient
spring.profiles.active=prod
spring.cloud.nacos.config.file-extension=properties
|
在nacos中创建配置
编写控制器测试配置读取情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
@RestController @Slf4j public class TestController {
@Value("${user.name}") private String name; public String test() { log.info("当前获取配置中name为:[{}]", name); return "当前获取配置中name为:"+name; }
}
|
启动项目测试配置读取
DataId
用来读取远程配置中心的中具体配置文件其完整格式如下:
${prefix}-${spring.profile.active}.${file-extension}
prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
spring.profile.active 即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 注意:当 spring.profile.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}
file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。
实现自动配置刷新
默认情况下nacos已经实现了自动配置刷新功能,如果需要刷新配置直接在控制器中加入@RefreshScpoper
注解即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
@RestController @Slf4j @RefreshScope public class TestController {
@Value("${user.name}") private String name;
@GetMapping("/test/test") public String test() { log.info("当前获取配置中name为:[{}]", name); return "当前获取配置中name为:"+name; }
}
|
然后再控制台修改配置,刷新页面发现值变了
命名空间
命名空间介绍(namespace)
官方:https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config
namespace命名空间是nacos针对于企业级开发设计用来针对于不同环境的区分,比如正在企业开发时有测试环境,生产环境,等其他环境,因此为了保证不同环境配置实现隔离,提出了namespace的概念,默认在nacos中存在一个public命名空间所有配置在没有指定命名空间时都在这个命名空间中获取配置,在实际开发时可以针对于不能环境创建不同的namespace空间。默认空间不能删除!
创建其他命名空间
每个命名空间都有一个唯一id,这个id是读取配置时指定空间的唯一标识
在配置列表查看命名空间
在指定空间下创建配置文件
在项目中使用命名空间指定配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
spring.cloud.nacos.server-addr=localhost:8848
spring.cloud.nacos.config.server-addr=${spring.cloud.nacos.server-addr}
spring.cloud.nacos.config.namespace=e7a4564a-c135-4dfb-a77e-57b4a5c2c703
spring.cloud.nacos.config.group=DEFAULT_GROUP
spring.application.name=configclient
spring.profiles.active=prod
spring.cloud.nacos.config.file-extension=properties
|
启动项目测试配置
配置分组
分组介绍(GROUP)
配置分组是对配置集进行分组,通过一个有意义的字符串(如 Buy 或 Trade )来表示,不同的配置分组下可以有相同的配置集(Data ID)。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:可用于区分不同的项目或应用,例如:学生管理系统的配置集可以定义一个group为:STUDENT_GROUP。
创建分组
项目读取指定分组的配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
spring.cloud.nacos.server-addr=localhost:8848
spring.cloud.nacos.config.server-addr=${spring.cloud.nacos.server-addr}
spring.cloud.nacos.config.namespace=e7a4564a-c135-4dfb-a77e-57b4a5c2c703
spring.cloud.nacos.config.group=BUUBIU
spring.application.name=configclient
spring.profiles.active=prod
spring.cloud.nacos.config.file-extension=properties
|
启动项目测试配置