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

1.Nacos简介

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

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

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

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

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坐标。


    com.alibaba.cloud
    spring-cloud-alibaba-dependencies
    2.2.0.RELEASE
    pom
    import

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



    
        cloud2020
        com.atguigu.springcloud
        1.0-SNAPSHOT
    
    4.0.0
    cloudalibaba-provider-payment9001
    
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-starter-actuator
        
        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        
        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    

添加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和其他服务注册中心特性对比
  Nacos Eureka Consul CoreDNS Zookeeper
一致性检查 CP+AP AP CP / CP
健康检查 TCP/HTTP/MySQL/Client Beat Client Beat TCP/HTTP/gRPC/Cmd / Client Beat
负载均衡 权重/DSL/metadata/CMDB Ribbon Fabio RR /
雪崩保护 支持 支持 不支持 不支持 不支持
自动注销实例 支持 支持 不支持 不支持 支持
访问协议 HTTP/DNS/UDP HTTP HTTP/DNS DNS TCP
监听支持 支持 支持 支持 不支持 支持
多数据中心 支持 支持 支持 不支持 不支持
跨注册中心 支持 不支持 支持 不支持 不支持
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坐标。



    
        cloud2020
        com.atguigu.springcloud
        1.0-SNAPSHOT
    
    4.0.0
    cloudalibaba-config-nacos-client3377
    
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-config
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-starter-actuator
        
        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        
        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    

添加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/都可以正常访问了,和刚才相比,向成功迈进了一步。再点击“集群管理”-“结点列表”查看结点,集群搭建成功了!Spring Cloud笔记-Spring Cloud Alibaba Nacos服务注册和配置中心(十八)_第1张图片

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

Spring Cloud笔记-Spring Cloud Alibaba Nacos服务注册和配置中心(十八)_第2张图片

这种方式搭建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模块再启动,等待拉取镜像以及初始化之后,通过浏览器就可以访问了,放一个效果图。

Spring Cloud笔记-Spring Cloud Alibaba Nacos服务注册和配置中心(十八)_第3张图片

既然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,查看“服务管理”-“服务列表”,可以看到服务成功注册进来了。

你可能感兴趣的:(Spring,Cloud)