Spring Cloud Alibaba+Nacos 2.2.5.Release 的基本使用和采坑问

2022-06-24 18:10:17 浏览数 (1)

◆ 前言

Nacos 是构建以“服务”为中心的现代应用架构的服务基础设施, 支持几乎所有主流类型服务的发现、配置和管理,是目前微服务项目构建的主流服务注册组件。本 Chat 以构建商品中心项目为例,重点在于了解 Nacos 的作用和熟悉 Nacos 的使用。

项目搭建

搭建 Spring Cloud Spring Cloud Alibaba Spring Boot 项目,各组件版本的正确匹配是关键和 pom 文件的书写规范。

项目结构:商品中心。

依赖配置:

代码语言:javascript复制
<?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>org.example</groupId>
    <artifactId>goods-center</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <java.version>1.8</java.version>
        <spring-boot.version>2.4.3</spring-boot.version>
        <spring-cloud.version>2020.0.1</spring-cloud.version>
        <spring-cloud-alibaba.version>2.2.5.RELEASE</spring-cloud-alibaba.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <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>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

controller:

代码语言:javascript复制
package org.example.goodscenter.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author lifeng
 * @date 2021-07-05 08:51
 */
@RestController
public class GoodsController {
    @GetMapping("/goods")
    public String getGoods(){
        return "GoodsCenter";
    }
}

Nacos 作注册中心

添加依赖:

代码语言:javascript复制
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

在 application.yaml 中添加配置:

代码语言:javascript复制
server:
  port: 7001
spring:
  application:
    name: goodsCenter
  cloud:
    nacos:
      discovery:
        server-addr: http://localhost:8848

启动 Nacos 后,访问 http://localhost:8848/nacos/index.html。

启动商品中心,即可在 Nacos 服务列表看到:

Nacos 作配置中心

Nacos 配置文件

添加依赖:

代码语言:javascript复制
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>

添加配置,新增配置文件 bootstrap.yaml。

代码语言:javascript复制
spring:
  application:
    name: goodsCenter
  profiles:
    active: dev #激活开发环境配置
  cloud:
    nacos:
      discovery:
        server-addr: http://localhost:8848
      config:
        server-addr: http://localhost:8848
        file-extension: yaml #指定配置文件的拓展名
        group: DEFAULT_GROUP #指定配置文件所在组

Nacos 配置文件 dataId 的完整格式如下:

代码语言:javascript复制
{prefix}-{spring.profile.active}.{file-extension}

prefix 默认为所属工程配置 spring.application.name 的值(即 goodsCenter),也可以通过配置项 spring.cloud.nacos.config.prefix 来配置。

spring.profile.active 即为当前环境对应的 profile,当 spring.profile.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 {prefix}.{file-extension}。

file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。

controller 层:

代码语言:javascript复制
package org.example.goodscenter.controller;

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

/**
 * @author lifeng
 * @date 2021-07-05 08:51
 */
@RestController
public class GoodsController {
    @GetMapping("/goods")
    public String getGoods(){
        return "GoodsCenter";
    }

    @Value("${test}")
    private String test;

    @RequestMapping("/test")
    public String test() {
        return this.test;
    }

}

启动项目后访问:

默认公共配置文件

在启动文件中可以看到有 2 配置文件,goodsCenter.yaml 和 goodsCenter-dev.yaml,后者是我们指定的,前者是默认的公共配置文件。

创建远程公共配置配置文件:

controller 层添加:

代码语言:javascript复制
    @Value("${testPublic}")
    private String testPublic;

    @RequestMapping("/testPublic")
    public String testPublic() {
        return this.testPublic;
    }

启动项目后测试:

共享配置文件

新建共享配置文件:

配置文件添加:

代码语言:javascript复制
shared-configs: public-config.yaml
refresh-enabled: true

完整配置文件如下:

代码语言:javascript复制
spring:
  application:
    name: goodsCenter
  profiles:
    active: dev #激活开发环境配置
  cloud:
    nacos:
      discovery:
        server-addr: http://localhost:8848
      config:
        server-addr: http://localhost:8848
        file-extension: yaml #指定配置文件的拓展名
        group: DEFAULT_GROUP #指定配置文件所在组
        shared-configs: public-config.yaml
        refresh-enabled: true

controller 层添加:

代码语言:javascript复制
    @Value("${publicConfig}")
    private String publicConfig;

    @RequestMapping("/publicConfig")
    public String publicConfig() {
        return this.publicConfig;
    }

启动项目后测试:

配置的优先级

1. applicant.yaml 和 bootstrap.yaml

重启项目后测试:7001 有效,8001 不生效。

小结:优先级 application.yaml>bootstrap.yaml。

2. goodsCenter-dev.yaml(Nacos 远程指定配置)

重启项目后测试:9001 有效,其他配置中的 server.port 不生效。

小结:优先级 goodsCenter-dev.yaml >application.yaml,Nacos 远程指定配置大于本地。

3. goodsCenter.yaml(Nacos 远程默认公共配置)

重启项目后测试:9001 有效,其他配置中的 server.port 不生效。

小结:优先级 goodsCenter-dev.yaml >goodsCenter.yaml,Nacos 远程指定配置大于公共默认配置。

4. public-config.yaml(共享配置)

重启项目后测试:9001 有效,其他配置中的 server.port 不生效。

小结:优先级 goodsCenter-dev.yaml >public-config.yaml,Nacos 远程指定配置优先级大于共享配置。

小结

  • 优先级最高:goodsCenter-dev.yaml
  • 其他:application.yaml 的优先级高于 bootstrap.yaml

5. 如何使本地配置优先级大于远程指定配置

在远程配置中添加:

代码语言:javascript复制
spring:
  cloud:
    config:
      override-none: true
      allow-override: true
      override-system-properties: false

Spring Cloud Config 本地配置覆盖远程配置的参数解释:

  • allow-override:决定 override-system-properties 是否启用,默认为 true,false=禁用用户的配置。
  • override-system-properties:用来标识外部配置是否能够覆盖系统属性,默认为 true。
  • override-none:当 allow-override 和 override-none 同时为 true,远程配置的优先级降低,不能覆盖其他配置。

重启项目后测试:7001 有效,其他配置中的 server.port 不生效

实现 Nacos 配置自动刷新

在上述操作中,远程配置修改后,需要重启项目才生效,如何实现修改配置后项目会自动刷新。

在启动类和控制层上添加注解 @RefreshScope:

常见错误

1. 无法读取到 bootstarp.yaml 配置:

代码语言:javascript复制
Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'test' in value "${test}"

原因以及解决:spring-cloud-dependencies 较新的版本不再默认加载 bootstrap 文件,如果需要加载 bootstrap 文件需要手动添加依赖。

代码语言:javascript复制
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>

2. Nacos 启动后一直打印 ClientWorker 日志:

代码语言:javascript复制
2021-07-18 21:55:05.007  INFO 15137 --- [ost_8848-public] c.a.n.client.config.impl.ClientWorker    : [fixed-localhost_8848-public] [data-received] dataId=goodsCenter-dev.yaml, group=DEFAULT_GROUP, tenant=public, md5=616c5228b3db5c750f58659592a8bca5, content=test: helloWorld!
server:
    port: 9001
spring:
  cloud:
    config:
      override-none: true
    ..., type=yaml

设置文件中,将 namespace 设置了 public,注释掉即可,其他原因可参考连接:

https://blog.csdn.net/qq_35425070/article/details/108191842

3.

代码语言:javascript复制
java.lang.IllegalArgumentException: Param 'serviceName' is illegal, serviceName is blank

原因:没有设置 application.name。

总结

Nacos 使服务注册与发现更加简单便捷,是 SpringCloudAlibaba 的核心组件之一。实现了微服务项目间的配置共享,随着技术框架核心依赖版本的不断升级,Nacos 在使用上也有需要注意和更新的地方。Nacos 远程配置存在不同类型。本地配置和远程配置的优先级,以及远程共享配置的灵活使用会是的项目配置管理更加高效完善。

来源:

https://www.toutiao.com/article/6991734351201321484/?log_from=43775beb412e3_1654054643038

“IT大咖说”欢迎广大技术人员投稿,投稿邮箱:aliang@itdks.com

来都来了,走啥走,留个言呗~

 IT大咖说  |  关于版权

由“IT大咖说(ID:itdakashuo)”原创的文章,转载时请注明作者、出处及微信公众号。投稿、约稿、转载请加微信:ITDKS10(备注:投稿),茉莉小姐姐会及时与您联系!

感谢您对IT大咖说的热心支持!

  • 相关推荐
  • 推荐文章
  • 为什么Dapr是比SpringCloud和Istio更优雅的微服务框架?
  • ClickHouse原理解析与应用实战
  • 一站式问题定位平台,以agent的方式无侵入接入应用
  • 技术专家带你彻底掌握线程池
  • 基于GF的后台管理系统,完善的权限用户管理,致力于快速高效开发
  • Java 工程师相见恨晚的神兵利器和使用技巧
  • MySQL 故障诊断:MySQL 占用 CPU 过高问题定位及优化
  • 高可用架构之 Sentinel 的降级原理详解
  • .NET 6 从0到1使用Docker部署至Linux环境

0 人点赞