博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
nacos作为配置中心兼容xml配置文件
阅读量:4493 次
发布时间:2019-06-08

本文共 12123 字,大约阅读时间需要 40 分钟。

  最近公司想要用配置中心,因为公司用的有传统的spring项目,有springboot项目,为了兼容都能够采用配置中心,做了一些尝试,经过比较还是倾向于使用nacos,传统dubbo采用spring方式读取xml读取配置文件的方式启动,其配置数据源,redis,rabbitmq等采用的是xml的配置,xml中取值是个问题,为了兼容xml能从远程配置中心更好的取值,做了一系列尝试。

  比较当前的一些配置中心

 Nacos的部署结构比较简单,运维成本较低。Apollo部署组件较多,运维成本比Nacos高。Spring Cloud Config生产高可用的成本最高。

Apollo支持Spring Boot和Spring Cloud项目,但是实现方式不同于标准,无法做无缝迁移,从Spring Cloud迁移到Apollo,存在代码改造和兼容性成本。

Nacos通过Spring Cloud for Alibaba支持Spring Boot和Spring Cloud生态,符合Spring生态中的标准实现方式,可以无缝从Spring Cloud Conig迁移到Nacos。
Apollo和Nacos相对于Spring Cloud Config的生态支持更广,在配置管理流程上做的更好。
Apollo相对于Nacos在配置管理做的更加全面,但使用起来也要麻烦一些。
Nacos使用起来相对比较简洁,在对性能要求比较高的大规模场景更适合。此外,Nacos除了提供配置中心的功能,还提供了动态服务发现、服务共享与管理的功能,降低了服务化改造过程中的难度。Nacos目前项目上的人力投入、社区的活跃度等也比较高
整体上来看,Nacos的读写性能最高,Apollo次之,Spring Cloud Config的依赖Git场景不适合开放的大规模自动化运维API

 一、传统的spring加载xml项目启动兼容

典型启动方式是:

1 public static void main(String[] args) throws IOException {2         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(3                 new String[] {"applicationContext.xml"});4         context.start();5         System.out.println("------------");6         System.in.read(); // 为保证服务一直开着, 利用输入流的阻塞来模拟.7     }

这种项目不适合通过注解进行,所以只能采用配置,网上参考的有些坑,主要是jar包冲突的问题,这里放上我修改的jar依赖

com.alibaba.nacos
nacos-spring-context
0.3.0
org.springframework
spring-context

application-nacos.xml

1 
2
6 7 8
9
10
11
12
13
14
15

同时需要将该xml导入到基本的application.xml中

nacos配置中心上添加的配置内容需要什么配置什么即可。

采用注解形式

@Configuration@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "127.0.0.1:8848"))@NacosPropertySource(dataId = "dubbo-config", autoRefreshed = true)public class nacosConfig {}

3、或者在application.xml里面整合好nacos的xml内容(命名空间,开启注解)采用注解

xmlns:nacos="http://nacos.io/schema/nacos" xsi:schemaLocation="http://nacos.io/schema/nacos http://nacos.io/schema/nacos.xsd 同时需要注意
放置的前后位置,不合适会报错,多更换几个位置试试就可以了,xml的加载顺序是从上到下来加载的

二、springboot项目兼容xml,这里有三种方式,可以采用上面的方式,也可以采用官方文档的注解方式,但是发现采用上面的方式配置动态刷新没有成功,而采用注解方式,需要注意的是注入值应该采用@NacosValue(value ="${xxxx}",autoRefreshed = true)方能能够实现自动刷新,而采用@Value("${xxxx}")不能实现自动刷新

第一种,采用同上面的方式

第二种,采用注解方式,jar包采用传统spring整合的jar包,依赖同上,

package com.topband.beings.config;import com.alibaba.nacos.api.annotation.NacosProperties;import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig;import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.ImportResource;@Configuration//@ImportResource({ "classpath:config/applicationContext-nacos.xml" })注:这个是采用xml配置需要添加的,因为不是采用显示加载application.xml启动@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "127.0.0.1:8848"))@NacosPropertySource(dataId = "being-springboot-config", autoRefreshed = true)public class NacosConfig {}

然后在controller注入值时采用是注入值应该采用@NacosValue(value ="${xxxx}",autoRefreshed = true)即可实现实时刷新,并且访问数据库什么的都是正常的

第三种,采用如下jar包,然后完全按照官方文档来即可

com.alibaba.boot
nacos-config-spring-boot-starter
0.2.1
org.springframework
spring-context

application.properties

nacos.config.server-addr=127.0.0.1:8848

启动类上加注解

@SpringBootApplication@NacosPropertySource(dataId = "xxxx你nacos上的dataId", autoRefreshed = true)public class NacosConfigApplication {    public static void main(String[] args) {        SpringApplication.run(NacosConfigApplication.class, args);    }}

同样的,采用@NacosValue(value ="${xxxx}",autoRefreshed = true)方能能够实现自动刷新,而采用@Value("${xxxx}")不能实现自动刷新,并且@NacosValue(value ="${xxxx}")也不能实时刷新,autoRefreshed默认为false

三、springboot直接采用springcloud的jar配置

org.springframework.cloud
spring-cloud-starter-alibaba-nacos-config
0.2.1.RELEASE

采用上述jar包去兼容xml的取值时,报不能加载属性值错误。没有成功,后来发现是application-name写错了,修改过来后,直接可用兼容。

四、一个springboot集成springcloud jar无xml配置的demo

  直接采用完全注解的方式加载,写了一个小demo,采用三中依赖,不用排除上面exclusions中的包,一个独立的demo,集成redis集群,运行ok

1、bootstrap.properties

server.port=8002spring.application.name=xxx-testspring.profiles.active=localspring.cloud.nacos.config.file-extension=propertiesspring.cloud.nacos.config.server-addr=127.0.0.1:8848#spring.cloud.nacos.config.namespace=d6775f80-ed7a-409a-8dbc-49b2cddee4d1

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

${prefix}-${spring.profile.active}.${file-extension}
  • prefix 默认为 spring.application.name 的值,也可以通过配置项 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 类型。

通过 Spring Cloud 原生注解 @RefreshScope 实现配置自动更新:

@RestController@RefreshScopepublic class TestController {    private Logger logger = LoggerFactory.getLogger(this.getClass());    @Autowired    RedisTemplate
template; @Value("${id}") private String id; @GetMapping("/getId") public String getId(){ logger.info("看一看id的变化: {}",id); template.opsForValue().set("hello","world"); String result = template.opsForValue().get("hello"); return "redis result: "+result+"\tid: "+id; }}

Redis属性及配置

1 package com.xx.test.config; 2  3  4 import org.springframework.beans.factory.annotation.Value; 5 import org.springframework.cloud.context.config.annotation.RefreshScope; 6 import org.springframework.stereotype.Component; 7  8 @Component 9 @RefreshScope10 public class RedisProperties {11     @Value("${redis.expireSeconds}")12     private int expireSeconds;13     @Value("${redis.clusterNodes}")14     private String clusterNodes;15     @Value("${redis.commandTimeout}")16     private int commandTimeout;17     @Value("${redis.maxTotal}")18     private int maxTotal;19     @Value("${redis.maxTotal}")20     private int maxIdle;21     @Value("${redis.maxWaitMillis}")22     private int maxWaitMillis;23     @Value("${redis.testOnBorrow}")24     private boolean testOnBorrow;25     @Value("${redis.maxRedirects}")26     private int maxRedirects;27 28     public int getExpireSeconds() {29         return expireSeconds;30     }31 32     public void setExpireSeconds(int expireSeconds) {33         this.expireSeconds = expireSeconds;34     }35 36     public String getClusterNodes() {37         return clusterNodes;38     }39 40     public void setClusterNodes(String clusterNodes) {41         this.clusterNodes = clusterNodes;42     }43 44     public int getCommandTimeout() {45         return commandTimeout;46     }47 48     public void setCommandTimeout(int commandTimeout) {49         this.commandTimeout = commandTimeout;50     }51 52     public int getMaxTotal() {53         return maxTotal;54     }55 56     public void setMaxTotal(int maxTotal) {57         this.maxTotal = maxTotal;58     }59 60     public int getMaxIdle() {61         return maxIdle;62     }63 64     public void setMaxIdle(int maxIdle) {65         this.maxIdle = maxIdle;66     }67 68     public int getMaxWaitMillis() {69         return maxWaitMillis;70     }71 72     public void setMaxWaitMillis(int maxWaitMillis) {73         this.maxWaitMillis = maxWaitMillis;74     }75 76     public boolean isTestOnBorrow() {77         return testOnBorrow;78     }79 80     public void setTestOnBorrow(boolean testOnBorrow) {81         this.testOnBorrow = testOnBorrow;82     }83 84     public int getMaxRedirects() {85         return maxRedirects;86     }87 88     public void setMaxRedirects(int maxRedirects) {89         this.maxRedirects = maxRedirects;90     }91 }

config

1 package com.xxx.test.config; 2  3 import com.xxx.test.common.redis.JRedisClient; 4 import org.springframework.beans.factory.annotation.Autowired; 5 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.Configuration; 7 import org.springframework.data.redis.connection.RedisClusterConfiguration; 8 import org.springframework.data.redis.connection.RedisNode; 9 import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;10 import org.springframework.data.redis.core.RedisTemplate;11 import org.springframework.data.redis.serializer.StringRedisSerializer;12 import redis.clients.jedis.JedisPoolConfig;13 14 import java.util.ArrayList;15 import java.util.List;16 17 @Configuration18 public class RedisConfig {19 20     @Autowired21     private RedisProperties redisProperties;22 23     @Bean24     public RedisClusterConfiguration redisClusterConfiguration(){25         RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();26         redisClusterConfiguration.setMaxRedirects(redisProperties.getMaxRedirects());27 28         List
nodeList = new ArrayList<>();29 30 String[] cNodes = redisProperties.getClusterNodes().split(",");31 //分割出集群节点32 for(String node : cNodes) {33 String[] hp = node.split(":");34 System.out.println("addr: "+hp[0]+"\t ip:"+Integer.parseInt(hp[1]));35 nodeList.add(new RedisNode(hp[0], Integer.parseInt(hp[1])));36 }37 redisClusterConfiguration.setClusterNodes(nodeList);38 return redisClusterConfiguration;39 }40 41 42 @Bean43 public JedisPoolConfig jedisPoolConfig(){44 JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();45 jedisPoolConfig.setMaxIdle(redisProperties.getMaxIdle());46 jedisPoolConfig.setTestOnBorrow(redisProperties.isTestOnBorrow());47 jedisPoolConfig.setMaxTotal(redisProperties.getMaxTotal());48 jedisPoolConfig.setMaxWaitMillis(redisProperties.getMaxWaitMillis());49 return jedisPoolConfig;50 }51 @Bean52 public JedisConnectionFactory getConnectionFactory(){53 return new JedisConnectionFactory(redisClusterConfiguration(),jedisPoolConfig());54 }55 @Bean56 public StringRedisSerializer stringRedisSerializer(){57 return new StringRedisSerializer();58 }59 @Bean60 public RedisTemplate redisTemplate(){61 RedisTemplate redisTemplate = new RedisTemplate();62 redisTemplate.setConnectionFactory(getConnectionFactory());63 redisTemplate.setKeySerializer(stringRedisSerializer());64 redisTemplate.setHashKeySerializer(stringRedisSerializer());65 return redisTemplate;66 }67 @Bean68 public JRedisClient jRedisClient(){69 JRedisClient jRedisClient = new JRedisClient();70 jRedisClient.setRedisTemplate(redisTemplate());71 return jRedisClient;72 }73 74 @Bean75 public RedisTemplate redisTemplate2(){76 RedisTemplate redisTemplate = new RedisTemplate();77 redisTemplate.setConnectionFactory(getConnectionFactory());78 redisTemplate.setKeySerializer(stringRedisSerializer());79 redisTemplate.setHashKeySerializer(stringRedisSerializer());80 redisTemplate.setValueSerializer(stringRedisSerializer());81 return redisTemplate;82 }83 @Bean84 public JRedisClient jRedisClient2(){85 JRedisClient jRedisClient = new JRedisClient();86 jRedisClient.setRedisTemplate(redisTemplate2());87 return jRedisClient;88 }89 90 }

nacos上配置按照约定的dataid进行配置即可。

参考:官方文档

 

@SpringBootApplication @NacosPropertySource(dataId = "example", autoRefreshed = true) public class NacosConfigApplication { public static void main(String[] args) { SpringApplication.run(NacosConfigApplication.class, args); } }

转载于:https://www.cnblogs.com/xiaoyao-001/p/11510337.html

你可能感兴趣的文章
POJ 3041 Asteroids (二分图最小点覆盖)
查看>>
Vue 爬坑之路(四)—— 与 Vuex 的第一次接触
查看>>
MySQL数据迁移到SQL Server
查看>>
Disconf源码分析之启动过程分析下(2)
查看>>
HTML <input> 标签
查看>>
java抽象类实现接口可以不用实现方法
查看>>
poj 2395 Out of Hay (最小生成树的最大边)
查看>>
(原)OSX 也变成svn服务器---3(欢迎大家指出错误。交流提升自己。)
查看>>
2019春第八周作业
查看>>
adt-bundle-windows-x86-20131030
查看>>
APP微信支付集成
查看>>
Socket
查看>>
开发油猴脚本:给任意网页的选中文字涂色
查看>>
实现iframe窗口高度自适应的又一个巧妙思路
查看>>
JQuery常用函数及功能小结
查看>>
jsp隐式对象
查看>>
通用jsp模板
查看>>
bzoj1010 [HNOI2008]玩具装箱toy
查看>>
vue部分问题
查看>>
正则表达式之 数据验证 与 文本替换
查看>>