Spring Cloud笔记-Spring Cloud Alibaba Nacos服务注册和配置中心(十八)

1.Nacos简介

Nacos命名的前四个字母分别取自Naming(服务注册,即服务命名管理)和Configuration(服务配置)的前两个字母,s取自Service,也就是服务的意思。它是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

简单一句话:Nacos=注册中心+配置中心=Eureka+Config+Bus。

Nacos官网地址:https://nacos.io/zh-cn/,可以在这里下载和查阅官方文档。

各种服务注册中心的比较
服务注册与服务发现框架CAP模型控制台管理社区活跃度
EurekaAP支持低(2.x版本闭源)
ZookeeperCP不支持
ConsulCP支持
NacosAP支持

2.安装并运行Nacos

1.Windows安装

通过Nacos下载地址选择合适的版本(最好选稳定版本)下载zip包,需要本地配置好了Java8和Maven环境,解压缩后,运行startup.cmd启动Nacos,浏览器访问http://localhost:8848/nacos查看管理后台,输入用户名密码(都是nacos)进入。

2.Linux安装

这里还是采用Docker的安装和启动方式,命令如下。

[root@bogon ~]# docker search nacos # 搜索Nacos镜像,这里只列出了第一个,我们等下也要用这个
INDEX       NAME                                          DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
docker.io   docker.io/nacos/nacos-server                  This project contains a Docker image meant...   73                   [OK]
[root@bogon ~]# docker pull docker.io/nacos/nacos-server:1.3.0 # 拉取1.3.0版本镜像,稍等片刻,如果不带tag时候,默认下载的最新版本
[root@bogon ~]# docker run --env MODE=standalone -d -p 8848:8848 nacos/nacos-server:1.3.0 # 后台运行Nacos,以单机模式运行
[root@bogon ~]# docker ps # 查看当前运行中的docker容器
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                               NAMES
563aac734e9e        nacos/nacos-server:1.3.0   "bin/docker-startu..."   26 seconds ago      Up 24 seconds       0.0.0.0:8848->8848/tcp              practical_mcnulty
[root@bogon ~]# docker ps -a # 查看所有容器(不管是运行的还是没运行的)
CONTAINER ID        IMAGE                                  COMMAND                  CREATED              STATUS                      PORTS                                                                                        NAMES
563aac734e9e        nacos/nacos-server:1.3.0               "bin/docker-startu..."   About a minute ago   Up About a minute           0.0.0.0:8848->8848/tcp                                                                       practical_mcnulty
4d6cb9734993        nacos/nacos-server:1.3.0               "bin/docker-startu..."   3 minutes ago        Exited (1) 2 minutes ago                                                                                                 amazing_liskov
e4622b9228e7        rabbitmq:management                    "docker-entrypoint..."   7 days ago           Exited (255) 23 hours ago   4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, 15671/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp   dreamy_cray
262532b32087        consul:1.6.1                           "docker-entrypoint..."   2 weeks ago          Exited (255) 7 days ago     8300-8302/tcp, 8301-8302/udp, 8600/tcp, 8600/udp, 0.0.0.0:8500->8500/tcp                     condescending_bartik
12121ee7ccdf        zookeeper:3.4.9                        "/docker-entrypoin..."   3 weeks ago          Exited (143) 4 hours ago                                                                                                 focused_mclean
3a4738e5d496        elasticsearch:6.8.7                    "/usr/local/bin/do..."   7 weeks ago          Exited (255) 7 weeks ago    0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp                                               xenodochial_banach
5eb892279b83        docker.io/rabbitmq:3.7.26-management   "docker-entrypoint..."   7 weeks ago          Exited (255) 7 weeks ago    4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, 15671/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp   nifty_visvesvaraya
9478537d54f6        redis                                  "docker-entrypoint..."   7 weeks ago          Exited (255) 7 weeks ago    0.0.0.0:6379->6379/tcp                                                                       frosty_easley
0c492ce51767        mysql                                  "docker-entrypoint..."   2 months ago         Up 51 minutes               0.0.0.0:3306->3306/tcp, 33060/tcp                                                            jolly_sammet
73f3714f4798        tomcat:8.5.34                          "catalina.sh run"        2 months ago         Exited (143) 2 months ago                                                                                                myTomcat
[root@bogon ~]# docker start 563aac734e9e # 如果已经有了容器,但是容器是关闭状态的,只需要使用docker start 容器id启动即可

安装完成,启动成功后,访问http://192.168.0.123:8848/nacos,输入用户名密码(都是nacos)查看管理后台。

3.Nacos作为服务注册中心演示

这里,我们需要创建一个服务提供者和一个服务消费者,把他们都注册进Nacos里。

基于Nacos的服务提供者

官方文档:https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_start_a_provider_application

新建cloudalibaba-provider-payment9001模块,在父pom.xml的dependencyManagement坐标的dependencies中加入spring-cloud-alibaba-dependencies坐标。

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.2.0.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

修改子模块的pom.xml,加入spring-cloud-starter-alibaba-nacos-discovery坐标。

<?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">
    <parent>
        <artifactId>cloud2020</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cloudalibaba-provider-payment9001</artifactId>
    <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.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

添加application.yml配置文件。

server:
  port: 9001
spring:
  application:
    name: nacos-payment-provider
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.0.123:8848 # 指明Nacos的地址
management:
  endpoints:
    web:
      exposure:
        include: '*'

添加主启动类,带上@EnableDiscoveryClient用于开启服务发现功能。

package com.atguigu.springcloud.alibaba;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@EnableDiscoveryClient
@SpringBootApplication
public class PaymentMain9001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain9001.class, args);
    }
}

添加业务类便于测试。

package com.atguigu.springcloud.alibaba.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PaymentController {
    @Value("${server.port}")
    private String serverPort;

    @GetMapping(value = "/payment/nacos/{id}")
    public String getPayment(@PathVariable("id") Integer id) {
        return "Hello Nacos Discovery: " + serverPort + "\t id: " + id;
    }
}
 

启动Nacos,启动Provider9001模块访问http://192.168.0.123:8848/nacos,点击左侧“服务管理”-“服务列表”即可看到Provider9001服务已经注册进来了。

Nacos自带负载均衡,为了演示负载均衡,仿照cloudalibaba-provider-payment9001模块创建cloudalibaba-provider-payment9002模块,端口号做相应的修改即可,其他大致相同。

创建完成后,启动Provider9002,查看Nacos管理后台,nacos-payment-provider服务名对应的实例数由1变成了2。

基于Nacos的服务消费者

官方文档:https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_start_a_consumer_application

新建cloudalibaba-consumer-nacos-order83模块,pom.xml和cloudalibaba-provider-payment9001一样。添加application.yml。

server:
  port: 83
spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.0.123:8848 # 配置Nacos地址
# 消费者将去访问的微服务地址,这里采用服务名称查找服务(成功注册进nacos的微服务提供者)
service-url:
  nacos-user-service: http://nacos-payment-provider

主启动类和cloudalibaba-provider-payment9001一样,需要带上@EnableDiscoveryClient注解。添加业务类。

package com.atuguigu.springcloud.alibaba.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@RestController
@Slf4j
public class OrderNacosController {
    @Resource
    private RestTemplate restTemplate;

    @Value("${service-url.nacos-user-service}")// 读取application.yml里的值
    private String serverURL;

    @GetMapping(value = "/consumer/payment/nacos/{id}")
    public String paymentInfo(@PathVariable("id") Integer id) {
        return restTemplate.getForObject(serverURL + "/payment/nacos/" + id, String.class);
    }
}

添加配置类,注意,这里一定要带上@LoadBalance注解,因为我们是通过服务名访问生产者的,即使只有一个生产者,通过服务名访问,也要带上@LoadBalance注解,否则会报错。

package com.atuguigu.springcloud.alibaba.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ApplicationContextConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

启动两个生产者和一个消费者,通过浏览器访问http://localhost:83/consumer/payment/nacos/1,根据请求返回值,可以看到负载均衡生效了,实际上,Nacos有负载均衡能力,是因为它包含了Ribbon的jar包。

服务注册中心对比

Nacos和其他服务注册中心特性对比
 NacosEurekaConsulCoreDNSZookeeper
一致性检查CP+APAPCP/CP
健康检查TCP/HTTP/MySQL/Client BeatClient BeatTCP/HTTP/gRPC/Cmd/Client Beat
负载均衡权重/DSL/metadata/CMDBRibbonFabioRR/
雪崩保护支持支持不支持不支持不支持
自动注销实例支持支持不支持不支持支持
访问协议HTTP/DNS/UDPHTTPHTTP/DNSDNSTCP
监听支持支持支持支持不支持支持
多数据中心支持支持支持不支持不支持
跨注册中心支持不支持支持不支持不支持
Spring Cloud集成支持支持支持不支持不支持
Dubbo集成支持不支持不支持不支持支持
Kubernetes集成支持不支持支持支持不支持

Nacos支持AP和CP的切换,命令如下。

curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'

如果不需要存储服务界别的信息且服务实例是通过nacos-client注册的,并且能够保持心跳上报,那么就可以选择AP模式,当前主流服务如Spring Cloud和Dubbo服务,都适用于AP模式,AP模式为了服务的可用性减弱了一致性,因此AP模式下只支持注册临时实例。

如果需要在服务级别编辑或存储配置信息,必须使用CP,Kubernetes服务和DNS服务都适用于CP模式,CP模式下支持注册持久化实例,此时以Raft协议为集群运行,该模式下注册实例前必须先注册服务,如果服务不存在,会报错。

4.Nacos作为服务配置中心演示

1.基础配置

新建cloudalibaba-config-nacos-client3377模块,修改pom.xml,加入spring-cloud-starter-alibaba-nacos-config和spring-cloud-starter-alibaba-nacos-discovery坐标。

<?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">
    <parent>
        <artifactId>cloud2020</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cloudalibaba-config-nacos-client3377</artifactId>
    <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.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

添加bootstrap.yml和application.yml配置文件。这里的bootstrap.yml和application.yml和之前的Spring Cloud Config里的意思是一样的,在项目初始化的时候,会先读取bootstrap.yml,后读取application.yml,其中bootstrap.yml属于系统层面,application.yml属于应用层面。

bootstrap.yml

server:
  port: 3377
spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.0.123:8848 # Nacos服务注册中心地址
      config:
        server-addr: 192.168.0.123:8848 # Nacos作为配置中心地址
        file-extension: yml #指定yml格式配置

application.yml

spring:
  profiles:
    active: dev # 表示开发环境

添加主启动类,带上@EnableDiscoveryClient注解。

package com.atguigu.springcloud.alibaba;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class NacosConfigClientMain3377 {
    public static void main(String[] args) {
        SpringApplication.run(NacosConfigClientMain3377.class, args);
    }
}

添加业务类,用于测试

package com.atguigu.springcloud.alibaba.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RefreshScope // 通过Spring Cloud原生注解@RefreshScope实现配置自动刷新
public class ConfigClientController {
    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/config/info")
    public String getConfigInfo() {
        return configInfo;
    }
}

我们配置bootstrap.yml的目的,就是让模块启动的时候,读取bootstrap.yml的内容,去Nacos上查找配置文件的,那么查找配置文件的规则是怎样的呢?

官方文档可以看到一个公式:${prefix}-${spring.profile.active}.${file-extension}。下面也对这里的参数做了解释:

  • ${prefix}:默认为spring.application.name的值,也可以通过配置项spring.cloud.nacos.config.prefix来配置
  • ${spring.profile.active}:为当前环境对应的profile,当spring.profile.active为空时,对应的连接符-也将不存在,dataId的拼接格式变成${prefix}.${file-extension}
  • ${file-extension}:为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension来配置,目前只支持 properties和yaml类型

根据bootstrap.yml和application.yml可知,这个公式对应的值是:nacos-config-client-dev.yml,有了这个值,就可以在Nacos管理后台做配置了,这个值对应管理后台的Data Id。

进入Nacos管理后台,点击“配置管理”-“配置列表”,点击右侧的“+”,将刚才的值输入到Data Id里。Group保持DEFAULT_GROUP默认即可,配置格式选择YAML,在配置内容里输入如下内容,也就是要对应测试类Controller中的@Value("${config.info}"),最后点击“发布”即可。

config:
  info: "this is nacos-config-client-dev.yml version=1"

启动nacos-client3377模块,访问http://localhost:3377/config/info,可以读取到刚才的配置文件,接下来,我们在Nacos上修改配置文件,再次发布,访问http://localhost:3377/config/info,发现读取到的配置信息立刻就变化了。

2.分组配置

在前面,我们往Nacos里添加配置文件的时候,可以发现有Data Id,Group,命名空间(NameSpace)这些参数,通过这些参数,我们可以把配置文件做分组,便于查找和归类。

其中NameSpace用于区分部署环境,Group和Data Id在逻辑上区分两个目标对象。

根据官方文档的说明,我们可以知道:

  • NameSpace:用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的Group或Data ID的配置。Namespace的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
  • Group:Nacos中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串对配置集进行分组,从而区分Data ID相同的配置集。当您在Nacos上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用DEFAULT_GROUP。配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如database_url配置和MQ_topic配置。
  • Data Id:Nacos中的某个配置集的ID。配置集ID是组织划分配置的维度之一。Data ID通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。

Data Id配置方案:使用默认的NameSpace和默认的Group,在Nacos管理后台创建两个不同Data Id的配置文件,通过修改application.yml里的spring.profile.active的值,即可实现读取不同配置文件。

Group配置方案:在Nacos管理后台创建一个Group,创建几个配置文件,在Group里输入刚才创建的Group的名称。要想读取指定Group下的配置文件,需要在spring.cloud.nacos.config下添加一个group属性,指定要访问哪个Group取配置文件。

NameSpace配置方案:在Nacos管理后台创建一个NameSpace,在它下面创建几个配置文件,要想读取自定义NameSpace下的配置文件,需要在spring.cloud.nacos.config下添加一个namespace属性,值为命名空间的ID。

如果把Data Id、Group、NameSpace类比成一个Java项目的话,那么NameSpace可以类比为一个模块,Group可以类比为某个模块里的一个包,Data Id可以类比为一个类。目的就是为了不同粒度的配置隔离。

5.Nacos集群和持久化配置(重要)

1.官网说明

Nacos单机部署手册官方文档地址:https://nacos.io/zh-cn/docs/deployment.html

Nacos集群搭建手册官方文档地址:https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html

在重启Nacos后,我们可以看到,之前的配置还是存在的,这是因为Nacos里内置了Derby数据库,但是,因为我们不方便操作Derby数据库,所以,改用MySQL和Nacos进行整合。

另外,正式环境,不可能只有一台Nacos服务,需要Nacos服务集群模式。如果启动了多个Nacos结点,数据存储存在一致性问题,为了解决这个问题,Nacos采用集中式存储来支持集群化部署,目前只支持MySQL存储。

我们先对单机支持MySQL数据库,具体操作步骤:

  1. 安装MySQL数据库,版本:5.6.5+
  2. 使用数据库初始化文件初始化MySQL数据库,配置文件的内容不要修改
  3. 修改Nacos的conf/application.properties配置文件,增加MySQL数据源配置支持

2.Nacos持久化配置解释

docker下载安装MySQL镜像,这里我的Nacos使用的是1.3.0版本,MySQL使用的是8.0.19版本(踩坑了,后面说)。

首先创建nacos_config数据库,然后在这个数据库下,使用数据库初始化文件初始化MySQL数据库,这个用Navicat连接上MySQL执行即可。

使用如下命令,进入Docker容器中Nacos目录,并修改application.properties。

[root@bogon ~]# docker ps # 查看当前运行的容器
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                               NAMES
563aac734e9e        nacos/nacos-server:1.3.0   "bin/docker-startu..."   9 minutes ago       Up 9 minutes        0.0.0.0:8848->8848/tcp              practical_mcnulty
0c492ce51767        mysql                      "docker-entrypoint..."   2 months ago        Up 58 minutes       0.0.0.0:3306->3306/tcp, 33060/tcp   jolly_sammet
[root@bogon ~]# docker exec -it practical_mcnulty bash # 进入Nacos里,这里的practical_mcnulty是docker ps命令中,Nacos的NAMES字段值,因为我没有取别名
[root@563aac734e9e nacos]# cd conf/ # 进入conf目录下,就能找到application.properties了
[root@563aac734e9e conf]# ll
total 40
-rw-r--r--. 1 root root   2180 Jun  5 18:47 application.properties
-rw-r--r--. 1  501 games 25080 Jun  5 16:33 nacos-logback.xml
-rw-r--r--. 1  501 games  7456 May 15 18:35 schema.sql
[root@563aac734e9e conf]# exit # 使用exit命令退出Docker容器
exit

可以看到如下内容:

# spring
server.servlet.contextPath=${SERVER_SERVLET_CONTEXTPATH:/nacos}
server.contextPath=/nacos
server.port=${NACOS_APPLICATION_PORT:8848}
spring.datasource.platform=${SPRING_DATASOURCE_PLATFORM:""}
nacos.cmdb.dumpTaskInterval=3600
nacos.cmdb.eventTaskInterval=10
nacos.cmdb.labelTaskInterval=300
nacos.cmdb.loadDataAtStart=false
db.num=${MYSQL_DATABASE_NUM:1}
db.url.0=jdbc:mysql://${MYSQL_SERVICE_HOST}:${MYSQL_SERVICE_PORT:3306}/${MYSQL_SERVICE_DB_NAME}?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.url.1=jdbc:mysql://${MYSQL_SERVICE_HOST}:${MYSQL_SERVICE_PORT:3306}/${MYSQL_SERVICE_DB_NAME}?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=${MYSQL_SERVICE_USER}
db.password=${MYSQL_SERVICE_PASSWORD}
### The auth system to use, currently only 'nacos' is supported:
nacos.core.auth.system.type=${NACOS_AUTH_SYSTEM_TYPE:nacos}


### The token expiration in seconds:
nacos.core.auth.default.token.expire.seconds=${NACOS_AUTH_TOKEN_EXPIRE_SECONDS:18000}

### The default token:
nacos.core.auth.default.token.secret.key=${NACOS_AUTH_TOKEN:SecretKey012345678901234567890123456789012345678901234567890123456789}

### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay.
nacos.core.auth.caching.enabled=${NACOS_AUTH_CACHE_ENABLE:false}

server.tomcat.accesslog.enabled=${TOMCAT_ACCESSLOG_ENABLED:false}
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D
# default current work dir
server.tomcat.basedir=
## spring security config
### turn off security
nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**
# metrics for elastic search
management.metrics.export.elastic.enabled=false
management.metrics.export.influx.enabled=false

nacos.naming.distro.taskDispatchThreadCount=10
nacos.naming.distro.taskDispatchPeriod=200
nacos.naming.distro.batchSyncKeyCount=1000
nacos.naming.distro.initDataRatio=0.9
nacos.naming.distro.syncRetryDelay=5000
nacos.naming.data.warmup=true

这个里面有许多${key:value}形式的东西,代表的意思是在Nacos启动的时候,读取启动参数里的key,如果读取不到就使用冒号后面的值,我们的启动参数里并没有带这些值,所以,我们就直接修改配置文件好了。修改后的内容:

# spring
server.servlet.contextPath=${SERVER_SERVLET_CONTEXTPATH:/nacos}
server.contextPath=/nacos
server.port=${NACOS_APPLICATION_PORT:8848}
spring.datasource.platform=mysql
nacos.cmdb.dumpTaskInterval=3600
nacos.cmdb.eventTaskInterval=10
nacos.cmdb.labelTaskInterval=300
nacos.cmdb.loadDataAtStart=false
db.num=1
db.url.0=jdbc:mysql://192.168.0.123:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
db.url.1=jdbc:mysql://${MYSQL_SERVICE_HOST}:${MYSQL_SERVICE_PORT:3306}/${MYSQL_SERVICE_DB_NAME}?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=root
### The auth system to use, currently only 'nacos' is supported:
nacos.core.auth.system.type=${NACOS_AUTH_SYSTEM_TYPE:nacos}


### The token expiration in seconds:
nacos.core.auth.default.token.expire.seconds=${NACOS_AUTH_TOKEN_EXPIRE_SECONDS:18000}

### The default token:
nacos.core.auth.default.token.secret.key=${NACOS_AUTH_TOKEN:SecretKey012345678901234567890123456789012345678901234567890123456789}

### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay.
nacos.core.auth.caching.enabled=${NACOS_AUTH_CACHE_ENABLE:false}

server.tomcat.accesslog.enabled=${TOMCAT_ACCESSLOG_ENABLED:false}
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D
# default current work dir
server.tomcat.basedir=
## spring security config
### turn off security
nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**
# metrics for elastic search
management.metrics.export.elastic.enabled=false
management.metrics.export.influx.enabled=false

nacos.naming.distro.taskDispatchThreadCount=10
nacos.naming.distro.taskDispatchPeriod=200
nacos.naming.distro.batchSyncKeyCount=1000
nacos.naming.distro.initDataRatio=0.9
nacos.naming.distro.syncRetryDelay=5000
nacos.naming.data.warmup=true

重启Nacos查看效果。然后崩了,访问http://192.168.0.123:8848/nacos/进不去了,可是查找原因:Nacos还不支持MySQL8。

于是,我到Nacos的GitHub上查看,找到了这个:https://github.com/alibaba/nacos/pull/3060,里面说已经支持MySQL8数据库驱动了,再看一眼更新日期:12天前,也就是2020-06-15,回看Docker Hub上的Nacos:1.3.0信息的更新时间:19天前,也就是2020-06-08。好吧,1.3.0版本的还没有更新MySQL8驱动,白高兴了,或许使用latest(更新时间8天前,也就是2020-06-19)就支持了(这个我没有测试,只是猜测),后续正式版本应该就支持了吧。

好吧,这里把MySQL版本换成5.7的,继续走上面的步骤,重启Nacos查看效果,又崩了,查看日志,大致意思是没有找到数据源,仔细对比了一些MySQL连接,找到错了,创建的数据库是nacos_config,可是数据库连接写成了nacos-config,修改后,重启,一切正常了。

3.Linux版Nacos+MySQL生产环境配置

Linux的下载安装启动,和Windows上类似,去官网下载即可,Linux需要下在*.tar.gz文件,下载后解压,在bin文件夹下可以看到startup.sh,启动即可。这里,我继续使用Docker进行操作,也是复习一下Docker。

为了演示集群搭建,我们需要一个Nginx,三个Nacos,一个MySQL。使用Docker安装Nginx并启动。

[root@bogon ~]# docker pull nginx:stable
Trying to pull repository docker.io/library/nginx ...
stable: Pulling from docker.io/library/nginx
8559a31e96f4: Already exists
9a38be3aab21: Pull complete
522e5edd83fa: Pull complete
2ccf5a90baa6: Pull complete
Digest: sha256:159aedcc6acb8147c524ec2d11f02112bc21f9e8eb33e328fb7c04b05fc44e1c
Status: Downloaded newer image for docker.io/nginx:stable
[root@bogon ~]# docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
docker.io/rabbitmq             management          95bc78c8d15d        10 days ago         187 MB
docker.io/nginx                stable              9fc56f7e4c11        2 weeks ago         132 MB
docker.io/mysql                5.7                 9cfcce23593a        2 weeks ago         448 MB
docker.io/nacos/nacos-server   1.3.0               d1f1facebfbc        3 weeks ago         756 MB
docker.io/rabbitmq             3.7.26-management   d2d45254c99b        7 weeks ago         180 MB
docker.io/redis                latest              f9b990972689        8 weeks ago         104 MB
docker.io/mysql                latest              0c27e8e5fcfa        2 months ago        546 MB
docker.io/elasticsearch        6.8.7               9cdc9986c313        4 months ago        880 MB
docker.io/consul               1.6.1               48b314e920d6        9 months ago        116 MB
docker.io/tomcat               8.5.34              ca9e2fccef98        20 months ago       463 MB
docker.io/zookeeper            3.4.9               3b83d9104a4c        3 years ago         129 MB
[root@bogon ~]# docker run -d -p 80:80 nginx:stable
e950da524e2aa17716f435fe5e745978b4ea36e7fd53a6506efcbed2f7946c7a
[root@bogon ~]# docker ps
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                               NAMES
e950da524e2a        nginx:stable               "nginx -g 'daemon ..."   3 seconds ago       Up 2 seconds        0.0.0.0:80->80/tcp                  festive_booth
fe0f363d0c89        mysql:5.7                  "docker-entrypoint..."   About an hour ago   Up About an hour    0.0.0.0:3306->3306/tcp, 33060/tcp   hungry_colden
563aac734e9e        nacos/nacos-server:1.3.0   "bin/docker-startu..."   2 hours ago         Up 52 minutes       0.0.0.0:8848->8848/tcp              practical_mcnulty
[root@bogon ~]#

通过浏览器访问http://192.168.0.123:80,如果能看到Welcome to nginx!说明Nginx启动成功。Nginx先放到一边过会再做配置,先搭建Nacos集群。

经历了2天的折腾,终于把Nacos集群搞好了,差点放弃,因为官方文档更新不及时,我踩坑了……后文会说。

先说一下我的集群环境,我这里使用的是nacos/nacos-server:1.3.0的镜像,在一台机器上通过Docker镜像的方式,部署了3台Nacos,通过端口号作为区分,虚拟机分配了4G内存(勉强够用,小了恐怕启动不起来),下面开始吧。

docker pull nacos/nacos-server:1.3.0 # 拉取nacos/nacos-server:1.3.0镜像,静静等待即可
# 输入以下命令,搭建集群
docker run -d \
-e MODE=cluster \
-e NACOS_APPLICATION_PORT=3333 \
-e NACOS_SERVERS=192.168.0.123:3333,192.168.0.123:4444,192.168.0.123:5555 \
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e MYSQL_SERVICE_HOST=192.168.0.123 \
-e MYSQL_SERVICE_PORT=3306 \
-e MYSQL_SERVICE_USER=root \
-e MYSQL_SERVICE_PASSWORD=root \
-e MYSQL_SERVICE_DB_NAME=nacos_config \
-e NACOS_SERVER_IP=192.168.0.123 \
-p 3333:3333 \
--name nacos3333 \
nacos/nacos-server:1.3.0

docker run -d \
-e MODE=cluster \
-e NACOS_APPLICATION_PORT=4444 \
-e NACOS_SERVERS=192.168.0.123:3333,192.168.0.123:4444,192.168.0.123:5555 \
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e MYSQL_SERVICE_HOST=192.168.0.123 \
-e MYSQL_SERVICE_PORT=3306 \
-e MYSQL_SERVICE_USER=root \
-e MYSQL_SERVICE_PASSWORD=root \
-e MYSQL_SERVICE_DB_NAME=nacos_config \
-e NACOS_SERVER_IP=192.168.0.123 \
-p 4444:4444 \
--name nacos4444 \
nacos/nacos-server:1.3.0

docker run -d \
-e MODE=cluster \
-e NACOS_APPLICATION_PORT=5555 \
-e NACOS_SERVERS=192.168.0.123:3333,192.168.0.123:4444,192.168.0.123:5555 \
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e MYSQL_SERVICE_HOST=192.168.0.123 \
-e MYSQL_SERVICE_PORT=3306 \
-e MYSQL_SERVICE_USER=root \
-e MYSQL_SERVICE_PASSWORD=root \
-e MYSQL_SERVICE_DB_NAME=nacos_config \
-e NACOS_SERVER_IP=192.168.0.123 \
-p 5555:5555 \
--name nacos5555 \
nacos/nacos-server:1.3.0

拿一个出来简单说说配置吧。

docker run -d \ # -d表示是后台运行
-e MODE=cluster \ # 以集群模式运行
-e NACOS_APPLICATION_PORT=3333 \ # 这台Nacos服务的port是3333
-e NACOS_SERVERS=192.168.0.123:3333,192.168.0.123:4444,192.168.0.123:5555 \ # Nacos集群的所有机器的信息
-e SPRING_DATASOURCE_PLATFORM=mysql \ # 使用外置MySQL存储配置信息
-e MYSQL_SERVICE_HOST=192.168.0.123 \ # 外置MySQL的IP
-e MYSQL_SERVICE_PORT=3306 \ # 外置MySQL的port
-e MYSQL_SERVICE_USER=root \ # 外置MySQL的用户名
-e MYSQL_SERVICE_PASSWORD=root \ # 外置MySQL的密码
-e MYSQL_SERVICE_DB_NAME=nacos_config \ # 外置MySQL的数据库,也就是Nacos的配置文件要存储得到哪个数据库,这个在单机版Nacos使用外置数据库时候介绍过
-e NACOS_SERVER_IP=192.168.0.123 \ # 这台Nacos服务的IP
-p 3333:3333 \ # 容器外部端口映射
--name nacos3333 \ # 给容器起个名字吧
nacos/nacos-server:1.3.0 # 运行哪个镜像

先说下我碰到的坑,从官方文档找参数,Nacos的port对应的是NACOS_SERVER_PORT,那就照着写呗,写上之后,3台启动呗,启动后,使用命令docker logs -f 容器id查看启动日志,3台Nacos看到的都是Nacos started successfully in cluster mode. use external storage,表示启动成功了,那就访问访问呗,结果,提示“无法访问此网站,拒绝了我们的连接请求”,这就很尴尬,肯定是哪里还有问题。进入其中某一台机器,查看conf/naming-raft.log日志,提示的是no leader is available now!,也就是这个集群没有leader,奇了怪了,3台机器都正常启动,正常情况下,要选出一个leader呀。

反反复复检查了几遍参数,并对照着文档看了下,没写错呀,删掉容器重建,折腾了5,6次,还是不行,关于报错,也是没有查到什么有帮助的解释。

这时候,我突然发现了文档上的一个问题,MYSQL_DATABASE_NUM给的默认值是2,和之前conf/application.properties里的${MYSQL_DATABASE_NUM:1}默认值是1不符呀?哪里错了?翻了翻GitHub,找到了答案:移除数据库主从镜像配置。再看官方文档,里面还有MYSQL_MASTER_SERVICE_HOST、MYSQL_SLAVE_SERVICE_HOST等字眼。突然意识到了一个问题:文档很可能没有更新。

查看bin/docker-startup.sh和conf/application.properties这两个文件,因为我们通过-e指定的参数,大多数都用在这里了,很快我发现了conf/application.properties里的{NACOS_APPLICATION_PORT:8848},似曾相识啊!和NACOS_SERVER_PORT确实有点像,坑点就在这里:对于nacos/nacos-server:1.3.0镜像,自定义Nacos端口号的时候,不要使用NACOS_SERVER_PORT,要使用NACOS_APPLICATION_PORT!因为conf/application.properties里写了。

在看bin/docker-startup.sh的时候,我发现了这么一段,不懂Bash,但是大致能看懂一些,就是遍历${NACOS_SERVERS}的值,把它们输出到$CLUSTER_CONF文件里。

function print_servers(){
   if [[ ! -d "${PLUGINS_DIR}" ]]; then
    echo "" > "$CLUSTER_CONF"
    for server in ${NACOS_SERVERS}; do
            echo "$server" >> "$CLUSTER_CONF"
    done
   else
    bash $PLUGINS_DIR/plugin.sh
   sleep 30
        fi
}

看看这个配置文件里写了什么,这就有意思了,打开配置文件cluster.conf一看,里面竟然有4行ip:port值,除了我定义的3333,4444,5555端口之外,还有一个8848端口,这是怎么冒出来的?又一次验证了我对端口配置的怀疑,自定义端口可能没生效,有的服务可能走了默认端口。

抱着试一试的想法,把-e参数里的NACOS_SERVER_PORT改成了NACOS_APPLICATION_PORT,启动3台机器容器,访问http://192.168.0.123:3333/nacos/http://192.168.0.123:4444/nacos/http://192.168.0.123:5555/nacos/都可以正常访问了,和刚才相比,向成功迈进了一步。再点击“集群管理”-“结点列表”查看结点,集群搭建成功了!

现在是2020-06-29,文档还没有更新,贴一下吧,踩过的坑……

这种方式搭建Nacos集群有点麻烦,另外介绍一种简单点的方式:使用docker-compose运行Nacos集群,下面开始操作。

使用命令“docker-compose -v”查看本机是否安装过docker-compose,如果没有安装,可以参考这里进行安装。

[root@localhost ~]# sudo curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # 下载docker-compose
……
[root@localhost ~]# sudo chmod +x /usr/local/bin/docker-compose # 给docker-compose加运行权限
[root@localhost ~]# docker-compose -v # 验证docker-compose是否安装成功
docker-compose version 1.26.0, build d4451659

这里还要用到git,如果没有git的还要安装下git才行。

[root@localhost ~]# git --version # 验证是否安装git
git version 1.8.3.1
[root@localhost ~]# yum install -y git # 如果没有安装git,使用这个命令安装git
……
[root@localhost ~]# git clone https://github.com/nacos-group/nacos-docker.git # 下载nacos-docker

很快,nacos-docker下载完成了,主要关注env和example文件夹。env里是一些环境变量,example是运行实例的例子,先把相关的命令列出来,在运行(在nacos-docker文件夹下执行命令)之前,需要查看下*.yaml里到底写的什么,是否需要根据自己的情况做修改呢?

[root@localhost ~]# docker-compose -f example/standalone-derby.yaml up # 使用Derby作为数据源,单机模式启动
[root@localhost ~]# docker-compose -f example/standalone-mysql-5.7.yaml up # 使用mysql-5.7作为数据源,单机模式启动
[root@localhost ~]# docker-compose -f example/standalone-mysql-8.yaml up # 使用mysql-8作为数据源,单机模式启动
[root@localhost ~]# docker-compose -f example/cluster-hostname.yaml up # 使用mysql5.7作为数据源,集群模式启动

这里只说集群模式了(cluster-hostname.yaml),集群模式看懂了,单机就不在话下了。

version: "3"
services:
  nacos1:
    hostname: nacos1
    container_name: nacos1 # 容器名称
    image: nacos/nacos-server:latest # 容器使用的镜像
    volumes:
      - ./cluster-logs/nacos1:/home/nacos/logs
      - ./init.d/custom.properties:/home/nacos/init.d/custom.properties
    ports: # 端口映射
      - "8848:8848"
      - "9555:9555"
    env_file: # nacos环境变量
      - ../env/nacos-hostname.env
    restart: always # 开机自启
    depends_on: # 数据源使用的是mysql
      - mysql
  nacos2:
    hostname: nacos2
    image: nacos/nacos-server:latest
    container_name: nacos2
    volumes:
      - ./cluster-logs/nacos2:/home/nacos/logs
      - ./init.d/custom.properties:/home/nacos/init.d/custom.properties
    ports:
      - "8849:8848"
    env_file:
      - ../env/nacos-hostname.env
    restart: always
    depends_on:
      - mysql
  nacos3:
    hostname: nacos3
    image: nacos/nacos-server:latest
    container_name: nacos3
    volumes:
      - ./cluster-logs/nacos3:/home/nacos/logs
      - ./init.d/custom.properties:/home/nacos/init.d/custom.properties
    ports:
      - "8850:8848"
    env_file:
      - ../env/nacos-hostname.env
    restart: always
    depends_on:
      - mysql
  mysql:
    container_name: mysql
    image: nacos/nacos-mysql:5.7 # 使用的mysql版本号
    env_file:
      - ../env/mysql.env # mysql环境变量
    volumes:
      - ./mysql:/var/lib/mysql
    ports: # 端口映射
      - "3306:3306"

如果虚拟机内存足够大(大于等于4G),那么可以直接运行上面的命令,否则,需要在nacos-hostname.env里添加jvm参数后,再使用上面的命令启动(配置完参数后实测,3台Nacos+1台mysql刚刚跑起来已经2.25G内存了,如果不配参数,4G内存接近吃满)。

#jvm
JVM_XMS=256m
JVM_XMX=256m
JVM_XMN=256m

启动的时候,报了一个错:chown: cannot read directory '/var/lib/mysql/': Permission denied,这是因为CentOS7默认开启了selinux安全模块,使用命令:su -c "setenforce 0"临时关闭selinux模块再启动,等待拉取镜像以及初始化之后,通过浏览器就可以访问了,放一个效果图。

既然Nacos集群搭建好了,下面看一下Nginx的配置。

[root@bogon ~]# docker exec -it festive_booth bash # 进入Nginx容器,festive_booth是docker ps命令中nginx的NAMES字段值
root@e950da524e2a:/# cd /etc/nginx/ # 进入/etc/nginx目录
root@e950da524e2a:/etc/nginx# ls -l # 查看目录下的文件
total 36
drwxr-xr-x. 1 root root   26 Jun  9 16:58 conf.d
-rw-r--r--. 1 root root 1007 Apr 21 12:43 fastcgi_params
-rw-r--r--. 1 root root 2837 Apr 21 12:43 koi-utf
-rw-r--r--. 1 root root 2223 Apr 21 12:43 koi-win
-rw-r--r--. 1 root root 5231 Apr 21 12:43 mime.types
lrwxrwxrwx. 1 root root   22 Apr 21 12:43 modules -> /usr/lib/nginx/modules
-rw-r--r--. 1 root root  643 Apr 21 12:43 nginx.conf
-rw-r--r--. 1 root root  636 Apr 21 12:43 scgi_params
-rw-r--r--. 1 root root  664 Apr 21 12:43 uwsgi_params
-rw-r--r--. 1 root root 3610 Apr 21 12:43 win-utf
root@e950da524e2a:/etc/nginx# cat nginx.conf # 查看nginx.conf的内容

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

nginx.conf就是nginx的主配置文件,注意最后一行有一个include /etc/nginx/conf.d/*.conf;的语句,它的意思是:加载配置文件的时候,把/etc/nginx/conf.d下的*.conf文件包括进来,我们看看/etc/nginx/conf.d下有什么文件,发现另一个default.conf。

root@e950da524e2a:/etc/nginx# cd /etc/nginx/conf.d/
root@e950da524e2a:/etc/nginx/conf.d# ls -l
total 4
-rw-r--r--. 1 root root 1114 Jun  9 16:58 default.conf
root@e950da524e2a:/etc/nginx/conf.d# cat default.conf
server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

当我尝试修改这个配置文件的时候,发现vi和vim命令无法使用,只能采用别的方法:挂载外部配置文件以替代docker容器内的配置文件。

在/usr/下创建一个docker-nginx的文件夹,在里面添加一个nginx.conf配置文件,主要关注点在upstream结点上,内容如下:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    upstream cluster {
        server 192.168.0.123:3333;
        server 192.168.0.123:4444;
        server 192.168.0.123:5555;
    }

    server {
        listen       80;
        listen  [::]:80;
        server_name  localhost;
    
        #charset koi8-r;
        #access_log  /var/log/nginx/host.access.log  main;
    
        location / {
            #root   /usr/share/nginx/html;
            #index  index.html index.htm;
            proxy_pass http://cluster;
        }
    
        #error_page  404              /404.html;
    
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
}

使用docker stop 容器id命令,把之前的容器停掉,docker rm 容器id把之前的容器删除,以挂载外置配置文件方式重新运行一个容器,启动命令:docker run -d -p 80:80 -v /usr/docker-nginx/nginx.conf:/etc/nginx/nginx.conf nginx:stable。

浏览器访问:http://192.168.0.123/nacos,根据Nginx的负载均衡规则, 可以正常访问到某台Nacos,登陆进去即可,一切顺利!

最后一步,我们将cloud-alibaba-provider-payment9002服务注册进Nacos集群。修改application.yml配置文件的server-addr的值,让其指向Nginx。

server:
  port: 9002
spring:
  application:
    name: nacos-payment-provider
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.0.123:80 # 指向Nginx,由Nginx进行转发(nginx下部署了3台Nacos集群)
        # server-addr: 192.168.0.123:8848 # 指明Nacos的地址
management:
  endpoints:
    web:
      exposure:
        include: '*'

Nginx下有3台Nacos部署的集群环境,由Nginx进行转发,启动Payment9002,访问http://192.168.0.123/nacos,查看“服务管理”-“服务列表”,可以看到服务成功注册进来了。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Cloud Alibaba Nacos 是一个服务注册中心和配置中心,可以实现服务注册与发现、配置的动态管理等功能,同时还提供了容灾和高可用的支持。下面简单介绍如何使用 Nacos 实现 Spring Cloud 的配置容灾。 首先,在应用的 `pom.xml` 文件中添加如下依赖: ```xml <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2.2.3.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>2.2.3.RELEASE</version> </dependency> ``` 然后在 `application.properties` 中配置 Nacos 的地址和应用的名称: ```properties spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 spring.cloud.nacos.discovery.namespace=your-namespace spring.cloud.nacos.config.server-addr=127.0.0.1:8848 spring.cloud.nacos.config.namespace=your-namespace spring.cloud.nacos.config.file-extension=properties spring.application.name=your-application-name ``` 其中 `server-addr` 是 Nacos 的地址,`namespace` 是命名空间,`file-extension` 是配置文件的扩展名,`application.name` 是应用的名称。 接着在 `bootstrap.properties` 中配置应用的环境和配置来源: ```properties spring.profiles.active=dev spring.cloud.nacos.config.prefix=${spring.application.name}-${spring.profiles.active} spring.cloud.nacos.config.group=DEFAULT_GROUP spring.cloud.nacos.config.shared-dataids=${spring.application.name}-${spring.profiles.active}.properties ``` 其中 `spring.profiles.active` 是应用的环境,`prefix` 是配置文件的前缀,`group` 是配置文件所在的分组,`shared-dataids` 是配置文件的名称。 最后,在代码中使用 `@Value` 注解来获取配置项的值: ```java @RestController public class ConfigController { @Value("${config.key}") private String configValue; @GetMapping("/config") public String getConfig() { return configValue; } } ``` 其中 `config.key` 是配置项的名称。 以上就是使用 Nacos 实现 Spring Cloud 的配置容灾的简单示例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值