第一章 SpringCloud注册配置中心之Nacos

472 阅读3分钟

文章目录


SpringCloud 分布式基础篇

一、nacos是什么?

一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

功能:

  1. 动态配置服务
    动态配置服务让您能够以中心化、外部化和动态化的方式管理所有环境的配置。动态配置消除了配置变更时重新部署应用和服务的需要。配置中心化管理让实现无状态服务更简单,也让按需弹性扩展服务更容易。
  2. 服务发现及管理
    动态服务发现对以服务为中心的(例如微服务和云原生)应用架构方式非常关键。Nacos支持DNS-Based和RPC-Based(Dubbo、gRPC)模式的服务发现。Nacos也提供实时健康检查,以防止将请求发往不健康的主机或服务实例。借助Nacos,您可以更容易地为您的服务实现断路器。
  3. 动态DNS服务
    通过支持权重路由,动态DNS服务能让您轻松实现中间层负载均衡、更灵活的路由策略、流量控制以及简单数据中心内网的简单DNS解析服务。动态DNS服务还能让您更容易地实现以DNS协议为基础的服务发现,以消除耦合到厂商私有服务发现API上的风险。

二、下载安装

1.下载

github.com/alibaba/nac…

2.服务器启动与关闭

2.1. 启动

Linux/Unix/Mac
启动命令(standalone代表着单机模式运行,非集群模式):

sh startup.sh -m standalone

如果您使用的是ubuntu系统,或者运行脚本报错提示[[符号找不到,可尝试如下运行:

bash startup.sh -m standalone

Windows
启动命令(standalone代表着单机模式运行,非集群模式):

startup.cmd -m standalone

2.2. 关闭

Linux/Unix/Mac

sh shutdown.sh

Windows

shutdown.cmd

或者双击shutdown.cmd运行文件。

2.3. 访问

http://服务器ip:8848/nacos
账号密码默认为naocs/nacos

三、Nacos Spring Cloud 快速开始

关于 Nacos Spring Cloud 的详细文档请参看:Nacos Config 和 Nacos Discovery。

  • 通过 Nacos Server 和 spring-cloud-starter-alibaba-nacos-config 实现配置的动态变更。
  • 通过 Nacos Server 和 spring-cloud-starter-alibaba-nacos-discovery 实现服务的注册与发现。

1. 前提

您需要先下载 Nacos 并启动 Nacos server。

2. 启动配置管理

2.1 添加依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>${latest.version}</version>
</dependency>

注意:

  • 版本 2.1.x.RELEASE 对应的是 Spring Boot 2.1.x 版本
  • 版本 2.0.x.RELEASE 对应的是 Spring Boot 2.0.x 版本
  • 版本 1.5.x.RELEASE 对应的是 Spring Boot 1.5.x 版本

2.1 配置 Nacos 地址和应用名

  • 此处配置文件名必须为 bootstrap.properties。
  • 如果不配置data-id,则默认为${prefix}-${spring.profiles.active}.${file-extension}
  • ${prefix} = spring.application.name 值
  • ${spring.profiles.active} = spring.profiles.active 值,当 spring.profiles.active 为空时,对应的连接符 - 也将不存在
  • ${file-extension} = 默认为 properties 或 yaml,可通过配置spring.cloud.nacos.config.file-extension 来配置。
  • 根据规则当前案例读取配置文件为example.properties、mysql.yml、mybatis.yml。
  • 如果配置中心和当前应用中的配置文件配置了相同的项,则优先使用配置中心的配置。
  • 配置中心没有的配置项会读取项目中配置文件的对应配置项。
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.applicatin.name=example

#下面配置根据需要配置,非必须
#data-id 配置文件名称
#group 配置分组 默认为default
#refresh 是否动态刷新 
spring.cloud.nacos.config.ext-config[0].data-id=mysql.yml
spring.cloud.nacos.config.ext-config[0].group=member
spring.cloud.nacos.config.ext-config[0].refresh=true

spring.cloud.nacos.config.ext-config[1].data-id=mybatis.yml
spring.cloud.nacos.config.ext-config[1].group=member
spring.cloud.nacos.config.ext-config[1].refresh=true

2.2 配置自动更新

通过 Spring Cloud 原生注解 @RefreshScope 实现配置自动更新,否则需要重启服务。

@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {

    @Value("${useLocalCache:false}")
    private boolean useLocalCache;

    @RequestMapping("/get")
    public boolean get() {
        return useLocalCache;
    }
}

3.启动服务发现

3.1 添加依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>${latest.version}</version>
</dependency>

注意:

  • 版本 2.1.x.RELEASE 对应的是 Spring Boot 2.1.x 版本
  • 版本 2.0.x.RELEASE 对应的是 Spring Boot 2.0.x 版本
  • 版本 1.5.x.RELEASE 对应的是 Spring Boot 1.5.x 版。

3.2 配置服务

  1. 在 bootstrap.properties 或 application.prpoperties 中配置 Nacos server 的地址
server.port=8070
spring.application.name=service-provider

spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
# 如果注册的不是default命名空间,则需要配置对应的命名空间id
spring.cloud.nacos.discovery.namespace=d84d049b-d3b8-44c1-a623-8c74e16bddef
  1. 通过 Spring Cloud 原生注解 @EnableDiscoveryClient 开启服务注册发现功能
@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderApplication {

	public static void main(String[] args) {
		SpringApplication.run(NacosProviderApplication.class, args);
	}

	@RestController
	class EchoController {
		@RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
		public String echo(@PathVariable String string) {
			return "Hello Nacos Discovery " + string;
		}
	}
}
  1. 在nacos客户端服务列表中查看该服务是否注册成功

在这里插入图片描述

4. 相关扩展

  1. 命名空间
  • 配置隔离
  • 默认为public
  • 开发、测试、生产维度做环境隔离
  • 按模块维度进行环境隔离
  1. 配置集:所有配置的集合
  2. 配置集id:配置文件名Data Id
  3. 配置分组Group
  • 默认为DEAAULT_GROUP
  • spring.cloud.nacos.config.ext-config[1].group=member 指定当前配置文件读取member分组下的配置
  • spring.cloud.nacos.config.group=member 同一指定分组
  1. 根据命名空间和分组,可按照不同模块进行隔离不同环境进行分组。

5. 实时读取nacos配置文件

下面案例为naocs配置elasticsearch mapping结构json,调用者获取该json创建mapping,实现半自动创建mapping的目的。

package com.gemp.es.service.impl;

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import com.gemp.es.service.EsIndexService;
import com.gemp.es.service.IndexService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Properties;

/**
 * @author: Mr.wanter
 * @since 2020-9-10 10:10
 */
@Service
public class IndexServiceImpl implements IndexService {

    @Resource
    EsIndexService esIndexService;
	
    @Value("${spring.cloud.nacos.config.server-addr}")
    private String serverAddr;

    @Value("${spring.cloud.nacos.config.group:DEFAULT_GROUP}")
    private String group;

    @Value("${spring.cloud.nacos.config.namespace}")
    private String namespace;

    @Override
    public boolean createIndex(String indexName) {
        String serverAddrIp = serverAddr.split(":")[0];
        String dataId = indexName;
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, serverAddrIp);
        properties.put(PropertyKeyConst.NAMESPACE, namespace);
        ConfigService configService = null;
        String content = null;
        try {
            configService = NacosFactory.createConfigService(properties);
            //获取配置文件数据
            content = configService.getConfig(dataId, group, 5000);
        } catch (NacosException e) {
            e.printStackTrace();
        }
        //业务处理
        boolean result = esIndexService.createIndexMapping(indexName, content);
        return result;
    }

    @Override
    public boolean delIndex(String indexName) {
        return esIndexService.deleteIndex(indexName);
    }

    @Override
    public List getAllIndex() {
        return esIndexService.getAllIndex();
    }
}