当前位置: 首页 > wzjs >正文

网站开发流行营销型网站大全

网站开发流行,营销型网站大全,wordpress服务器搬迁,建立健全背景 Nacos SpringBoot版本中,提供了NacosValue注解,支持控制台修改值时,自动刷新,但是今天遇见了无法自动刷新的问题。 环境 SpringBoot 2.2.x nacos-client:2.1.0 nacos-config-spring-boot-starter:0…

背景

Nacos SpringBoot版本中,提供了@NacosValue注解,支持控制台修改值时,自动刷新,但是今天遇见了无法自动刷新的问题。

环境

SpringBoot 2.2.x
nacos-client:2.1.0
nacos-config-spring-boot-starter:0.2.12

问题排查

首先确认,nacos的配置信息:

nacos:config:bootstrap:enable: truelog-enable: falseserver-addr: xxxtype: yamlauto-refresh: truedata-ids: my-config.yml

确认auto-refresh配置为true,Nacos提供了注解@NacosConfigListener可以监听配置修改的信息,排查nacos与client的长连接通道是否正常。

@NacosConfigListener(dataId = "${nacos.config.data-ids}", timeout = 5000)
public void onConfigChange(String newConfig) {log.info("Nacos配置更新完成, config data={}", newConfig);
}

在控制台修改配置,发现onConfigChange()可以正常触发,说明长连通道没有问题,看来只能追查源码。

com.alibaba.nacos.client.config.impl.CacheData#safeNotifyListener

private void safeNotifyListener(final String dataId, final String group, final String content, final String type,final String md5, final String encryptedDataKey, final ManagerListenerWrap listenerWrap) {final Listener listener = listenerWrap.listener;if (listenerWrap.inNotifying) {LOGGER.warn("[{}] [notify-currentSkip] dataId={}, group={}, md5={}, listener={}, listener is not finish yet,will try next time.",name, dataId, group, md5, listener);return;}Runnable job = () -> {long start = System.currentTimeMillis();ClassLoader myClassLoader = Thread.currentThread().getContextClassLoader();ClassLoader appClassLoader = listener.getClass().getClassLoader();try {if (listener instanceof AbstractSharedListener) {AbstractSharedListener adapter = (AbstractSharedListener) listener;adapter.fillContext(dataId, group);LOGGER.info("[{}] [notify-context] dataId={}, group={}, md5={}", name, dataId, group, md5);}// Before executing the callback, set the thread classloader to the classloader of// the specific webapp to avoid exceptions or misuses when calling the spi interface in// the callback method (this problem occurs only in multi-application deployment).Thread.currentThread().setContextClassLoader(appClassLoader);ConfigResponse cr = new ConfigResponse();cr.setDataId(dataId);cr.setGroup(group);cr.setContent(content);cr.setEncryptedDataKey(encryptedDataKey);configFilterChainManager.doFilter(null, cr);String contentTmp = cr.getContent();listenerWrap.inNotifying = true;// 重点实现方法,将Nacos Server的配置写入Spring容器中listener.receiveConfigInfo(contentTmp);// compare lastContent and contentif (listener instanceof AbstractConfigChangeListener) {Map data = ConfigChangeHandler.getInstance().parseChangeData(listenerWrap.lastContent, content, type);ConfigChangeEvent event = new ConfigChangeEvent(data);((AbstractConfigChangeListener) listener).receiveConfigChange(event);listenerWrap.lastContent = content;}.....省略部分代码}

进入receiveConfigInfo()实现:
com.alibaba.nacos.spring.context.event.config.DelegatingEventPublishingListener#receiveConfigInfo

@Override
public void receiveConfigInfo(String content) {// 刷新Spring容器配置onReceived(content);// 发布变更事件publishEvent(content);
}

com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor#addListenerIfAutoRefreshed

public static void addListenerIfAutoRefreshed(final NacosPropertySource nacosPropertySource, final Properties properties,final ConfigurableEnvironment environment) {if (!nacosPropertySource.isAutoRefreshed()) { // Disable Auto-Refreshedreturn;}final String dataId = nacosPropertySource.getDataId();final String groupId = nacosPropertySource.getGroupId();final String type = nacosPropertySource.getType();final NacosServiceFactory nacosServiceFactory = getNacosServiceFactoryBean(beanFactory);try {ConfigService configService = nacosServiceFactory.createConfigService(properties);Listener listener = new AbstractListener() {@Overridepublic void receiveConfigInfo(String config) {String name = nacosPropertySource.getName();NacosPropertySource newNacosPropertySource = new NacosPropertySource(dataId, groupId, name, config, type);newNacosPropertySource.copy(nacosPropertySource);MutablePropertySources propertySources = environment.getPropertySources();// replace NacosPropertySource// 核心实现,将Nacos的配置值刷新Spring容器中的配置值propertySources.replace(name, newNacosPropertySource);}};....省略部分代码}

点击replace的实现,发现一点问题:
疑点1
这里面有两个实现,其中一个是jasypt的实现,这个三方类库是常用于对代码中的数据库配置信息进行加密的,难道说,是因为它?同时在控制台也有一条日志值得注意:

[notify-error] dataId=xxx  …… placeholder 'project.version' in value "${project.version}

这里是一个疑点,我们先继续往下看:
com.alibaba.nacos.spring.context.event.config.DelegatingEventPublishingListener#receiveConfigInfo

@Override
public void receiveConfigInfo(String content) {onReceived(content);publishEvent(content);
}private void publishEvent(String content) {NacosConfigReceivedEvent event = new NacosConfigReceivedEvent(configService,dataId, groupId, content, configType);// 发布变更事件applicationEventPublisher.publishEvent(event);
}

org.springframework.context.support.AbstractApplicationContext#publishEvent

/*** Publish the given event to all listeners.* @param event the event to publish (may be an {@link ApplicationEvent}* or a payload object to be turned into a {@link PayloadApplicationEvent})* @param eventType the resolved event type, if known* @since 4.2*/protected void publishEvent(Object event, @Nullable ResolvableType eventType) {Assert.notNull(event, "Event must not be null");// Decorate event as an ApplicationEvent if necessaryApplicationEvent applicationEvent;if (event instanceof ApplicationEvent) {applicationEvent = (ApplicationEvent) event;}else {applicationEvent = new PayloadApplicationEvent<>(this, event);if (eventType == null) {eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();}}// Multicast right now if possible - or lazily once the multicaster is initializedif (this.earlyApplicationEvents != null) {this.earlyApplicationEvents.add(applicationEvent);}else {// 重点关注,发布广播事件,通知全部监听器getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);}// Publish event via parent context as well...if (this.parent != null) {if (this.parent instanceof AbstractApplicationContext) {((AbstractApplicationContext) this.parent).publishEvent(event, eventType);}else {this.parent.publishEvent(event);}}}

下面就是核心的实现部分,真正刷新值的实现逻辑:
com.alibaba.nacos.spring.context.annotation.config.NacosValueAnnotationBeanPostProcessor#onApplicationEvent

@Override
public void onApplicationEvent(NacosConfigReceivedEvent event) {// In to this event receiver, the environment has been updated the// latest configuration information, pull directly from the environment// fix issue #142for (Map.Entry<String, List<NacosValueTarget>> entry : placeholderNacosValueTargetMap.entrySet()) {String key = environment.resolvePlaceholders(entry.getKey());// 从Spring容器中获取变更后的新值,通过反射的方式,更新数据String newValue = environment.getProperty(key);if (newValue == null) {continue;}List<NacosValueTarget> beanPropertyList = entry.getValue();for (NacosValueTarget target : beanPropertyList) {String md5String = MD5Utils.md5Hex(newValue, "UTF-8");boolean isUpdate = !target.lastMD5.equals(md5String);if (isUpdate) {target.updateLastMD5(md5String);Object evaluatedValue = resolveNotifyValue(target.nacosValueExpr, key, newValue);if (target.method == null) {setField(target, evaluatedValue);}else {setMethod(target, evaluatedValue);}}}}
}

OK,看到这里,基本已经明朗,了解了Nacos配置刷新的全流程,非常可疑的一点,就是三方类库jasypt,为了验证才想,我们将jasypt的类库移除,再次进行尝试,奇迹出现了!Nacos可以顺利刷新配置值,终于破案,是因为jasypt的加密导致的该问题,搜了一下可能导致的原因:
1、属性源优先级冲突:jasypt 的 PropertySource(如 EncryptablePropertySource)可能覆盖或干扰 Nacos 的动态属性源,导致解密后的值无法被 Nacos 更新逻辑捕获。
2、解密逻辑未触发:Nacos 配置更新时,新的加密值未被 jasypt 及时解密,导致 Environment 中仍是旧值。

查看一下jasypt使用的版本:

<dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>2.1.1</version>
</dependency>

猜想是否是2.1.1版本的BUG导致了该问题,于是升级至最新版本3.0.5,再次进行测试,发现Nacos可以顺利更新,问题解决。


文章转载自:

http://15Fosmx5.zyytn.cn
http://SUoAnKGV.zyytn.cn
http://m7wu2pEZ.zyytn.cn
http://fFrjI8Jq.zyytn.cn
http://AgIRARyn.zyytn.cn
http://i7S2icxn.zyytn.cn
http://cA3or5DO.zyytn.cn
http://jJZnqFGh.zyytn.cn
http://ZyveTfmm.zyytn.cn
http://4TjCsL4X.zyytn.cn
http://mKeuKqSE.zyytn.cn
http://amACFZZO.zyytn.cn
http://K918ZTrN.zyytn.cn
http://6HvzI0fN.zyytn.cn
http://l7cdvaZH.zyytn.cn
http://eUBboVnU.zyytn.cn
http://AZUeyZff.zyytn.cn
http://cNQvSDcQ.zyytn.cn
http://oWkfJSzE.zyytn.cn
http://U6sPoWX6.zyytn.cn
http://86qbUyHJ.zyytn.cn
http://maxQgZTS.zyytn.cn
http://NPBekEOg.zyytn.cn
http://OHDAjC7i.zyytn.cn
http://hejEaVbh.zyytn.cn
http://AD0BFo2K.zyytn.cn
http://hn44AhE3.zyytn.cn
http://eEqNLAI3.zyytn.cn
http://Bpa569Xd.zyytn.cn
http://cGshzClh.zyytn.cn
http://www.dtcms.com/wzjs/661827.html

相关文章:

  • 用什么做视频网站比较好镇江平面设计
  • 海淘网站是谁做的视频网站开发需求分析
  • 怎么用flash做网站网站建设ppt答辩
  • 云南城市建设职业学院网站网站策划编辑的工作内容
  • 漳州正规网站建设费用繁体企业网站源码
  • 北京网站排名有哪些网站是做数据展示
  • 建设工程质量网站高端的西安网页设计
  • 国外专门做视频翻译网站浙江十大外贸公司排名
  • 外包公司做网站价格重视网站建设
  • 如何利用某个软件做一个网站discuz论坛seo设置
  • 顾问完美一键优化
  • dede 网站图标互联网创业项目零成本
  • 哪几个做内贸的网站比较好一点长沙经开区建设局网站
  • wordpress 站点身份页面设计简洁明快
  • 南充建设公司网站wordpress 二维码插件下载
  • 购物网站设计流程图云南集优科技网站
  • 网站正在建设中末班设计公司网页模板
  • 网站建设公司服务wordpress设置网址错
  • 策划会展网站建设wordpress阿里云邮箱
  • 鱼爪网商城网站如何建设网站建设公司汕头的
  • 全屏产品网站网站开发建设价格附件
  • 网站建设中敬请期待直播平台开发方案
  • 阿里巴巴新网站怎么做运营寄生虫网站排名代做
  • 哪些网站能够免费做公考题关于网站开发的自我评价
  • 顺企网哈尔滨网站建设怎么提高网站的访客量
  • 做vi设计的网站广州网站制作培训
  • 环保主题静态网站模板下载浙江购物网站开发设计
  • 有谁帮做网站的wordpress网站缩
  • 网站建设必备网站改版后 搜索不到
  • 专用车网站建设价格wordpress 反广告插件