Nacos配置中心组件学习

news2024/9/21 16:42:11

Nacos配置中心组件学习

      • 1. Nacos简介
        • 1.1 Nacos是啥
        • 1.2 作用
      • 2. springCloud项目集成
        • 2.1 maven依赖
        • 2.2 Nacos配置相关参数
        • 2.3 配置信息
        • 2.5 配置使用
        • 2.6 获取实时配置
      • 3. nacos自动装配
        • 3.1 配置加载原理
        • 3.2 配置实时刷新原理
      • 4. nacos配置中心原理
        • 3.1. 动态配置管理
        • 3.2. 配置存储与一致性
      • 3.3. 长轮询与推送机制
        • 3.4. 本地缓存与版本控制
        • 3.5. 安全性与权限管理

1. Nacos简介

1.1 Nacos是啥

​ Nacos(Dynamic Naming and Configuration Service)是一个开源的服务发现和配置管理平台,主要用于微服务架构中。Nacos的名字源自于“Naming and Configuration Service”的缩写,它提供了两大核心功能:服务发现和服务配置。上篇博文Naocos注册中心。下面我们一起来学习有关Nacos另外一个重要特性Nacos配置中心

1.2 作用
  1. 服务发现
    • 允许服务之间相互发现和通信,支持基于DNS和基于RPC的服务发现。
    • 服务提供者在启动时注册自己,服务消费者通过服务名查找服务,实现服务之间的解耦。
  2. 服务配置
    • 动态配置服务是Nacos的另一个重要功能,允许在所有环境中以集中和动态的方式管理所有服务的配置。
    • 配置的更改可以自动推送到使用该配置的服务,实现配置的热更新,无需重启服务。
  3. 集中管理
    • 提供一个中央配置管理服务来统一管理所有服务的配置,避免了配置文件分散在各个项目里导致的不便维护问题。
  4. 动态更新
    • 能够在不重启服务的情况下,动态地更新配置,提高了系统的灵活性和可维护性。
  5. 版本控制&
    • 配置的变更被版本化,以便追踪变更历史和回滚到之前的配置,增强了配置的管理能力。
  6. 权限控制
    • 对配置的访问进行权限控制,确保只有授权的用户可以修改配置,提高了配置的安全性。
  7. 高可用性和故障转移
    • Nacos服务具有高可用性,能够在部分故障的情况下继续工作,并且能够从故障中恢复,保证了系统的稳定运行。
  8. 多环境配置
    • 支持多环境配置,如开发、测试和生产环境,可以实现环境隔离和配置加密,确保配置的正确性和安全性。
  9. 简化服务治理
    • Nacos无缝支持一些主流的开源生态,如Kubernetes Service、gRPC&Dubbo RPC Service、Spring Cloud RESTful Service等,使得服务治理更加容易和高效。

2. springCloud项目集成

前期准备:部署nacos服务,参考:Naocos注册中心

2.1 maven依赖
<dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2.2 Nacos配置相关参数

通常使用bootstrap.propertiesbootstrap.yml文件来配置Nacos的相关参数

spring:
  application:
    name: order-server
   cloud:
    nacos:
      #nacos配置中心配置信息
      config:
        prefix: customer-server
        namespace: nacos-xiu-dev
        server-addr: 127.0.0.0:8848
        file-extension: yml
        # username: name
        # password: pwd!
        
      #nacos服务中心配置  
      discovery:
        server-addr: 127.0.0.0:8848
        namespace: nacos-xiu-dev
        # username: name
        # password: pwd!

在 Nacos Spring Cloud 中,dataId 的完整格式如下:

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

按照上述逻辑我们环境为dev在nacos服务里的文件为 命名空间:nacos-xiu-dev文件名称: customer-server-dev.yml

2.3 配置信息

​ 在nacos服务上添加配置信息如下:

nacos: 
  olympic:
   games:
     pingpangball: 马龙,樊振东,孙颖莎
     dive: 全红婵,陈芋汐
     shoot: 黄雨婷,盛李豪 

在这里插入图片描述

配置项说明使用场景
命名空间(Namespace)用于进行不同环境的配置隔离,如开发环境、测试环境和生产环境等。
不同的命名空间下,可以存在相同名称的配置分组(Group)或配置集(Data ID)。
1.隔离不同环境的配置,防止环境间的配置相互干扰。
2.支持多租户配置隔离,不同租户可以使用相同的Nacos集群,但通过命名空间进行隔离
配置分组(Group)用于对配置集进行分组,不同的配置分组下可以有相同的配置集(Data ID)。根据功能模块或组件进行配置分组,以便于管理。
配置集
(Data ID)
一个配置文件就是一个配置集,包含了系统各个方面的配置信息。配置集通过Data ID来唯一标识。配置文件,最细粒度的配置信息,开发最长接触的
多格式支持Nacos支持多种文件格式的配置项,包括JSON、XML、YAML、Properties、Text等。常用的为 yaml文件、properties文件
2.5 配置使用

在你的Spring Boot应用中,你可以通过@Value注解或@ConfigurationProperties来注入这些配置。

@Value注入配置

  @Value("${nacos.olympic.games.pingpangball}")
  private String pingpangBall;

  @GetMapping("/getOlympicName")
  public String test() {
     log.info("pingpangBall:{}",pingpangBall);
     return "伦敦奥运会";
  }

@ConfigurationProperties注入配置

//注意必须要有set/get方法
@Data
@Component
//设置配置信息前缀
@ConfigurationProperties(prefix = "nacos.olympic.games")
public class OlympicConfig implements Serializable {
    /**
     * 乒乓球
     */
     private String pingpangBall;
    /**
     * 跳水
     */
    private String dive;
    /**
     * 射击
     */
    private String shoot;
}

使用

@Resource
private OlympicConfig olympicConfig;

@GetMapping("/getOlympicName")
public String test() {
   log.info("config:{}", JsonUtil.toJson(olympicConfig));
   return "伦敦奥运会";
}
2.6 获取实时配置
  1. 启用配置刷新

    • application.ymlapplication.properties文件中添加配置,启用Nacos配置的刷新功能。例如,在application.properties中添加spring.cloud.nacos.config.refresh.enabled=true。默认配置刷新已启用
  2. 使用@RefreshScope注解

    • 在需要实时刷新配置的Bean上添加@RefreshScope注解。这个注解会告诉Spring Cloud在配置发生变化时,重新创建这个Bean,并注入最新的配置信息。
    @Data
    @Component
    @ConfigurationProperties(prefix = "nacos.olympic.games")
    //启用实时刷新
    @RefreshScope
    public class OlympicConfig implements Serializable {
        /**
         * 乒乓球
         */
         private String pingpangBall;
        /**
         * 跳水
         */
        private String dive;
        /**
         * 射击
         */
        private String shoot;
    }
    

Nacos实时刷新的原理

Nacos实时刷新的原理主要依赖于客户端与Nacos服务器之间的长轮询机制。当Nacos客户端启动时,它会向Nacos服务器发起请求,订阅自己关心的配置信息。Nacos服务器会保持这个连接,并在配置信息发生变化时,主动将最新的配置信息推送给客户端。客户端在接收到新的配置信息后,会更新本地缓存,并通知应用程序使用最新的配置。

@RefreshScope 注解的工作原理

作用在类上作用在方法上
当@RefreshScope 注解被应用在一个类上时,Spring Cloud会为这个类创建一个代理Bean。这个代理Bean会在每次被调用时检查配置是否已更改。如果配置已更改,则Spring Cloud会重新创建实际的Bean实例,并将其注入到应用程序中。被用在方法上(尽管在实际应用中这种用法并不常见)。然而,需要注意的是,当@RefreshScope 作用在方法上时,它可能并不会像作用在类上时那样直接重新创建Bean实例,而是可能影响到方法调用时的某些行为或结果。但具体的行为可能会根据Spring Cloud的版本和配置而有所不同。

3. nacos自动装配

​ 查看spring-cloud-starter-alibaba-nacos-config maven依赖中的spring.factories中的自动装配类(如下配置类中去掉了重复的配置)

自动装配类创建的bean实例bean实例的作用
NacosConfigBootstrapConfigurationNacosConfigProperties用于封装Nacos配置中心的配置信息,如服务器地址、命名空间、组名等。
加载方式:通过@ConfigurationProperties注解从spring.cloud.nacos.config路径下的配置文件中读取配置项。
NacosConfigManager作为Nacos配置中心的顶层接口ConfigService的封装,提供配置获取、监听等功能。
NacosPropertySourceLocator负责从Nacos配置中心加载配置信息,并将这些配置信息封装成PropertySource对象,进而添加到Spring的Environment中,供应用程序使用
NacosConfigAutoConfigurationNacosRefreshProperties控制Nacos配置中心的配置刷新行为,包括是否启用自动刷新、刷新策略的配置
NacosRefreshHistory它负责记录并存储配置刷新的历史信息。通过提供详细的历史记录查询功能
NacosContextRefreshernacosContextRefresher类在Nacos配置中心中起到了桥梁和纽带的作用,它通过监听配置变化、触发刷新操作以及发布刷新事件等方式,实现了配置的动态更新和应用程序的灵活调整。
NacosConfigEndpointAutoConfigurationNacosConfigEndpointNacosConfigEndpoint类通过提供Actuator端点、配置信息查看、动态刷新支持等功能,为Spring Cloud Alibaba项目中的Nacos配置中心提供了丰富的监控和管理手段
NacosConfigHealthIndicator它主要用于监测Nacos配置中心的健康状态
NacosConnectionFailureAnalyzernacos客户端(应用程序)连接nacos服务端失败信息的分析(日志打印)
3.1 配置加载原理

从上面的配置可以知道,nacos配置中心中配置加载的入口是

  • 应用启动时,Spring Cloud Alibaba通过BootstrapApplicationContext来加载外部配置。在这个过程中,NacosPropertySourceLocator会被触发,从Nacos Server拉取配置
  • NacosPropertySourceLocator通过ConfigServiceProxy与Nacos Server进行通信,获取配置信息,并将这些信息封装成PropertySource对象,然后添加到Spring的Environment中。
  • 接下来我们就可以像在spring中使用普通配置方式一样了。比如@Value注解或@ConfigurationProperties来注入这些配置。

下面我们来看一看NacosPropertySourceLocator具体实现。

locate方法

locate方法是在Spring Cloud Alibaba的Nacos配置管理中使用的,用于将Nacos中的配置加载到Spring环境中

@Override
public PropertySource<?> locate(Environment env) {
  //设置环境变量(方便后续使用不同的环境(profiles)加载配置)
  nacosConfigProperties.setEnvironment(env);
  //基于nacos配置信息 通过nacosConfigManager获取ConfigService实例,这是与Nacos服务器进行交互的关键组件
  ConfigService configService = nacosConfigManager.getConfigService();

  if (null == configService) {
    log.warn("no instance of config service found, can't load config from nacos");
    return null;
  }
  //设置获取配置的超时时间
  long timeout = nacosConfigProperties.getTimeout();
  nacosPropertySourceBuilder = new NacosPropertySourceBuilder(configService,
      timeout);
  
  //获取配置的dataId的前缀 正确地定位到Nacos中的配置。
  //一般为:`prefix` 默认为 `spring.application.name` 的值,也可以通过配置项 `spring.cloud.nacos.config.prefix`来配置
  String name = nacosConfigProperties.getName();
  String dataIdPrefix = nacosConfigProperties.getPrefix();
  if (StringUtils.isEmpty(dataIdPrefix)) {
    dataIdPrefix = name;
  }

  if (StringUtils.isEmpty(dataIdPrefix)) {
    dataIdPrefix = env.getProperty("spring.application.name");
  }

  //创建CompositePropertySource 这个对象将用于存储从Nacos加载的所有配置属性源。
  CompositePropertySource composite = new CompositePropertySource(
      NACOS_PROPERTY_SOURCE_NAME);

  //加载共享配置 其配置信息跨多个应用或服务的通用配置。
  //spring.cloud.nacos.config.shared-configs 指定
  loadSharedConfiguration(composite);
  //加载扩展配置 其配置信息包含一些特定于某个服务或功能的配置
  loadExtConfiguration(composite);
  //加载应用配置 常见的配置信息
  loadApplicationConfiguration(composite, dataIdPrefix, nacosConfigProperties, env);
  //返回加载完成后的配置对象
  return composite;
}

共享配置、扩展配置

在这里插入图片描述

加载配置信息

其实不管是loadSharedConfiguration、loadExtConfiguration、loadApplicationConfiguration最终都是调用loadNacosDataIfPresent方法加载配置。这里我们以最常见的设置配置的方式loadApplicationConfiguration方法进行分析。

//加载常用配置
private void loadApplicationConfiguration(
       CompositePropertySource compositePropertySource, String dataIdPrefix,
       NacosConfigProperties properties, Environment environment) {
    //获取配置文件的文件类型 比如yaml、properties等 用于读取到数据的格式化
    String fileExtension = properties.getFileExtension();
    //获取配置分组
    String nacosGroup = properties.getGroup();
  
    //加载默认配置文件 dataId= dataIdPrefix
    
    loadNacosDataIfPresent(compositePropertySource, dataIdPrefix, nacosGroup,
          fileExtension, true);
    // load with suffix, which have a higher priority than the default
    //加载默认配置文件 dataId= dataIdPrefix
    loadNacosDataIfPresent(compositePropertySource,
          dataIdPrefix + DOT + fileExtension, nacosGroup, fileExtension, true);
    // Loaded with profile, which have a higher priority than the suffix
    for (String profile : environment.getActiveProfiles()) {
       String dataId = dataIdPrefix + SEP1 + profile + DOT + fileExtension;
       loadNacosDataIfPresent(compositePropertySource, dataId, nacosGroup,
             fileExtension, true);
    }

dataIdPrefix: 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。

以上述的示例代码为例子:spring.application.name=customer-server,profiles=dev

上述代码加载三种类型的配置信息(dataId) customer-server、customer-server.yaml、customer-server-dev.yaml,配置优先级从高到低

为customer-server-dev.yaml —> customer-server.yaml —> customer-server.

具体加载实现

1. loadNacosDataIfPresent方法核心实现
 //加载配置为NacosPropertySource(包含配置信息)
 NacosPropertySource propertySource = this.loadNacosPropertySource(dataId, group,
      fileExtension, isRefreshable);
 //放入composite的配置列表的头部 这表明后加载的配置文件优先级更高
 this.addFirstPropertySource(composite, propertySource, false);

2.loadNacosPropertySource方法核心实现
	NacosPropertySource build(String dataId, String group, String fileExtension,
			boolean isRefreshable) {
    //从nacos服务端加载配置
		Map<String, Object> p = loadNacosData(dataId, group, fileExtension);
    //将配置构造成NacosPropertySource
		NacosPropertySource nacosPropertySource = new NacosPropertySource(group, dataId,
				p, new Date(), isRefreshable);
    //存储到map中
		NacosPropertySourceRepository.collectNacosPropertySource(nacosPropertySource);
		return nacosPropertySource;
	}

3. loadNacosData核心实现
  private Map<String, Object> loadNacosData(String dataId, String group,String fileExtension) {
		String data = null;
		try {
      //从nacos服务端获取配置信息(字符串形式)
			data = configService.getConfig(dataId, group, timeout);
		  //省略日志打印
      //根据配置文件类型将字符串类型的配置信息转换成map
			Map<String, Object> dataMap = NacosDataParserHandler.getInstance()
					.parseNacosData(data, fileExtension);
			return dataMap == null ? EMPTY_MAP : dataMap;
		}
		catch (NacosException e) {
		   //省略异常处理
		}
		return EMPTY_MAP;
	}

3.2 配置实时刷新原理

Nacos 服务器端负责存储配置数据,并提供配置监听和推送的功能。该功能是nacos实时刷新得以实现的基础。

  • 长轮询支持:Nacos 服务器端支持客户端的长轮询请求,即客户端发起一个请求后,服务器会保持这个连接打开,直到有配置更新或超时。这种方式可以减少无效的轮询请求,提高性能。
  • 数据变更通知:当配置数据发生变化时,Nacos 服务器端会记录这些变化,并通知所有正在等待的客户端。这通常通过维护一个客户端连接列表,并在数据变化时遍历这个列表来实现。
  • nacos与spring cloud整合,nacos基于spring的事件发布和监听机制,会在spring启动后注册一个配置变化的事件监听。其启作用的为NacosContextRefresher

NacosContextRefresher

spring启动时候注册配置变更事件

@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
    // many Spring context
    if (this.ready.compareAndSet(false, true)) {
       //注册nacos配置变更事件
       this.registerNacosListenersForApplications();
    }
}
private void registerNacosListenersForApplications() {
    //是否开启自动刷新 默认为true
    if (isRefreshEnabled()) {
       //针对需要加载的所有配置文件都分别进行事件监听
       for (NacosPropertySource propertySource : NacosPropertySourceRepository
             .getAll()) {
          if (!propertySource.isRefreshable()) {
             continue;
          }
          //以上面示例代码为例 分别对customer-server、customer-server.yaml、customer-server-dev.yaml、
          String dataId = propertySource.getDataId();
          //添加事件监听
          registerNacosListener(propertySource.getGroup(), dataId);
       }
    }
}
private void registerNacosListener(final String groupKey, final String dataKey) {
    String key = NacosPropertySourceRepository.getMapKey(dataKey, groupKey);
  
    //创建监听配置变化的监听器,其方法innerReceive即为配置变更处发的逻辑
    Listener listener = listenerMap.computeIfAbsent(key,
          lst -> new AbstractSharedListener() {
             @Override
             public void innerReceive(String dataId, String group,
                   String configInfo) {
                refreshCountIncrement();
                nacosRefreshHistory.addRefreshRecord(dataId, group, configInfo);
                // todo feature: support single refresh for listening
                applicationContext.publishEvent(
                      new RefreshEvent(this, null, "Refresh Nacos config"));
                if (log.isDebugEnabled()) {
                   log.debug(String.format(
                         "Refresh Nacos config group=%s,dataId=%s,configInfo=%s",
                         group, dataId, configInfo));
                }
             }
          });
    try {
       //为nacos服务添加事件监听器
       configService.addListener(dataKey, groupKey, listener);
    }
    catch (NacosException e) {
       log.warn(String.format(
             "register fail for nacos listener ,dataId=[%s],group=[%s]", dataKey,
             groupKey), e);
    }
}

这段代码展示了如何在Spring Cloud Alibaba的Nacos配置中心中注册一个监听器,以便在配置发生变化时能够接收到通知并执行相应的更新逻辑

  • 构建配置变更事件监听器
  • 为nacos服务添加事件监听器

innerReceive方法

该方法三个参数, 当某个分组group下的某个配置dataId发生变化则会将最新的配置信息configInfo传递到该方法中

  public void innerReceive(String dataId, String group,
                   String configInfo) {
      //累加配置变更次数
      refreshCountIncrement();
      //记录此次变化到历史中,便于追溯历史变更记录
      nacosRefreshHistory.addRefreshRecord(dataId, group, configInfo);
      //发布一个刷新事件,接受到该事件的组件即可获取到最新配置 
      //比如@RefreshScope底层逻辑肯定是消费了该RefreshEvent事件 从而获取到最新变化配置
      applicationContext.publishEvent(
            new RefreshEvent(this, null, "Refresh Nacos config"));
      if (log.isDebugEnabled()) {
         log.debug(String.format(
               "Refresh Nacos config group=%s,dataId=%s,configInfo=%s",
               group, dataId, configInfo));
      }
   }

4. nacos配置中心原理

Nacos配置中心的工作原理主要围绕动态配置管理、配置存储与一致性、长轮询与推送机制以及本地缓存与版本控制等核心原理展开。以下是详细的工作原理介绍:

3.1. 动态配置管理
  • 功能概述:Nacos配置中心提供了一种集中式的动态配置管理功能,允许开发者实现配置的集中管理、动态更新和实时推送。这意味着当配置信息发生变化时,Nacos能够自动将更新推送给所有相关的服务实例,无需重启服务即可使新配置生效。
  • 技术实现:Nacos通过集中存储配置信息(如使用MySQL等数据库)来确保配置数据的安全性和持久性。同时,它支持多种配置格式(如Properties、YAML等),以满足不同应用场景下的配置需求。
3.2. 配置存储与一致性
  • 配置存储:Nacos采用集中式的存储方式,将配置信息存储在可靠的存储介质中。这种集中存储方式使得配置信息的管理更加便捷和统一。
  • 一致性保证:在集群部署模式下,Nacos通过一致性协议(如Raft协议)来保证配置数据在不同节点之间的一致性。即使在部分节点发生故障的情况下,也能保证配置数据的完整性和准确性。

3.3. 长轮询与推送机制

  • 长轮询机制:Nacos客户端通过长轮询机制与服务器保持连接,以实时获取配置更新。当配置发生变化时,服务器会主动将更新推送给客户端,而不是让客户端定时轮询查询。这种推送机制大大减少了客户端与服务器之间的通信次数,提高了配置更新的实时性和效率。
  • 推送机制:推送可以通过HTTP长轮询或WebSocket等方式实现。使用WebSocket可以更加实时地推送配置变更,但需要确保网络环境支持WebSocket。
3.4. 本地缓存与版本控制
  • 本地缓存:为了提高性能并减少对服务器的访问压力,Nacos客户端会将获取到的配置信息缓存在本地。当本地缓存中的配置信息与服务器上的配置信息不一致时,客户端会重新从服务器拉取最新的配置信息。
  • 版本控制:Nacos为每个配置项分配一个唯一的版本号。当配置发生变化时,版本号也会随之更新。客户端在发起请求时可以携带自己的配置版本号,以便服务器判断是否需要推送新的配置信息给客户端。
3.5. 安全性与权限管理
  • 安全性:Nacos提供了多种安全措施来保护配置信息的安全性,如数据加密、访问控制等。
  • 权限管理:Nacos实现了权限管理功能,允许管理员在控制台创建不同的账户,并分配不同的权限(如读写、只读)。这样可以确保只有具有相应权限的用户才能访问或修改配置信息。

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

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

相关文章

这家AGV机器人龙头高歌猛进,半年营收27亿,国内对手们慌了吗?

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 机器人业务高歌猛进&#xff0c;海康威视创新引擎全速运转 海康威视于近日揭晓了其2024年上半年的辉煌成绩单。这份报告不仅彰显了公司整体业务的稳健增长&#xff0c;更引人注目的是…

Mybatis 一文速通 节约学习或复习成本

目录 1、简介 1.1、什么是Mybatis 1.2、持久化 1.3持久层 1.4为什么需要Mybatis&#xff1f; 2、第一个Mybatis程序 2.1、搭建环境 2.2、创建一个模块 2.3、编写代码 2.4、测试 3、CRUD 1、namespace 2、select 3、insert 4、update 5、delete 6、常见错误分析…

Linux进程间通信学习记录(IPC 机制、共享内存以及信号灯集)

0.System V IPC机制&#xff1a; ①.IPC对象包含&#xff1a;共享内存、消息队列和信号灯集。 ②.每个IPC对象有唯一的ID。 ③.IPC对象创建后一直存在&#xff0c;直到被显示地删除。 ④.每一个IPC对象有一个关联的KEY。&#xff08;其他进程通过KEY访问对应的IPC对象&#xff…

SpringCloud远程调用为啥要采用HTTP,而不是RPC?

关于SpringCloud远程调用采用HTTP而非RPC。 1. 首先SpringCloud开启Web服务依赖于内部封装的Tomcat容器&#xff0c;而今信息飞速发展&#xff0c;适应大流量的微服务&#xff0c;采用Tomcat处理HTTP请求&#xff0c;开发者编写Json作为资源传输&#xff0c;服务器做出相应的响…

Flutter【01】状态管理

声明式编程 Flutter 应用是 声明式 的&#xff0c;这也就意味着 Flutter 构建的用户界面就是应用的当前状态。 当你的 Flutter 应用的状态发生改变时&#xff08;例如&#xff0c;用户在设置界面中点击了一个开关选项&#xff09;你改变了状态&#xff0c;这将会触发用户界面…

flume--数据从kafka到hdfs发生错误

解决&#xff1a; #1.将flume自带的依赖删除 mv /opt/installs/flume1.9/lib/guava-11.0.2.jar /opt/installs/flume1.9/lib/guava-11.0.2.jar.bak #2.将hadoop的依赖发送到flume下 cp /opt/installs/hadoop3.1.4/share/hadoop/common/lib/guava-27.0-jre.jar /opt/installs/f…

招商期货:以超融合支撑期货重要业务,承载80%信创系统

招商期货有限公司&#xff08;以下简称“招商期货”&#xff09;成立于 1993 年&#xff0c;是招商证券股份有限公司的全资子公司&#xff0c;注册资本 35.98 亿元&#xff0c;是中国首批券商全资控股期货公司。 随着数字化进程快速推进、交易模式不断创新&#xff0c;系统建设…

Axure设计之三级菜单导航教程(中继器)

中继器作为复杂的元件&#xff0c;通常被用来制作“高保真”的动态原型&#xff0c;以达到良好的视觉效果和交互效果。本文将教大家通过AxureRP9工具如何使用中继器设计三级菜单导航。 一、案例效果 原型预览&#xff1a;https://1zvcwx.axshare.com 主要效果&#xff1a; 1…

异步交互技术Ajax-Axios

目录 一、同步交互和异步交互 二、Ajax 1.概述 2.如何实现ajax请求 三、异步传输数据乱码的问题 regist.html页面代码 服务端代码处理 四、Axios 1. Axios的基本使用 &#xff08;1&#xff09;引入Axios文件 &#xff08;2&#xff09;使用Axios发送请求&#xff0…

Chapter 42 递归

欢迎大家订阅【Python从入门到精通】专栏&#xff0c;一起探索Python的无限可能&#xff01; 文章目录 前言一、基本概述二、案例分析 前言 递归是一种在编程中广泛使用的技术&#xff0c;通过让函数调用自身来逐步解决问题。本章详细讲解了 Python 中递归的基本原理以及应用场…

SSRF服务器请求伪造

目录 SSRF服务器请求伪造 一、SSRF漏洞概述 二、SSRF常见的函数 1、file_get_contents() 2、fsockopen() 3、exec()发送GET请求 4、exec()发送POST请求 三、SSRF主要危害 1、先准备以下脚本 2、读取文件和信息 3、内网扫描 4、获取指纹信息 四、SSRF漏洞挖掘技巧 …

Nginx---Web服务器

简介 介绍nginx中Web服务器的相关配置 环境配置 mkdir /data/web/html -p mkdir /data/web/html/test{1..5} echo test1 > /data/web/html/test1/index.html echo test2 > /data/web/html/test2/index.html echo test3 > /data/web/html/test3/index.html echo tes…

FPGA时序约束

目录 一、概述二、时序分析基本概念时钟抖动时钟偏差时钟不确定性Clock Uncertainty同步电路和异步电路建立时间和保持时间发起沿和采样沿关键路径 三、时序分析的基本公式时序分析的基本路径数据到达时间和时钟到达时间建立时间的裕量&#xff08;Setup slack&#xff09;保持…

STM32CubeMX 配置串口通信 HAL库

一、STM32CubeMX 配置串口 每个外设生成独立的 ’.c/.h’ 文件 不勾&#xff1a;所有初始化代码都生成在 main.c 勾选&#xff1a;初始化代码生成在对应的外设文件。 如 GPIO 初始化代码生成在 gpio.c 中。 二、重写fputc函数 ​ #include <stdio.h>#ifdef __GNUC__#def…

“LOCAL_LISTENER”参数导致业务无法连接数据库,文末附Oracle连接故障检查监听的排查流程

1. 背景及问题 今天在Oracle BCV技术[1]做数据同步&#xff0c;建立生产库的测试库&#xff0c;需要DBA配合同步前后的停库和起库。在同步完起库后&#xff0c;有部门反应同步好的测试库连接不上去。 2. 问题排查 以我当前的知识储备&#xff0c;能想到的可能就是以下几点进…

【NLP】注意力机制:规则、作用、原理、实现方式

文章目录 1、本章目标2、注意力机制介绍2.1、注意力概念2.2、注意力机制2.3、翻译举例 3、注意力计算规则3.1、打个比喻3.2、公式3.2.1、线性变换 点积注意力3.2.2、加性注意力3.2.3、点积注意力3.2.4、对比与总结3.2.5、bmm运算 4、注意力机制的作用5、注意力机制原理⭐5.1、…

基于java的美食信息推荐系统的设计与实现论文

摘 要 使用旧方法对美食信息推荐系统的信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在美食信息推荐系统的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。这次开发的美…

Linux系统-vi/vim编辑器权限管理文档处理三剑客

1.vi/vim文本编辑器 vim是vi的增强版&#xff0c;vi是系统自带的。以下命令在vi/vim中通用&#xff1a; 刚打开的默认模式 快捷键&#xff1a;gg 跳到文件开头&#xff0c;G 跳到文件最后一行。 快捷键&#xff1a;0 跳到行首&#xff0c;$ 跳到行尾。 快捷键&#xff1a;…

C++ | Leetcode C++题解之第355题设计推特

题目&#xff1a; 题解&#xff1a; class Twitter {struct Node {// 哈希表存储关注人的 Idunordered_set<int> followee;// 用链表存储 tweetIdlist<int> tweet;};// getNewsFeed 检索的推文的上限以及 tweetId 的时间戳int recentMax, time;// tweetId 对应发送…

vue3--定时任务cron表达式组件比较

## 背景&#xff1a; 之前使用vue2开发项目时&#xff0c;使用了cron组件&#xff0c;比较了两种组件的使用效果。现在需要把原有的vue2项目升级为vue3&#xff0c;需要对应的cron组件。 方案一&#xff0c;vue3-cron-plus 具体实现&#xff1a; 安装插件 npm install vue3-…