一、nacos安装

nacos官网:https://nacos.io/zh-cn/index.html

1. docker-compose安装

  1. Clone项目
git clone https://github.com/nacos-group/nacos-docker.git
cd nacos-docker
  1. 单机模式 Derby
docker-compose -f example/standalone-derby.yaml up
  1. 单机模式 Mysql
docker-compose -f example/standalone-mysql.yaml up
  1. 集群模式
docker-compose -f example/cluster-hostname.yaml up
  1. 启动后可访问:http://你的ip地址:8848/nacos
  2. 容器中的应用 nacos 服务注册不上 nacos docker中的服务能注册吗_微服务

  3. 初始账号密码都是nacos

2. 或者Windows、Linux安装nacos server

  1. 下载网址:https://github.com/alibaba/nacos/releases

    或者从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/

// change the $version to your actual path
cd distribution/target/nacos-server-$version/nacos/bin
  1. 下载对应版本的nacos
    点击spring-cloud-alibaba-dependencies这个文件
  2. 容器中的应用 nacos 服务注册不上 nacos docker中的服务能注册吗_容器中的应用 nacos 服务注册不上_02

  3. 然后在里面搜索nacos,对应的<nacos.client.version>1.1.1</nacos.client.version>就是我们需要下载的对应的版本。
  4. 容器中的应用 nacos 服务注册不上 nacos docker中的服务能注册吗_微服务_03

  5. 下载编译后打包方式
unzip nacos-server-$version.zip 或者 tar -xvf nacos-server-$version.tar.gz
cd nacos/bin
  1. 启动服务器
    Linux/Unix/Mac:
    启动命令(standalone代表着单机模式运行,非集群模式):
sh startup.sh -m standalone

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

bash startup.sh -m standalone

Windows:

cmd startup.cmd

或者双击startup.cmd运行文件(bin目录下)。

  1. 关闭服务器
    Linux/Unix/Mac:
sh shutdown.sh

Windows:

cmd shutdown.cmd

或者双击shutdown.cmd运行文件(bin目录下)。

  1. 启动后可访问:http://localhost:8848/nacos
    账号密码都是nacos

二、服务注册与发现

1. maven项目添加依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

基础的maven完整依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>open.source.test</groupId>
    <artifactId>nacos-discovery-test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>nacos-discovery-test</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>${spring.boot.version}</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring.cloud.alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <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>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2. SpringBoot主启动类添加@EnableDiscoveryClient注解



3.application.yml配置

spring:
  cloud:
    nacos:
      discovery:
        # 地址
        server-addr: localhost:8848
        # 命名空间
        # namespace: eade4058-37c6-4a86-97ca-80413a7af66e
        # 集群名称
        # cluster-name: user-center-cluster
        # 元数据   k-v
        # metadata:
          #	instance: c

4. 服务发现的领域模型

容器中的应用 nacos 服务注册不上 nacos docker中的服务能注册吗_bootstrap_04

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OMhJppYt-1593961790557)(C:\Users\VULCAN\AppData\Roaming\Typora\typora-user-images\image-20200324195923623.png)]

5. namespace和元数据

namespace:
在nacos中,微服务只能调用同一namespace下的微服务,而不能跨越调用,实现了微服务的 隔离。
元数据metadata:
Nacos数据(如配置和服务)描述信息,如服务版本、权重、容灾策略、负载均衡策略、鉴权配置、各种自定义标签 (label),从作用范围来看,分为服务级别的元信息、集群的元信息及实例的元信息。
元数据的作用:

  • 提供描述信息
  • 让微服务调用更加灵活(例如:微服务版本控制)


三、Nacos配置管理

1. 为什么要实现配置管理

  • 不同环境,不同配置
  • 配置属性动态更新

2. 项目架构图

容器中的应用 nacos 服务注册不上 nacos docker中的服务能注册吗_容器中的应用 nacos 服务注册不上_05

3. 使用Nacos管理配置

1. 基本配置
  1. pom.xml
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
  1. 写配置

    创建一个新的配置文件bootstrap.yml,一下配置一定要写在bootstrap.yml,写在application.yml是不生效的
spring:
  cloud:
    nacos:
      config:
        server-addr: localhost:8848
        file-extension: yaml
  application:
    name: content-center
  profiles:
    active: dev
  1. Nacos控制台配置
    nacos控制台点击配置列表,创建一个配置
  2. 测试
    测试代码:
@Value("${your.configuration}")
private String yourConfiguration;

@GetMapping("/test-config")
public String testConfiguration() {
    return this.yourConfiguration;
}

能够获取到其配置的内容

容器中的应用 nacos 服务注册不上 nacos docker中的服务能注册吗_微服务_06

4. 配置动态属性刷新与回滚

  1. 动态属性刷新
    添加 @RefreshScope注解:
    只需要在想修改的配置属性所在的类上添加 @RefreshScope注解

    修改配置内容,不重启服务也能动态获取
  2. 回滚
    nacos配置管理中,点击历史版本,输入id和group,即可查看配置的历史版本,并可以回滚

    回滚bug:

5. 应用的共享配置

  1. 通用配置
    修改bootstrap.yml,把dev环境改查prod环境
spring:
  cloud:
    nacos:
      config:
        server-addr: localhost:8848
        file-extension: yaml
  application:
    name: content-center
  profiles:
    active: prod

nacos新增content-center.yaml配置(通用配置,没有后缀)

容器中的应用 nacos 服务注册不上 nacos docker中的服务能注册吗_bootstrap_07


尽管修改了bootstrap文件中微服务的配置环境为prod,但还是能够读取到通用配置中的内容

容器中的应用 nacos 服务注册不上 nacos docker中的服务能注册吗_容器中的应用 nacos 服务注册不上_08


而把bootstrap文件中微服务的配置环境改回dev,获取的值是content-center-dev.yaml的值

容器中的应用 nacos 服务注册不上 nacos docker中的服务能注册吗_bootstrap_09

  1. 配置共享
    实现不同微服务的配置共享。
    在开发中,我们可以把不同微服务相同的配置抽取到共享配置中,如mysql连接配置、nacos服务发现配置等。
  1. 方式一:shared-dataids
    在需要配置的微服务的bootstrap.yml中添加以下配置,然后在nacos配置管理添加被共享的配置,如下面的common1.yaml,common2.yaml,即可读取到common1.yaml,common2.yaml中的配置。
  2. 方式二:ext-config
    在需要配置的微服务的bootstrap.yml中添加以下配置,然后在nacos配置管理添加被共享的配置
  3. 优先级对比

6. 引导上下文

  1. 用来连接配置服务器,读取外部配置
    对于我们的bootstrap.yml就是引导上下文的配置文件,对于我们的应用,通过bootstrap.yml来连接nacos,读取nacos里面的配置。
  2. Application Context的父上下文

7. 远程配置 & 本地配置优先级

在远程配置中添加以下配置,即可修改优先级

容器中的应用 nacos 服务注册不上 nacos docker中的服务能注册吗_bootstrap_10

8. 最佳实践总结

  • 能放本地,不放远程
  • 尽量规避优先级
  • 定规范,例如所有的配置属性都要加上注释
  • 配置管理人员尽量少


四、Nacos数据持久化

容器中的应用 nacos 服务注册不上 nacos docker中的服务能注册吗_微服务_11

自定义数据持久化:

Nacos的单机运行模式仅适用于学习与测试环境,对于有高可用要求的生产环境显然是不合适的。那么,我们是否可以直接启动多个单机模式的Nacos,然后客户端指定多个Nacos节点就可以实现高可用吗?答案是否定的。

在搭建Nacos集群之前,我们需要先修改Nacos的数据持久化配置为MySQL存储。默认情况下,Nacos使用嵌入式数据库实现数据的存储。所以,如果启动多个默认配置下的Nacos节点,数据存储是存在一致性问题的。为了解决这个问题,Nacos采用了集中式存储的方式来支持集群化部署,目前只要支持MySQL的存储。

配置Nacos的MySQL存储只需要下面三步:

  1. 安装数据库,版本要求:5.6.5+
  2. 初始化MySQL数据库,数据库初始化文件:nacos-mysql.sql,该文件可以在Nacos程序包下的conf目录下获得。执行完成后可以得到如下图所示的表结构:
  3. 修改conf/application.properties文件,增加支持MySQL数据源配置,添加(目前只支持mysql)数据源的url、用户名和密码。配置样例如下:
spring.datasource.platform=mysql

db.num=1
db.url.0=jdbc:mysql://localhost:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=

深入思考:

关于Nacos数据的持久化实现,与其他的中间件相比,在实现上并没有采用分布式算法来解决一致性问题,而是采用了比较常规的集中化存储来实现。由于采用单一数据源的方式,直接解决了分布式一致性问题,所以从学习成本的角度上来说,Nacos的实现原理会更容易被理解和接受。但是,从部署的负责度和硬件投入成本上来说,与etcd、consul、zookeeper这些通过算法方式解决一致性问题的中间件相比,就显得不足了。

同时,在引入MySQL的存储时,由于多了一个中间件的存在,整个Nacos系统的整体可用性一定是会所有下降的。所以为了弥补可用性的下降,在生产上MySQL的高可用部署也是必须的,成本再次提高。不论如何提高,可用性都难以达到100%,所以这种方式,不论如何提升存储的可用性,理论上都会对Nacos集群的自身可用性造成微小的下降。

以上思考主要从理论上,粗略讨论的,并没有经过详细的成本评估与可用性计算。所以,对于实际应用场景下,可能这些成本的增加和可用性的降低并没有那么多大的影响。同时,Spring Cloud Alibaba下使用的各开源组件都有对应的商业产品,在没有足够运维人力的团队下,使用对应的商业产品可能从各方面都会更加划算。