nacos基本功能初体验

774 阅读5分钟

1 部署

1.1 单节点部署

如果只是想部署一个节点进行测试,则非常简单,只要下载nacos包,也不需要修改任何配置,执行startup.sh脚本即可。如下所示:

% unzip nacos-server-2.2.3.zip
% cd nacos
% ls
LICENSE	NOTICE	bin	conf	target
% ls bin conf target
bin:
shutdown.cmd	shutdown.sh	startup.cmd	startup.sh

conf:
1.4.0-ipv6_support-update.sql	announcement.conf		application.properties		application.properties.example	cluster.conf.example		derby-schema.sql		mysql-schema.sql		nacos-logback.xml

target:
nacos-server.jar

% ./bin/startup.sh -m standalone
nacos is starting with standalone
nacos is starting,you can check the /nacos/logs/start.out

启动日志默认在logs/start.out文件中,从启动日志可知,服务默认监听的端口为8848,以stand alone模式启动,采用的数据库存储为嵌入式内存数据库。standalone模式下,nacos也只能采用嵌入式数据库。

    2023-06-08 15:00:51,383 INFO Tomcat initialized with port(s): 8848 (http)

    2023-06-08 15:00:51,505 INFO Root WebApplicationContext: initialization completed in 2258 ms

    2023-06-08 15:00:56,018 INFO Adding welcome page: class path resource [static/index.html]

    2023-06-08 15:00:56,378 WARN You are asking Spring Security to ignore Ant [pattern='/**']. This is not recommended -- please use permitAll via HttpSecurity#authorizeHttpRequests instead.

    2023-06-08 15:00:56,379 INFO Will not secure Ant [pattern='/**']

    2023-06-08 15:00:56,397 INFO Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@4a9cc6cb, org.springframework.security.web.context.SecurityContextPersistenceFilter@21526f6c, org.springframework.security.web.header.HeaderWriterFilter@cdc3aae, org.springframework.security.web.csrf.CsrfFilter@3f19b8b3, org.springframework.security.web.authentication.logout.LogoutFilter@517bd097, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@299266e2, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@66ea1466, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5990e6c5, org.springframework.security.web.session.SessionManagementFilter@5dcbb60, org.springframework.security.web.access.ExceptionTranslationFilter@a486d78]

    2023-06-08 15:00:56,417 INFO Exposing 1 endpoint(s) beneath base path '/actuator'

    2023-06-08 15:00:56,454 INFO Tomcat started on port(s): 8848 (http) with context path '/nacos'

    2023-06-08 15:00:56,470 INFO Nacos started successfully in stand alone mode. use embedded storage

从启动日志也可知,通过以下地址可以登录nacos web管理页面:

    http://127.0.0.1:8848/nacos

image.png

如果你只想使用nacos的服务注册和发现以及服务管理的功能,可以通过参数指定,如下所示:

% ./bin/startup.sh -m standalone -f naming

或者你只想使用nacos的配置管理的功能,也可以通过参数指定,如下所示:

% ./bin/startup.sh -m standalone -f config

关闭nacos服务:

% ./bin/shutdown.sh
The nacosServer(51598) is running...
Send shutdown request to nacosServer(51598) OK

1.2 集群部署

如果想在生产环境中使用,需采用集群方式部署,集群部署时,一般采用外部数据库。

1.2.1 准备数据库

我这里的外部数据库采用mysql,版本为8.x,如下初始化mysql的数据库和表

mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.33    |
+-----------+
1 row in set (0.00 sec)

mysql> CREATE DATABASE IF NOT EXISTS nacos DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci;
mysql> use nacos;
mysql> source ./conf/mysql-schema.sql;
mysql> show tables;
+----------------------+
| Tables_in_nacos      |
+----------------------+
| config_info          |
| config_info_aggr     |
| config_info_beta     |
| config_info_tag      |
| config_tags_relation |
| group_capacity       |
| his_config_info      |
| permissions          |
| roles                |
| tenant_capacity      |
| tenant_info          |
| users                |
+----------------------+
12 rows in set (0.00 sec)

1.2.2 准备配置文件

由于nacos使用了raft协议来同步集群内节点的数据,所以集群模式时需要三个以上的节点,且节点数最好是单数。我这里在单机启动三个nacos实例来搭建一个三节点测试集群,三个实例的端口号分别为8847、8848、8849。

修改配置文件conf/application.properties内容如下:

    ### Default web context path:
    server.servlet.contextPath=/nacos
    ### Include message field
    server.error.include-message=ALWAYS
    ### Default web server port:
    server.port=8847

    ### Deprecated configuration property, it is recommended to use `spring.sql.init.platform` replaced.
    # spring.datasource.platform=mysql
    spring.sql.init.platform=mysql

    ### Count of DB:
    db.num=1

    ### Connect URL of DB:
    db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&failOverReadOnly=false&allowMultiQueries=true&rewriteBatchedStatements=true
    db.user.0=root
    db.password.0=mysql123@Sys

    ### Connection pool configuration: hikariCP
    db.pool.config.connectionTimeout=30000
    db.pool.config.validationTimeout=10000
    db.pool.config.maximumPoolSize=20
    db.pool.config.minimumIdle=2

这里需要注意的是,配置文件中的spring.datasource.platform=mysqlspring.sql.init.platform=mysql配置默认是注释掉的,需要打开一个,否则启动时会报dataSource or tableName is null错误:

    Caused by: com.alibaba.nacos.api.exception.NacosException: Nacos Server did not start because dumpservice bean construction failure :
    errCode: 102, errMsg: dataSource or tableName is null
            at com.alibaba.nacos.config.server.service.dump.DumpService.dumpOperate(DumpService.java:260)
            at com.alibaba.nacos.config.server.service.dump.ExternalDumpService.init(ExternalDumpService.java:61)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:389)
            at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:333)
            at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:157)
            ... 54 common frames omitted
    Caused by: com.alibaba.nacos.api.exception.runtime.NacosRuntimeException: errCode: 102, errMsg: dataSource or tableName is null
            at com.alibaba.nacos.plugin.datasource.MapperManager.findMapper(MapperManager.java:102)
            at com.alibaba.nacos.config.server.service.repository.extrnal.ExternalConfigInfoPersistServiceImpl.findConfigMaxId(ExternalConfigInfoPersistServiceImpl.java:628)
            at com.alibaba.nacos.config.server.service.dump.processor.DumpAllProcessor.process(DumpAllProcessor.java:51)
            at com.alibaba.nacos.config.server.service.dump.DumpService.dumpConfigInfo(DumpService.java:317)
            at com.alibaba.nacos.config.server.service.dump.DumpService.dumpOperate(DumpService.java:230)
            ... 62 common frames omitted

创建一个集群配置文件conf/cluster.conf,里面指定加入集群的节点列表,内容如下:

    127.0.0.1:8847
    127.0.0.1:8848
    127.0.0.1:8849

1.2.3 启动集群

逐次启动集群所有节点,观察启动日志,如下表示启动成功。

    2023-06-07 17:14:43,622 INFO The server IP list of Nacos is [127.0.0.1:8847, 127.0.0.1:8848, 127.0.0.1:8849, 172.18.186.84:8847]

    2023-06-07 17:14:44,628 INFO Nacos is starting...

    2023-06-07 17:14:53,702 INFO Nacos started successfully in cluster mode. use external storage

2 服务注册、发现与管理

2.1 服务注册

如果是java开发者,在spring boot、spring cloud加持下,服务提供者想向nacos注册自己,只需要添加几项简单配置和注解即可。

pom.xml文件中添加nacos的相关依赖:

    <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <version>2022.0.0.0-RC2</version>
    </dependency>

bootstrap.yml配置文件中添加nacos服务的地址:

spring:
  cloud:
    nacos:
      discovery:
        server-addr: "127.0.0.1:8848"

然后添加注解@EnableDiscoveryClient

@EnableDiscoveryClient
@SpringBootApplication
public class NacosClientProviderApplication {

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

}

启动服务后,就可以在nacos web管理页面看到注册的服务了:

假设服务提供者提供了以下服务,我们后续通过nacos发现服务后调用它:

    @Slf4j
    @RestController
    @RequestMapping("/service")
    public class ServiceController {

        @GetMapping("/hello")
        public String hello() {
            log.info("==============Hello ServiceController");
            return "hello";
        }
    }

2.2 服务发现和调用

服务调用者通过nacos发现服务和调用服务,与服务提供者一样添加相同的依赖和配置即可: pom.xml文件中添加nacos的相关依赖:

    <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <version>2022.0.0.0-RC2</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>

bootstrap.yml配置文件中添加nacos服务的地址:

spring:
  cloud:
    nacos:
      discovery:
        server-addr: "127.0.0.1:8848"

然后添加注解@EnableDiscoveryClient

@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class NacosClientProviderApplication {

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

}

使用openfeign即可调用服务提供者的服务:

@FeignClient(name = "nacos-client-provider", path = "/service")
public interface ServiceFeign {

    @GetMapping("/hello")
    String hello();
}

3 配置管理

跟服务注册和发现类似,pom.xml中添加相应的依赖:

    <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        <version>${nacos.version}</version>
    </dependency>

bootstrap.yml配置文件中添加相应的配置:

spring:
  cloud:
    nacos:
      config:
        server-addr: "127.0.0.1:8848"
        # nacos中维护的配置文件的格式
        file-extension: yml
        import-check:
          # 关闭检查时,即使nacos中没有该服务的任何配置,也能正常启动。
          enabled: false

然后就可以在nacos web配置管理页面添加服务的配置了(服务默认会向nacos获取${服务名}.yml${服务名}-${active-profile}.yml文件的配置),如下新增配置,跟我们编写本地配置文件是一样的。

image.png

服务通过@ConfigurationProperties("app")注解获取nacos的配置,

@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
@ConfigurationProperties("app")
public class NacosConfig {

    private String helloContent;

}

或通过@Value获取nacos的配置(不过通过@Value注解获取配置,如果需要动态更新,还需要在相应类上添加@RefreshScope注解),就获取本地配置一样

@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
@RefreshScope
public class NacosConfig {

    @Value("${app.hello-content}")
    private String helloContent;

}

nacos上的配置发布后,相应服务的配置项的值也立即发生了变化。同理,修改nacos上的配置发布后,相应服务配置项的值也立即更新了。

image.png