SpringBoot使用Nacos作为配置中心 例子和总结

前言

学习笔记汇总地址:
https://blog.csdn.net/lwb314/article/details/108277732
我发现我写的博客屁话有点多,不爱看的可以跳过前言。
搭建好Nacos服务器之后,开始学习Nacos的第一个主要功能:配置中心
配置中心的作用就是替代项目的配置文件。这个时候就产生了几个问题:
1.为什么要替换配置文件,我觉得所有技术都是为了解决实际工作中产生的痛点才产生的,那么配置中心解决的痛点是什么呢,我觉得主要就是微服务部署的点多了之后修改配置不方便的问题,这是最根本的问题,如果一个服务的点很多,这个时候需要改其中一个配置项目,那么传统配置文件,只能去服务器上一个一个修改,我现在的所有程序是2个点主备,还没什么感觉,但是我能接受的极限就是2个点,如果出来3个点,我就会觉得一个一个修改特别麻烦,这个时候配置中心就特别有用了,我只需要在配置中心修改就能达到我的目的。
2.有人可能会说我用Docker+K8S这种CI/CD技术也可以解决只修改一次全部生效的效果。我暂时对这2个技术还不熟悉,但是又一点我觉得这2个好像做不了,据我的了解这2个东西是帮助你发版的,但是配置中心可以实时生效,也可以理解成热部署,比如你需要修改一个功能的开关,直接修改配置中心就可以马上生效,而不需要发版才能生效。
3.我本身觉得配置是分几个级别的,有一些配置说实话,我觉得动了会出问题,下边我会做好几个实验,按照我认为的配置级别挨个实验。

环境

开发工具:IDEA,虽然我个人主要还是爱用eclipse,但是IDEA集成的一些插件确实是挺方便的。
JDK:1.8
Nacos:1.3.2
Spring版本:这个重点说一下,我最一开始汇总那个帖子已经说了,我们这里使用的是Spring Cloud Alibaba,但是有人可能会在找依赖的时候出现错误,因为这东西版本好多,我之前对3种技术都写了例子,例子入口:Spring Boot/Cloud+Nacos+Dubbo 整合例子
3个例子,都使用了Spring Boot+Nacos+Dubbo,应该说都跟阿里的微服务沾边了,但是我个人认为还是例子3算是纯粹的Spring Cloud Alibaba,所以我们这次主要学习的就是这个技术。
那么为什么我觉得这个才是最纯粹的呢?看图说话,因为Spring Cloud alibaba在git上就有一个基于Spring 规范的技术实现spring cloud alibaba starters,里边就是阿里技术栈的全部东西了,我接下来的学习就是准备把这下边的技术全部自学一遍,然后写成帖子,当然,主要是看时间和热情度什么时候没有。我最近的热情在于学习Unity3D做游戏,呵呵,感觉当年毕业不应该学Java的。
在这里插入图片描述

快速开始

这就是为什么我写这个例子用IDEA的原因。
第一步,创建项目,这个时候有一个非常方便的方式,IDEA里带了一个Spring Initializr,这个是快速开发Spring Cloud的一个很好用的工具,Spring 官网自带一个就是这个插件默认的那个地址,打开就是下边第2个图这样的,不过这里不能用Spring 原生的那个地址,需要用阿里云的地址,因为阿里云这套技术在Spring 原生的那个地址里是搜不到的,下边会上图。
在这里插入图片描述
在这里插入图片描述

第一个例子里,我们只用nacos config,所以只引入下图里的2个依赖,在左边搜索关键字就可以找到这2个依赖,Spring 官方的Initializr是也可以搜到nacos,但是后续的dubbo就不行了,所以我一直用阿里云的地址:http://start.aliyun.com,我的版本是2.3.0
在这里插入图片描述
配置中心启动完成后,会在你对应的dataId和group里生成一个对应的监听,但是我没找到怎么使用这个监听,如图
在这里插入图片描述

代码

依赖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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.lwb</groupId>
    <artifactId>provider-server-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>provider-server-demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.0.RELEASE</spring-boot.version>
        <spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <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>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.0.RELEASE</version>
                <configuration>
                    <mainClass>com.lwb.provider.server.demo.ProviderServerDemoApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

启动函数

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import javax.annotation.PostConstruct;

/**
 * @author xiaojing, Jianwei Mao
 */

@SpringBootApplication
public class ProviderServerDemoApplication {

    @Value("${server.port:1}")
    int port;

    @PostConstruct
    public void init() {
        System.out.println(port);
    }

    public static void main(String[] args) {
        SpringApplication.run(ProviderServerDemoApplication.class, args);
    }


}

bootstrap.properties配置

我的项目也有application.properties,只是里边什么也没写,这里还遇到了一个小坑

spring.application.name=nacos-config-demo
spring.cloud.nacos.config.server-addr=10.10.171.249:8848
spring.cloud.nacos.config.namespace=lwb_public

执行效果

可以看到,我替换的是spring boot web启动的tomcat接口,对应属性是server.port,已经修改成功,使用的是Nacos配置中心下的lwb_public命名空间(不是默认的public),dataId是nacos-config-demo.properties

2020-08-31 14:20:17.407  INFO 130008 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8003 (http)
2020-08-31 14:20:17.414  INFO 130008 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-08-31 14:20:17.415  INFO 130008 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.35]
2020-08-31 14:20:17.533  INFO 130008 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-08-31 14:20:17.533  INFO 130008 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1125 ms
2020-08-31 14:20:17.614  WARN 130008 --- [           main] o.s.boot.actuate.endpoint.EndpointId     : Endpoint ID 'nacos-config' contains invalid characters, please migrate to a valid format.
8003
2020-08-31 14:20:17.758  INFO 130008 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'

规则说明

命名空间:

注意我的命名空间的ID和名字不一样,名字可以改ID是不能改的,而spring.cloud.nacos.config.namespace=lwb_namespace_test_1属性用的是ID,而不是名字
在这里插入图片描述

dataId:

我这里用了一个最简单的配置,dataId取名nacos-config-demo.properties,可以理解成这个就是你原来的配置文件名字,这样就好理解多了.
nacos的dataId和Spring Config的规则好像是一样的,具体如下:
p r e f i x − {prefix}- prefix{spring.profiles.active}.${file-extension}
prefix默认为 spring.application.name的值,也可以通过配置项spring.cloud.nacos.config.prefix来配置。
spring.profiles.active 即为当前环境对应的profile,但是,不建议使用,原因在后面会说明。
注意,当activeprofile为空时,对应的连接符-也将不存在,dataId 的拼接格式变成 p r e f i x . {prefix}. prefix.{file-extension}
file-extension为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension来配置。
在这里插入图片描述

bootstrap.properties

这里我要说的是,因为我的应用要使用nacos作为配置,所以nacos的地址肯定在应用初始化之前就得拿到,所以必须写在bootstrap配置文件里,而不能写在applicaton里
Spring Cloud 构建于 Spring Boot 之上,在 Spring Boot 中有两种上下文,一种是 bootstrap,另外一种是 application,
application 配置文件这个容易理解,主要用于 Spring Boot 项目的自动化配置。
bootstrap 是应用程序的父上下文,也就是说 bootstrap 加载优先于 applicaton。

遇坑总结

@EnableNacosConfig

根据nacos官网和一些帖子里写了必须使用@EnableNacosConfig 这个标签,但是实际代码里看是不需要的.

application.properties

这里我之前习惯性的写了个spring.application.name=lwb_test,如果写了这个属性,那么bootstrap里的spring.application.name就不生效了,我还取了不同的名字,导致启动失败,一直提示找不到lwb_test.properties配置文件,后来删除了application.properties里的应用名才好了。

删除坑

lwb_public,我上边的例子里使用了lwb_public,但是我发现我的命名空间名字和ID一样了,我想测试一下实际用的是名字和ID的时候我就把这个命名空间删除了,结果,程序还是能跑起来,而且这个命名空间里的配置生效了,我也找不到历史版本,这就感觉很坑。我觉得要么不生效,要么生效但是能让我看见,总之感觉这点很坑。

dataId

不知道命名规则之前,我的dataId随便取了一个lwb_test,结果死活就是找不到,后来才查到上边的规则。下图是我改成yml之后的配置,也是可以的不管是选text,yaml,Properties,都可以生效
在这里插入图片描述

使用springboot启动一切正常 run on server 跑起来无法访问 eureka首页 ``` 2019-05-20 17:38:53.768 INFO 7884 --- [ main] com.example.demo.ServletInitializer : No active profile set, falling back to default profiles: default 2019-05-20 17:38:55.377 WARN 7884 --- [ main] o.s.boot.actuate.endpoint.EndpointId : Endpoint ID 'service-registry' contains invalid characters, please migrate to a valid format. 2019-05-20 17:38:56.471 INFO 7884 --- [ main] o.s.cloud.context.scope.GenericScope : BeanFactory id=526ac23a-b26e-3353-b9ab-50e7bcf72d48 2019-05-20 17:38:56.706 INFO 7884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$976b1f47] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2019-05-20 17:38:56.714 INFO 7884 --- [ main] o.a.c.c.C.[.[localhost].[/eureka] : Initializing Spring embedded WebApplicationContext 2019-05-20 17:38:56.714 INFO 7884 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2914 ms 2019-05-20 17:38:57.117 WARN 7884 --- [ main] c.n.c.sources.URLConfigurationSource : No URLs will be polled as dynamic configuration sources. 2019-05-20 17:38:57.117 INFO 7884 --- [ main] c.n.c.sources.URLConfigurationSource : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath. 2019-05-20 17:38:57.151 INFO 7884 --- [ main] c.netflix.config.DynamicPropertyFactory : DynamicPropertyFactory is initialized with configuration sources: com.netflix.config.ConcurrentCompositeConfiguration@5d0b5f31 2019-05-20 17:38:59.724 WARN 7884 --- [ main] c.n.c.sources.URLConfigurationSource : No URLs will be polled as dynamic configuration sources. 2019-05-20 17:38:59.725 INFO 7884 --- [ main] c.n.c.sources.URLConfigurationSource : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath. 2019-05-20 17:39:00.103 INFO 7884 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2019-05-20 17:39:01.714 INFO 7884 --- [ main] o.s.c.n.eureka.InstanceInfoFactory : Setting initial instance status as: STARTING 2019-05-20 17:39:01.804 INFO 7884 --- [ main] com.netflix.discovery.DiscoveryClient : Initializing Eureka in region us-east-1 2019-05-20 17:39:01.806 INFO 7884 --- [ main] com.netflix.discovery.DiscoveryClient : Client configured to neither register nor query for data. 2019-05-20 17:39:01.829 INFO 7884 --- [ main] com.netflix.discovery.DiscoveryClient : Discovery Client initialized at timestamp 1558345141827 with initial instances count: 0 2019-05-20 17:39:01.930 INFO 7884 --- [ main] c.n.eureka.DefaultEurekaServerContext : Initializing ... 2019-05-20 17:39:01.935 WARN 7884 --- [ main] c.n.eureka.cluster.PeerEurekaNodes : The replica size seems to be empty. Check the route 53 DNS Registry 2019-05-20 17:39:01.975 INFO 7884 --- [ main] c.n.e.registry.AbstractInstanceRegistry : Finished initializing remote region registries. All known remote regions: [] 2019-05-20 17:39:01.976 INFO 7884 --- [ main] c.n.eureka.DefaultEurekaServerContext : Initialized 2019-05-20 17:39:02.009 INFO 7884 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 2 endpoint(s) beneath base path '/actuator' 2019-05-20 17:39:02.227 INFO 7884 --- [ main] o.s.c.n.e.s.EurekaServiceRegistry : Registering application service-eureka with eureka with status UP 2019-05-20 17:39:02.235 INFO 7884 --- [ Thread-13] o.s.c.n.e.server.EurekaServerBootstrap : Setting the eureka configuration.. 2019-05-20 17:39:02.237 INFO 7884 --- [ Thread-13] o.s.c.n.e.server.EurekaServerBootstrap : Eureka data center value eureka.datacenter is not set, defaulting to default 2019-05-20 17:39:02.239 INFO 7884 --- [ Thread-13] o.s.c.n.e.server.EurekaServerBootstrap : Eureka environment value eureka.environment is not set, defaulting to test 2019-05-20 17:39:02.269 INFO 7884 --- [ Thread-13] o.s.c.n.e.server.EurekaServerBootstrap : isAws returned false 2019-05-20 17:39:02.270 INFO 7884 --- [ Thread-13] o.s.c.n.e.server.EurekaServerBootstrap : Initialized server context 2019-05-20 17:39:02.270 INFO 7884 --- [ Thread-13] c.n.e.r.PeerAwareInstanceRegistryImpl : Got 1 instances from neighboring DS node 2019-05-20 17:39:02.270 INFO 7884 --- [ Thread-13] c.n.e.r.PeerAwareInstanceRegistryImpl : Renew threshold is: 1 2019-05-20 17:39:02.270 INFO 7884 --- [ Thread-13] c.n.e.r.PeerAwareInstanceRegistryImpl : Changing status to UP 2019-05-20 17:39:02.272 INFO 7884 --- [ main] com.example.demo.ServletInitializer : Started ServletInitializer in 11.507 seconds (JVM running for 19.123) 2019-05-20 17:39:02.291 INFO 7884 --- [ Thread-13] e.s.EurekaServerInitializerConfiguration : Started Eureka Server 2019-05-20 17:39:02.465 INFO 7884 --- [ main] org.apache.jasper.servlet.TldScanner : 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的JAR可以缩短启动时间和JSP编译时间。 2019-05-20 17:39:02.690 INFO 7884 --- [ main] c.s.j.s.i.a.WebApplicationImpl : Initiating Jersey application, version 'Jersey: 1.19.1 03/11/2016 02:08 PM' 2019-05-20 17:39:02.885 INFO 7884 --- [ main] c.n.d.provider.DiscoveryJerseyProvider : Using JSON encoding codec LegacyJacksonJson 2019-05-20 17:39:02.885 INFO 7884 --- [ main] c.n.d.provider.DiscoveryJerseyProvider : Using JSON decoding codec LegacyJacksonJson 2019-05-20 17:39:02.885 INFO 7884 --- [ main] c.n.d.provider.DiscoveryJerseyProvider : Using XML encoding codec XStreamXml 2019-05-20 17:39:02.885 INFO 7884 --- [ main] c.n.d.provider.DiscoveryJerseyProvider : Using XML decoding codec XStreamXml 2019-05-20 17:39:03.458 INFO 7884 --- [ main] org.apache.catalina.startup.HostConfig : Deployment of deployment descriptor [E:\apache-tomcat-9.0.17\conf\Catalina\localhost\eureka.xml] has finished in [18,757] ms 2019-05-20 17:39:03.459 INFO 7884 --- [ main] org.apache.catalina.startup.HostConfig : 把web 应用程序部署到目录 [E:\apache-tomcat-9.0.17\webapps\docs] 2019-05-20 17:39:03.487 INFO 7884 --- [ main] org.apache.catalina.startup.HostConfig : Deployment of web application directory [E:\apache-tomcat-9.0.17\webapps\docs] has finished in [28] ms 2019-05-20 17:39:03.488 INFO 7884 --- [ main] org.apache.catalina.startup.HostConfig : 把web 应用程序部署到目录 [E:\apache-tomcat-9.0.17\webapps\examples] 2019-05-20 17:39:03.764 INFO 7884 --- [ main] o.a.c.c.C.[.[localhost].[/examples] : ContextListener: contextInitialized() 2019-05-20 17:39:03.764 INFO 7884 --- [ main] o.a.c.c.C.[.[localhost].[/examples] : SessionListener: contextInitialized() 2019-05-20 17:39:03.766 INFO 7884 --- [ main] o.a.c.c.C.[.[localhost].[/examples] : ContextListener: attributeAdded('StockTicker', 'async.Stockticker@60157e9c') 2019-05-20 17:39:03.772 INFO 7884 --- [ main] org.apache.catalina.startup.HostConfig : Deployment of web application directory [E:\apache-tomcat-9.0.17\webapps\examples] has finished in [284] ms 2019-05-20 17:39:03.772 INFO 7884 --- [ main] org.apache.catalina.startup.HostConfig : 把web 应用程序部署到目录 [E:\apache-tomcat-9.0.17\webapps\host-manager] 2019-05-20 17:39:03.805 INFO 7884 --- [ main] org.apache.catalina.startup.HostConfig : Deployment of web application directory [E:\apache-tomcat-9.0.17\webapps\host-manager] has finished in [33] ms 2019-05-20 17:39:03.805 INFO 7884 --- [ main] org.apache.catalina.startup.HostConfig : 把web 应用程序部署到目录 [E:\apache-tomcat-9.0.17\webapps\manager] 2019-05-20 17:39:03.839 INFO 7884 --- [ main] org.apache.catalina.startup.HostConfig : Deployment of web application directory [E:\apache-tomcat-9.0.17\webapps\manager] has finished in [34] ms 2019-05-20 17:39:03.840 INFO 7884 --- [ main] org.apache.catalina.startup.HostConfig : 把web 应用程序部署到目录 [E:\apache-tomcat-9.0.17\webapps\ROOT] 2019-05-20 17:39:03.863 INFO 7884 --- [ main] org.apache.catalina.startup.HostConfig : Deployment of web application directory [E:\apache-tomcat-9.0.17\webapps\ROOT] has finished in [22] ms 2019-05-20 17:39:03.884 INFO 7884 --- [ main] org.apache.coyote.ajp.AjpNioProtocol : 开始协议处理句柄["ajp-nio-8009"] 2019-05-20 17:39:03.892 INFO 7884 --- [ main] org.apache.catalina.startup.Catalina : Server startup in [19,245] milliseconds 2019-05-20 17:39:05.298 INFO 7884 --- [p-nio-80-exec-3] o.a.c.c.C.[.[localhost].[/eureka] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2019-05-20 17:39:05.302 INFO 7884 --- [p-nio-80-exec-3] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2019-05-20 17:39:05.336 INFO 7884 --- [p-nio-80-exec-3] o.s.web.servlet.DispatcherServlet : Completed initialization in 33 ms 2019-05-20 17:39:05.997 ERROR 7884 --- [p-nio-80-exec-3] o.s.b.w.servlet.support.ErrorPageFilter : Cannot forward to error page for request [/] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false ```
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页