Spring Cloud融合Nacos实现服务配置中心 | Spring Cloud 7

news2024/12/24 9:41:49

一、服务配置中心

先我们来看一下,微服务架构下关于配置文件的一些问题:

  • 配置文件相对分散。在一个微服务架构下,配置文件会随着微服务的增多变的越来越多,而且分散在各个微服务中,不好统一配置和管理。

  • 配置文件无法区分环境,开发环境、测试环境、线上环境。微服务项目可能会有多个环境,例如:测试环境、预发布环境、生产环境。每一个环境所使用的配置理论上都是不同的,一旦需要修改,就需要我们去各个微服务下手动维护,这比较困难。

  • 配置文件无法实时更新。我们修改了配置文件之后,必须重新启动微服务才能使配置生效,这对一个正在运行的项目来说是非常不友好的。

基于上面这些问题,我们就需要配置中心的加入来解决这些问题。

配置中心的思路是:

  • 首先把项目中各种配置全部都放到一个集中的地方进行统一管理,并提供一套标准的接口。
  • 当各个服务需要获取配置的时候,就来配置中心的接口拉取自己的配置。
  • 当配置中心中的各种参数有更新的时候,也能通知到各个服务实时的过来同步最新的信息,使之动态更新。

二、Nacos配置中心

Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。

使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。

Spring Cloud Alibaba Nacos ConfigConfig ServerClient 的替代方案,客户端和服务器上的概念与 Spring EnvironmentPropertySource 有着一致的抽象,在特殊的 bootstrap 阶段,配置被加载到 Spring 环境中。当应用程序通过部署管道从开发到测试再到生产时,您可以管理这些环境之间的配置,并确保应用程序具有迁移时需要运行的所有内容。

三、准备条件

已完成Nacos服务端部署,本章基于上章实现的Nacos集群为基础,详情请见:nacos 单机集群搭建及常用生产环境配置 | Spring Cloud 3

已完成SpringCloud初始项目的手脚架搭建,详情请见:Spring Cloud入门篇 Hello World | Spring Cloud 1

四、项目搭建

4.1 项目目录结构

在这里插入图片描述

  • 模块nacos-config演示如何使用Nacos Config Starter完成Spring Cloud应用的配置管理

4.2 pom.xml配置

spring cloud alibaba 2021.0.1.0版本后,spring-cloud-starter-alibaba-nacos-config 模块移除了 spring-cloud-starter-bootstrap 依赖,如果你想以旧版的方式使用,你需要手动加上该依赖。

本示例以旧版的方式使用展开,后续补充新版本特性及升级注意事项

本示例版本说明:
<spring-boot.version>2.7.9</spring-boot.version>
<spring-cloud.version>2021.0.5</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.4.0</spring-cloud-alibaba.version>

nacos-config/pom.xml完整配置如下:

<?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>
		<groupId>com.gm</groupId>
		<artifactId>springboot-cloud-example</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<modelVersion>4.0.0</modelVersion>

	<artifactId>nacos-config</artifactId>

	<dependencies>
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
		</dependency>
		<!--在`spring cloud alibaba 2021.0.1.0`版本后,`spring-cloud-starter-alibaba-nacos-config` 模块移除了 `spring-cloud-starter-bootstrap` 依赖-->
		<!--如使用bootstrap.yml配置需添加以下依赖-->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-bootstrap</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	</dependencies>

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

</project>

4.3 配置文件

nacos-config/src/main/resources/bootstrap.yml

server:
  port: 3001

spring:
  profiles:
    active: dev
  application:
    name: @artifactId@
  cloud:
    nacos:
      username: @nacos.username@
      password: @nacos.password@
      config:
        server-addr: 192.168.0.31:8848
        prefix: @artifactId@
        file-extension: yaml

config:
  name: bootstrap

nacos-config/src/main/resources/bootstrap-dev.yml

config:
  name: bootstrap-dev

4.4 常见示例

com/gm/demo/nacos_config/component/ConfigListener.java 监听配置信息的例子

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import javax.annotation.PostConstruct;

import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class ConfigListener {

    /**
     * Nacos group.
     */
    public static final String GROUP = "DEFAULT_GROUP";

    @Autowired
    private NacosConfigManager nacosConfigManager;

    @Value("${spring.cloud.nacos.config.prefix}")
    private String prefix;

    @Value("${spring.cloud.nacos.config.file-extension}")
    private String fileExtension;

    @PostConstruct
    public void init() throws NacosException {

        String dataId = prefix + "." + fileExtension;
        log.error("add listener [dataId]:" + dataId);
        ConfigService configService = nacosConfigManager.getConfigService();

        configService.addListener(dataId, GROUP, new Listener() {
            @Override
            public Executor getExecutor() {
                return Executors.newSingleThreadExecutor();
            }

            @Override
            public void receiveConfigInfo(String content) {
                log.info("[dataId]:[" + dataId + "],Configuration changed to:");
                log.error("\n" + content);
            }
        });
    }
}

com/gm/demo/nacos_config/model/ConfigInfo.java 通过将配置信息配置为bean,支持配置变自动刷新的例子

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "config")
public class ConfigInfo {
    private String name;
}

com/gm/demo/nacos_config/controller/ConfigController.java 对接 nacos 接口通过接口完成对配置信息新增/替换、查询和其他示例补充

一般都是通过@Value的形式读取配置信息,但是无法感知修改后的值,需要利用@RefreshScope动态刷新。

import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import com.gm.demo.nacos_config.model.ConfigInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RefreshScope
@RestController
@RequestMapping("/config")
public class ConfigController {

    @Autowired
    private ConfigInfo configInfo;

    @Value("${config.name:}")
    private String name;

    @Autowired
    private NacosConfigManager nacosConfigManager;

    @Value("${spring.cloud.nacos.config.prefix}")
    private String prefix;

    @Value("${spring.cloud.nacos.config.file-extension}")
    private String fileExtension;

    public static final String GROUP = "DEFAULT_GROUP";

    /**
     * 通过将配置信息配置为bean,支持配置变自动刷新
     *
     * @return
     */
    @RequestMapping("/model")
    public ConfigInfo model() {
        return configInfo;
    }

    /**
     * 通过 @Value 注解进行配置信息获取
     *
     * @return
     */
    @RequestMapping("/value")
    public String value() {
        return name;
    }

    /**
     * 对接 nacos 接口,通过接口完成对配置信息新增/替换单独属性
     *
     * @param name
     * @return
     * @throws NacosException
     */
    @RequestMapping("/publish")
    public boolean publishConfig(
            @RequestParam("name") String name) throws NacosException {
        String dataId = prefix + "." + fileExtension;
        String content = "config:\n" +
                "  name: " + name;
        ConfigService configService = nacosConfigManager.getConfigService();
        return configService.publishConfig(dataId, GROUP, content);
    }

    @RequestMapping("/getConfig")
    public String getConfig()
            throws NacosException {
        String dataId = prefix + "." + fileExtension;
        ConfigService configService = nacosConfigManager.getConfigService();
        return configService.getConfig(dataId, GROUP, 2000);
    }
}

com/gm/demo/nacos_config/NacosConfigApplication.java主方法启动类

支持配置的动态更新,五秒刷新一次

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

import java.util.concurrent.TimeUnit;

/**
 * nacos 配置获取 启动类
 *
 * @author 高明
 */
@SpringBootApplication
public class NacosConfigApplication {

    public static void main(String[] args) throws InterruptedException {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(NacosConfigApplication.class, args);
        while (true) {
            //当动态配置刷新时,会更新到 Enviroment中,因此这里每隔5秒中从Enviroment中获取配置
            String name = applicationContext.getEnvironment().getProperty("config.name");
            System.err.println("=========>>>>>>>>>>名字 :" + name);
            TimeUnit.SECONDS.sleep(5);
        }
    }
}

源码地址:https://gitee.com/gm19900510/springboot-cloud-example

更多详细配置请见官网:https://github.com/alibaba/spring-cloud-alibaba/blob/2021.x/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/readme-zh.md

五、测试

5.1 项目启动

此时nacos无对应配置,获取的输出name为本地profile粒度配置的内容
nacos开启对:
[Nacos Config] Listening config: dataId=nacos-config, group=DEFAULT_GROUP
[Nacos Config] Listening config: dataId=nacos-config.yaml, group=DEFAULT_GROUP
[Nacos Config] Listening config: dataId=nacos-config-dev.yaml, group=DEFAULT_GROUP
此三项的配置监听

在这里插入图片描述

5.2 向nacos中新增配置

浏览器访问:http://127.0.0.1:3001/config/publish?name=nacos

将以下内容,通过上述请求新增至nacos服务端中:

config:
  name: nacos

简单实现可见ConfigController中的publishConfig方法

在这里插入图片描述
此时发现配置监听和动态配置刷新均感知到数据的变化,此时nacos服务端中,存在一条新增的记录

在这里插入图片描述
在这里插入图片描述

5.3 查看@Value刷新

浏览器访问:http://127.0.0.1:3001/config/value
在这里插入图片描述

5.4 查看信息配置为bean刷新

浏览器访问:http://127.0.0.1:3001/config/model
在这里插入图片描述

5.5 新增nacos内profile粒度配置

nacos服务端创建配置nacos-config-dev.yaml
在这里插入图片描述
查看控制台数据变化
在这里插入图片描述

六、下章预告

下章对nacos融合springcloud配置中心高级使用、配置加载优先级、本地配置优先、新特性使用和老版本升级等相关问题进行展开说明。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/386503.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jQuery和ajax案例练习

jQuery和ajax案例练习1.使用jquery修改div元素的背景色(随意颜色)2.使用jquery修改div的子元素p的内容为"我是子元素"3.使用jquery修改第二个p元素的背景色为"orange"4.使用jQuery添加文本的方式将“添加的文本”追加到p标签的后方5.删除列表元素中最后一个…

理解依赖注入(DI – Dependency Injection)

文章目录依赖注入1.provide(提供)1.1 在选项式 API 中&#xff0c;可通过provide选项为后代提供数据1.2 如果想访问到组件的实例this&#xff0c;provide必须采用函数的方式&#xff08;不能用箭头函数&#xff09;&#xff0c;为保证注入方和供给方之间的响应性链接&#xff0…

K8s:开源安全平台 kubescape 实现 Pod 的安全合规检查/镜像漏洞扫描

写在前面 生产环境中的 k8s 集群安全不可忽略&#xff0c;即使是内网环境容器化的应用部署虽然本质上没有变化&#xff0c;始终是机器上的一个进程但是提高了安全问题的处理的复杂性分享一个开源的 k8s 集群安全合规检查/漏洞扫描 工具 kubescape博文内容涉及&#xff1a; kube…

工控机如何安装Python

钡铼技术BL302基于arm架构工控机&#xff0c;采用NXP的高性能处理器I.MX6ULL 运行速度高达800MHz&#xff0c;并配有8GFlash空间和512M RAM&#xff0c;硬件接口有2个网口、2个串口、1个USB口、1个SD卡卡槽、1个HDMI显示接口&#xff0c;可运行LINUX、Ubuntu、Debian等OS&#…

项目管理:如何做到项目信息透明?

项目管理中&#xff0c;管理者最担心的问题是什么&#xff1f;方项目进度不透明&#xff0c;项目的进展不明确&#xff0c;使用项目管理工具让项目进度一目了然。 1、项目管理必须目标明确。 明确的目标能够更好地指导接下来的一系列项目管理工作。 2、项目管理必须资源配置…

Redis缓存一致

背景介绍&#xff1a; redis是一个key-value存储系统。它支持存储的value类型相对更多&#xff0c;包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash&#xff08;哈希类型&#xff09;。这些数据类型都支持push/pop、add/remove及取交集并集和差…

2023 工业互联网平台:智慧制硅厂 Web SCADA 生产线

我国目前是全球最大的工业硅生产国、消费国和贸易国&#xff0c;且未来该产业的主要增量也将来源于我国。绿色低碳发展已成为全球大趋势和国际社会的共识&#xff0c;随着我国“双碳”目标的推进&#xff0c;光伏产业链快速发展&#xff0c;在光伏装机需求的带动下&#xff0c;…

干货分享!PCBA元器件间距的可焊性设计

“ SMT贴片加工逐步往高密度、细间距的设计发展&#xff0c;元器件的最小间距设计需考虑smt厂家的经验程度和工艺是否完善。元器件最小间距的设计除了保证smt焊盘间不易短接的安全间距外&#xff0c;还应考虑元器件的可维护性。 ” 元器件布局为什么要保证安全间距&#xff…

喜讯!华秋电子荣获第六届“高新杯”十大优秀企业奖

2月22日&#xff0c;由中科为集团与广东高科技产业商会联合举办的“第六届‘高新杯’十大优秀高新企业颁奖典礼暨2023年高新企业高质量发展春茗会”&#xff0c;在深圳隆重举行。 中科为集团自2014年举办首届“高新杯”以来&#xff0c;已主办了5届&#xff0c;共计600多家企业…

如何在CSDN上赚钱:CSDN收益渠道分析

文章目录说明哪些人&#xff0c;哪些资源赚到了钱&#xff1f;上传付费资源的策略一些经验说明 在CSDN平台上要想获得回报&#xff0c;主要的渠道&#xff1a; 付费资源付费专栏文章打赏 这三个都有门槛&#xff0c;上传付费资源需要原力等级达到Lv5&#xff0c;粉丝数500&a…

微信怎么发文字朋友圈?简单快捷的方法,只需1分钟

微信是一个非常受欢迎的聊天工具&#xff0c;也是一个交友&#xff0c;分享生活的平台。其中&#xff0c;朋友圈是最受欢迎的功能之一&#xff0c;让我们可以与好友分享自己的生活点滴&#xff0c;也能够关注他人的动态。那么微信怎么发文字朋友圈呢&#xff1f;下面跟着小编一…

tensorflow lite简介-移动设备端机器学习

TensorFlow Lite 是一组工具&#xff0c;可帮助开发者在移动设备、嵌入式设备和 loT 设备上运行模型&#xff0c;以便实现设备端机器学习。 支持多平台 支持多种平台&#xff0c;涵盖 Android 和 iOS 设备、嵌入式 Linux 和微控制器。 原理/流程 工作原理或者使用流程就是上面…

物联网WEB大屏数据可视化

最近了解WEB大屏显示。一般像嵌入式这类的&#xff0c;MQTT协议会走的多一些&#xff0c;走订阅和发布的策略&#xff0c;网上走了一圈之后&#xff0c;目前有几个实现方案。这里对比一下几个物联网协议&#xff0c;相对而言MQTT更合适物联网&#xff0c;其它几个协议不是干这个…

ChatGPT解答:安卓APP耗电量测试方案和源码,用Android代码实现

ChatGPT解答&#xff1a;安卓APP耗电量测试方案和源码&#xff0c;用Android代码实现 安卓APP耗电量测试方案和源码&#xff0c;用Android代码实现 作为一名AI助手&#xff0c;我不会编写代码&#xff0c;但我可以为您提供一些关于安卓APP耗电量测试方案和源码的信息和建议。 …

Web前端:2023年React最佳实践

大多数前端开发人员都希望React JS能成为他们的武器库&#xff0c;来创建独特的、前沿的用户界面。1.重要文件组织服务于相似功能并且被设计为使用某一特征的文件应该被保存在一起。例如&#xff0c;与单个组件相关的所有样式文件和其他文件应该位于同一位置。在这种做法的帮助…

iphone备忘录删除怎么恢复?分享苹果数据找回办法

手机备忘录上写记录&#xff0c;这是不少上班族的小习惯。因为它可以先记录紧急事务&#xff0c;然后再慢慢的解决。也可以把我们一些重要的账号密码存在备忘录里&#xff0c;方便在何时何地直接登入使用。那么如果我们不小心删除了iphone备忘录呢?碰到这种事该怎么办呢?有没…

Vue中二级菜单的实现

在不使用ElementUi等框架的情况下&#xff0c;制作一个二级菜单&#xff0c;网上搜寻很多资料&#xff0c;但部分要不只显示HTML结构&#xff0c;不显示CSS样式&#xff0c;要不就是复杂的让人无法理解。效果图&#xff1a;针对菜单做了CSS样式修饰&#xff0c;给一级二级菜单都…

基于STM32+CS创世 SD NAND(贴片SD卡)完成FATFS文件系统移植与测试(下篇)

四、移植FATFS文件系统 前面第3章&#xff0c;完成了SD NAND的驱动代码编写&#xff0c;这一章节实现FATFS文件的移植。 4.1 FATFS文件系统介绍 &#xff08;1&#xff09;介绍 FatFs 是一种完全免费开源的 FAT 文件系统模块&#xff0c;专门为小型的嵌入式系统而设计。它完…

07--组件

一、小程序组件分类微信团队为开发者提供了一系列基础组件&#xff0c;开发者可以通过组合这些基础组件进行快速开发。小程序中的组件也是非常丰富的&#xff0c;开发者可以基于组件快速搭建出漂亮的页面结构。小程序中的组件其实相当于网页中的HTML标签&#xff0c;只不过标签…

5年测试路,终于爬到了半山腰,结果碰到00后入场,我该拿什么争,我不想35岁被淘汰......

软件测试是一个付出就有回报的工作&#xff0c;可能很多人会说软件测试就是吃青春饭&#xff0c;然而其他工作又何尝不是&#xff1f;没有哪一家公司养尸位素餐之人&#xff0c;大龄员工有被辞退的&#xff0c;也有没被辞退的。干任何职业&#xff0c;抱着一劳永逸的心态&#…