Spring Cloud动力节点-07Alibaba简介、注册、配置中心
1.项目简介
1.1 组件
Nacos 致力于发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
2.Nacos 的核心概念
2.1 服务 (Service)
2.2 服务注册中心 (Service Registry)
2.3 服务元数据 (Service Metadata)
2.4 服务提供方 (Service Provider)
2.5 服务消费方 (Service Consumer)
2.6 配置 (Configuration)---配置文件中心
2.7 配置管理 (Configuration Management)
2.8 名字服务 (Naming Service)
2.9 配置服务 (Configuration Service)
3.NacosServer 的安装和启动
3.1 NacosServer 的下载
下载起来比较慢,我这边已经下载好了
3.2 解压以及目录说明
3.3 修改配置文件【重点】
打开后如图:
Nacos 默认使用嵌入式数据库实现数据的存储,并不方便观察数据存储的基本情况,这里面我们修改为使用 Mysql 数据库做数据的存储,方便我们观察数据的结构。
spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://localhost:3306/nacos?characterEncoding=utf8&connectTimeout=1 000&socketTimeout=3000&autoReconnect=true db.user=root db.password=123456
3.4 Mysql 表的导入
3.5 NacosServer 的启动、
启动报错:
nacos访问地址无登录界面问题:版本2.2.3
场景:
访问 localhost:8848/nacos 地址时,没有弹出登录界面,提示"当前集群没有开启鉴权,请参考文档开启鉴权~"。此时左边菜单也没有权限控制模块。
原因分析:
这是新版本的配置文件中鉴权开关没有开启的原因,具体可以修改以下配置项,按照如下配置即可
nacos.core.auth.enabled=true nacos.core.auth.server.identity.key=${NACOS_AUTH_IDENTITY_KEY:example} nacos.core.auth.server.identity.value=${NACOS_AUTH_IDENTITY_KEY:example} nacos.core.auth.plugin.nacos.token.secret.key=${NACOS_AUTH_TOKEN:SecretKey01234567890123456789012345345678999987654901234567890123456789}
重启服务,再次访问 localhost:8848/nacos, 搞定!默认账号nacos,密码nacos
Nacos 默认用户名和密码都是 nacos。
至此,Nacos Server 已经安装成功。
4.使用 Nacos 做注册中心
Maven新建07-nacos项目
4.1 搭建两个 nacos 的客户端
4.2 版本依赖【重点-再贴图一次】
这里点击上方 GitHub 上的下载大概率是很慢的,非常慢,这里推荐个快速下载 nacos 的地址 :
https://sourceforge.net/projects/nacos.mirror/
4.3 创建两个项目,选择依赖
<?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.tongda</groupId> <artifactId>nacos-client-a</artifactId> <version>0.0.1-SNAPSHOT</version> <name>01-nacos-client-a</name> <description>01-nacos-client-a</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.7.6</spring-boot.version> <spring-cloud-alibaba.version>2021.0.5.0</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-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <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> </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>${spring-boot.version}</version> <configuration> <mainClass>com.tongda.Application</mainClass> <skip>true</skip> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
4.4 application.yml
server: port: 8080 spring: application: name: nacos-client-a cloud: nacos: #客户端注册的地址 server-addr: localhost:8848 # 往服务地址,注册自己 username: nacos password: nacos discovery: # 命名空间,可以做项目隔离 namespace: car-namespace group: dev # 在命名空间下的组别,可以用来细粒度的隔离
4.5 修改两个启动类
package com.tongda; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient // 开启服务发现客户端,也就是nacosServer的客户端 public class NacosClientAApplication { public static void main(String[] args) { SpringApplication.run(NacosClientAApplication.class, args); } }
4.6 给 02-nacos-client-b添加一个 controller
package com.tongda.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class BController { @GetMapping("info") public String info() { return "20W"; } }
4.7 启动 02-nacos-client-b测试
4.8 给 01-nacos-client-a添加一个 controller,做服务发现
package com.tongda.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class TestController { @Autowired public DiscoveryClient discoveryClient; public String testDis() { List<ServiceInstance> instances = discoveryClient.getInstances("user-service"); System.out.println(instances); return "ok"; } }
4.9 启动 alibaba-nacos-consumer 测试
5.集成 openfeign 做远程调用和负载均衡
出处有坑
步骤回显
- 引入openfeign的依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
- 被调用的微服务提供接口
@RestController @RequestMapping("/test") public class CouponController { @RequestMapping("/list") public Result list(@RequestParam Map<String, Object> params){ PageUtils page = couponService.queryPage(params); return Result.ok().put("page", page); } }
- 调用方编写feign的接口
@FeignClient("test1-demo") public interface TestFeign { @RequestMapping("/test/list") Result list(); }
项目用的alibaba的nacos作为注册中心,故@FeignClient(“test1-demo”)的名称为被调用服务接口放的在nacos上的注册名称。
- 开启openFeign
只需要在启动类上如下注解就好了
@SpringBootApplication @EnableDiscoveryClient //加入如下注解,开启openFeign @EnableFeignClients public class Test2DemoApplication { public static void main(String[] args) { SpringApplication.run(Test2DemoApplication.class, args); } }
发现报错
缺少依赖,启动报错
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.bearjun.gulimail.member.feign.CouponFeign': Unexpected exception during bean creation; nested exception is java.lang.IllegalStateException: No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalancer? at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-5.3.6.jar:5.3.6] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.6.jar:5.3.6] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.6.jar:5.3.6] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.6.jar:5.3.6] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.6.jar:5.3.6] at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.6.jar:5.3.6] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.6.jar:5.3.6] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.6.jar:5.3.6] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657) ~[spring-beans-5.3.6.jar:5.3.6] ... 21 common frames omitted Caused by: java.lang.IllegalStateException: No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalancer? at org.springframework.cloud.openfeign.FeignClientFactoryBean.loadBalance(FeignClientFactoryBean.java:333) ~[spring-cloud-openfeign-core-3.0.2.jar:3.0.2]
问题分析
由于SpringCloud Feign在Hoxton.M2 RELEASED版本之后不再使用Ribbon而是使用spring-cloud-loadbalancer,所以不引入spring-cloud-loadbalancer会报错。
链接:https://blog.csdn.net/weixin_43556636/article/details/110653989
解决方法
加入spring-cloud-loadbalancer依赖 并且在nacos中排除ribbon依赖,不然loadbalancer无效
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-loadbalancer</artifactId> </dependency>
依赖冲突
java.lang.AbstractMethodError: org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.choose(Ljava/lang/String;Lorg/springframework/cloud/client/loadbalancer/Request;)Lorg/springframework/cloud/client/ServiceInstance; at org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient.execute(FeignBlockingLoadBalancerClient.java:88) ~[spring-cloud-openfeign-core-3.0.2.jar:3.0.2] at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:119) ~[feign-core-10.10.1.jar:na] at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:89) ~[feign-core-10.10.1.jar:na] at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:100) ~[feign-core-10.10.1.jar:na] at com.sun.proxy.$Proxy91.list(Unknown Source) ~[na:na] at com.bearjun.gulimail.member.controller.MemberController.list(MemberController.java:44) ~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_261] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_261] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_261] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_261] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) ~[spring-web-5.3.6.jar:5.3.6] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141) ~[spring-web-5.3.6.jar:5.3.6] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.6.jar:5.3.6] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.6.jar:5.3.6] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.6.jar:5.3.6] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.6.jar:5.3.6] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060) ~[spring-webmvc-5.3.6.jar:5.3.6] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962) ~[spring-webmvc-5.3.6.jar:5.3.6] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.6.jar:5.3.6] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.6.jar:5.3.6] at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) ~[tomcat-embed-core-9.0.45.jar:4.0.FR] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.6.jar:5.3.6] at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.45.jar:4.0.FR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.45.jar:9.0.45]...........
问题分析
nacos中 pring-cloud-starter-netflix-ribbon会与它冲突,造成loadbalanc包失效
解决方法
我们只需要再nacos的服务注册与发现的依赖中去掉ribbon
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <!-- 排除ribbon的依赖 --> <exclusions> <exclusion> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </exclusion> </exclusions> </dependency>
Maven显示中央仓库找不到spring-cloud-starter-alibaba-nacos-discovery,去阿里云镜像发现上面版本信息写的unknown,有点懵逼于是去MavenRepository找一下版本号,看一下与SpringCloud适配的版本,Nacos1.3,完事
版本不匹配解决方法如下:
com.alibaba.nacos.api.exception.NacosException: failed to req API解决方案
5.1 启动多台 alibaba-nacos-provider
5.2.1 添加 openfeign 的依赖,注意还需要 cloud 的依赖管理,此处有坑可看前面避坑
<?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.tongda</groupId> <artifactId>nacos-client-a</artifactId> <version>0.0.1-SNAPSHOT</version> <name>01-nacos-client-a</name> <description>01-nacos-client-a</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.6.13</spring-boot.version> <spring-cloud.version>2021.0.5</spring-cloud.version> <spring-cloud-alibaba.version>2021.0.5.0</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-discovery</artifactId> </dependency>
<-- Openfeign避坑,必须loadbalancer一起导入依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-loadbalancer</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <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.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.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>${spring-boot.version}</version> <configuration> <mainClass>com.tongda.Application</mainClass> <skip>true</skip> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
问题分析
由于SpringCloud Feign在Hoxton.M2 RELEASED版本之后不再使用Ribbon而是使用spring-cloud-loadbalancer,所以不引入spring-cloud-loadbalancer会报错。
链接:https://blog.csdn.net/weixin_43556636/article/details/110653989
5.2.2 修改启动类,添加注解
package com.tongda; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableDiscoveryClient // 开启服务发现客户端,也就是nacosServer的客户端 @EnableFeignClients // 开启Feign远程调用 public class NacosClientAApplication { public static void main(String[] args) { SpringApplication.run(NacosClientAApplication.class, args); } }
5.2.3 添加一个 feign 的接口,注意和提供者一致
package com.tongda.feign; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; @FeignClient(value = "user-service") // Feign远程调用提供者 public interface TestFeign { // 调用02-nacos-b中Bcontroller做接口 @GetMapping("info") public String info(); }
5.2.4 添加一个 controller
package com.tongda.controller; import com.tongda.feign.TestFeign; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class TestController { @Autowired public DiscoveryClient discoveryClient; @Autowired public TestFeign testFeign; @GetMapping("test") public String testDis() { List<ServiceInstance> instances = discoveryClient.getInstances("user-service"); System.out.println(instances); return testFeign.info(); // return "ok"; } }
5.2.5 启动测试
6.Nacos Discovery 对外暴露 Endpoint
6.1 给任意项目添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
6.2 修改配置文件
management: endpoints: web: exposoure: include: '*'
6.3 启动项目访问查看效果
7.Nacos Discovery Starter 更多的配置项
配置项 | Key | 默认值 | 说明 |
---|---|---|---|
服务端地址 | spring.cloud.nacos.discovery.server-addr | 无 | NacosServer 启动监听的ip地址和端口 |
服务名 | spring.cloud.nacos.discovery.service | ${spring.application.name} | 给当前的服务命名 |
服务分组 | spring.cloud.nacos.discovery.group | DEFAULT_GROUP | 设置服务所处的分组 |
权重 | spring.cloud.nacos.discovery.weight | 1 | 取值范围 1 到 100,数值越大,权重越大 |
网卡名 | spring.cloud.nacos.discovery.networkinterface | 无 | 当IP未配置时,注册的IP为此网卡所对应的IP地址,如果此项也未配置,则默认取第一块网卡的地址 |
注册的IP地址 | spring.cloud.nacos.discovery.ip | 无 | 优先级最高 |
注册的端口 | spring.cloud.nacos.discovery.port | -1 | 默认情况下不用配置,会自动探测 |
命名空间 | spring.cloud.nacos.discovery.namespace | 无 | 常用场景之一是不同环境的注册的区分隔离,例如开发测试环境和生 产环境的资源(如配置、服务)隔离等。 |
AccessKey | spring.cloud.nacos.discovery.access-key | 无 | 当要上阿里云时,阿里云上面的一个云账号名 |
SecretKey | spring.cloud.nacos.discovery.secret-key | 无 | 当要上阿里云时,阿里云上面的一个云账号密码 |
Metadata | spring.cloud.nacos.discovery.metadata | 无 | 使用Map格式配置,用户可以根据自己的需要自定义一些和服务相关的元数据信息 |
日志文件名 | spring.cloud.nacos.discovery.metadataspring.cloud.nacos.discovery.log-name | 无 | |
集群 | spring.cloud.nacos.discovery.cluster-name | DEFAULT | 配置成Nacos集群名称 |
接入点 | spring.cloud.nacos.discovery.enpoint | UTF-8 | 地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址 |
是否集成Ribbon | ribbon.nacos.enabled | true | 一般都设置成true即可 |
是否开启Nacos Watch | spring.cloud.nacos.discovery.watch.enabled | true | 可以设置成false来关闭 watch |
1.服务端地址
spring.cloud.nacos.discovery.server-addr 无 Nacos Server 启动监听的 ip 地址和端口
2.服务名
spring.cloud.nacos.discovery.s ervice ${spring.application.name} 给当前的服务命名
3.服务分组
spring.cloud.nacos.discovery.group DEFAULT_GROUP 设置服务所处的分组
4.权重
spring.cloud.nacos.discovery.weight 1 取值范围 1 到 100 ,数值越大,权重越大
5.网卡名
spring.cloud.nacos.discovery.network-interface 无 当 IP 未配置时,注册的 IP 为此网卡所对应的 IP 地址,如果此项也未配置,则 默认取第一块网卡的地址
集群配置时,nacos、nacos1、nacos2,properties中修改数据库SQL、端口
8848\8849\8850,新建cluster.conf
编辑cluster.conf
注:避免中文目录
启动失败,发现端口占用
09【Nacos 配置文件中心】
1.Nacos 简介
使用 Spring Cloud Alibaba Nacos Config,可基于 Spring Cloud 的编程模型快速接入 Nacos 配置管理功能,动态服务发现为核心。
启动nacos,新建nacos配置文件
2.创建项目 config-client-a
2.1 创建项目选择依赖
<?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.tongda</groupId> <artifactId>nacos-config-a</artifactId> <version>0.0.1-SNAPSHOT</version> <name>04-nacos-config-a</name> <description>04-nacos-config-a</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.7.6</spring-boot.version> <spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version> <spring-cloud.version>2021.0.5</spring-cloud.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>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-loadbalancer</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <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.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.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>${spring-boot.version}</version> <configuration> <mainClass>com.tongda.Application</mainClass> <skip>true</skip> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
修改Bootstrap.yml
# 应用服务 WEB 访问端口 server.port=8080 # Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html # Nacos认证信息 spring.cloud.nacos.config.username=nacos spring.cloud.nacos.config.password=nacos spring.cloud.nacos.config.contextPath=/nacos # 设置配置中心服务端地址 spring.cloud.nacos.config.server-addr=mse-6d50f4f0-p.nacos-ans.mse.aliyuncs.com:8848 # Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可 # spring.cloud.nacos.config.namespace= spring.config.import=nacos:nacos-config-example.properties?refresh=true # Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html spring.application.name=nacos-service # Nacos认证信息 spring.cloud.nacos.discovery.username=nacos spring.cloud.nacos.discovery.password=nacos # Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口 spring.cloud.nacos.discovery.server-addr=mse-6d50f4f0-p.nacos-ans.mse.aliyuncs.com:8848 # 注册到 nacos 的指定 namespace,默认为 public spring.cloud.nacos.discovery.namespace=public
指定读取哪个中心,账号密码,哪个命名空间,组中哪个文件格式信息。
# 应用服务 WEB 访问端口 server: port: 8081 spring: application: name: nacos-config-a cloud: nacos: config: # 项目在启动的时候去哪里找它对应的配置文件 server-addr: localhost:8848 username: nacos password: naocs # namespace: # 默认命名空间 # group: prefix: nacos-config-a # 默认${spring.application.name},调用哪个配置文件nacos-config-a file-extension: yml # 读取格式yml文件类型
此处有坑
查看SpringCloud Alibaba 2021版 nacos 配置中心教程得知,在该版本下原有的nacos配置文件获取规则不再生效需要改为spring.config.import的方式来配置,此种配置方式也支持多个配置文件的获取,配置参考如下
注意事项:
如果使用 spring.config.import
就不能使用 bootstrap.yml/properties
引入配置的方式了 !!!
如果引入了spring-cloud-starter-alibaba-nacos-config
,并且使用 import
方式导入配置,项目启动时会自动检测是否引入了 nacos:条目
,如果没有 import nacos
条目,会出现如下错误:
The spring.config.import property is missing a nacos: entry Action: Add a spring.config.import=nacos: property to your configuration. If configuration is not required add spring.config.import=optional:nacos: instead. To disable this check, set spring.cloud.nacos.config.import-check.enabled=false.
spring: application: name: order cloud: nacos: config: group: DEV_GROUP server-addr: 127.0.0.1:8848 namespace: c822f776-306c-4dd2-9612-68b697e3b240 username: nacos password: nacos discovery: server-addr: 127.0.0.1:8848 config: import: - optional:nacos:order.yml - optional:nacos:comm.yml?group=DEFAULT_GROUP&refreshEnabled=false
spring cloud2021.0.5版本nacos配置中心的使用总结
原有的bootstrap.yml配置文件不再生效,需要修改为application.yml的配置
# application.yml spring: cloud: nacos: config: group: DEFAULT_GROUP server-addr: 127.0.0.1:8848 config: import: - optional:nacos:test.yml # 监听 DEFAULT_GROUP:test.yml - optional:nacos:test01.yml?group=group_01 # 覆盖默认 group,监听 group_01:test01.yml - optional:nacos:test02.yml?group=group_02&refreshEnabled=false # 不开启动态刷新 - nacos:test03.yml # 在拉取nacos配置异常时会快速失败,会导致 spring 容器启动失败
# 应用服务 WEB 访问端口 server: port: 8083 spring: application: name: nacos-config-a cloud: nacos: config: # 项目在启动的时候去哪里找它对应的配置文件 server-addr: localhost:8848 prefix: nacos-config-a file-extension: yml # 配置文件类型 refresh-enabled: true # 动态刷新配置 username: nacos password: naocs # spring cloud2021.0.5后配置变更,需要以下方式导入nacos的配置文件 # config: # # 因为springboot 2.4版本以后默认关闭加载bootstrap.yml,所以只能通过此方式连接到nacos config # import: # nacos:${spring.application.name}.${spring.cloud.nacos.config.file-extension} # config: # import: # # 监听 # - optional:nacos:nacos-config-a.yml # # 开启动态刷新 # - optional:nacos:nacos-config-a.yml?group=DEFAULT_GROUP&refreshEnabled=true # namespace: # 默认命名空间 # group: # prefix: nacos-config-a # 默认${spring.application.name},调用哪个配置文件nacos-config-a # file-extension: yml # 读取格式yml文件类型
注意:
如果想保留以前的使用方式(bootstrap引入配置),需要添加依赖 pring-cloud-starter-bootstrap 依赖,不需要修改一行代码。
refreshEnabled参数要搭配@RefreshScope使用,如果没有使用@RefreshScope注解,就算配置了refreshEnabled=true也不会自动刷新。
refreshEnabled=false只是针对test02.yml这个配置文件在修改时不会自动刷新。如果test.yml中的参数和test02.yml所中的参数在同一个类中被使用且配置了@RefreshScope注解,那么在修改test02.yml后再修改test.yml会导致test02.yml被刷新。
2.2 在 NacosServer 里面添加一个配置文件
填写具体信息:
发布配置文件:
返回查看配置文件发布成功了
2.3 查看上一讲中创建的数据库中的信息
2.4 config-client-a 项目中添加一个配置文件 bootstrap.yml
正确案列配置
<!--Springboot版本管理--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.13</version> <type>pom</type> </dependency> <!--spring-cloud版本管理--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2021.0.5</version> </dependency> <!--spring-cloud-alibaba版本管理--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2021.0.5.0</version> </dependency> <!--引入nacos服务--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--引入nacos-config服务--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--bootstrap加载到上下文--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency>
<?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.tongda</groupId> <artifactId>nacos-config-a</artifactId> <version>0.0.1-SNAPSHOT</version> <name>04-nacos-config-a</name> <description>04-nacos-config-a</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.7.6</spring-boot.version> <spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version> <spring-cloud.version>2021.0.5</spring-cloud.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-discovery</artifactId> </dependency> <!--引入nacos-config服务--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--bootstrap加载到上下文--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <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.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.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>${spring-boot.version}</version> <configuration> <mainClass>com.tongda.Application</mainClass> <skip>true</skip> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
2)项目添加application.yml
bootstrap.yml
文件
spring: # 配置中心地址 application: # 服务名称 name: nacos-config-a # 环境配置 例如 admin-dev.yaml #profiles: # active: dev cloud: nacos: discovery: # 开启nacos作为服务注册中心,默认值:true enabled: true # nacos集群服务注册地址 server-addr: localhost:8848 # nacos用户名 username: nacos # nacos密码 password: nacos # 命名空间,默认 public,可设置dev,pro等,相同特征的服务分类,先去nacos命名空间创建 # namespace: public # 分组,默认 DEFAULT_GROUP 相同特征的服务划分的更细 group: DEFAULT_GROUP # 临时实例,默认true,false永久实例,即使宕机也不会从nacos服务中删除,可应对雪崩保护,避免服务被删除 ephemeral: true # 权重 1-100 数值越大权重越大分配的流量就越大,通常结合权重负载均衡策略 # weight: 100 config: server-addr: ${spring.cloud.nacos.discovery.server-addr} username: ${spring.cloud.nacos.discovery.username} password: ${spring.cloud.nacos.discovery.password} # dataid为yaml的文件扩展名配置方式 ${spring.application.name}.${file‐extension:properties} file-extension: yaml # namespace: group: DEFAULT_GROUP context-path: /nacos # 共享配置 #shared-configs: # - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
2.5 config-client-a 中添加一个实体类 Hero
package com.tongda.domain; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.stereotype.Component; @Data @AllArgsConstructor @NoArgsConstructor @RefreshScope // 刷新的域,当配置文件修改后可以动态刷新 @Component // 添加到 IOC 中,一会在 controller 注入 public class TongDa { @Value("${tongda.name}") private String name; @Value("${tongda.age}") private Integer age; @Value("${tongda.address}") private String address; }
2.6 config-client-a 中添加一个测试类 Controller
package com.tongda.controller; import com.tongda.domain.TongDa; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class TestController { @Resource public TongDa tongda; @GetMapping("info") public String getInfo(){ return tongda.getName()+":"+tongda.getAge()+":"+tongda.getAddress(); } }
2.7 启动测试
2.8 测试配置文件的动态刷新
不需要重启,直接请求 http://localhost:8083/Info 查看结果已经刷新了
2.9 配置文件的历史版本查询
2.10 配置文件的回滚
3.配置文件的读取方式【重点】
例如:发布nacos-config-dev
5.获取多配置文件
5.1 在 Nacos 中新建两个配置文件
一般项目,先创建命名空间,在项目分组,项目id
新建配置:user-center-dev.yml,A组
再创建一个mamber-center-dev.yml,B组
同一项目,不同组
创建新项目,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.tongda</groupId> <artifactId>nacos-config-test</artifactId> <version>0.0.1-SNAPSHOT</version> <name>05-nacos-config-test</name> <description>05-nacos-config-test</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.7.8</spring-boot.version> <spring-cloud.version>2021.0.5</spring-cloud.version> <spring-cloud-alibaba.version>2021.0.5.0</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-discovery</artifactId> </dependency> <!--引入nacos-config服务--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--bootstrap加载到上下文--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <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.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.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>${spring-boot.version}</version> <configuration> <mainClass>com.tongda.Application</mainClass> <skip>true</skip> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
bootstrap.yml优先级>大于application.yml
配置文件的读取优先级
本地配置文件:bootstrap.yml 先加载 application.yml后加载,application 也不会覆盖 bootstrap,而 application.yml 里面的内容可以动态替换。Spring Boot 中application.yml与bootstrap.yml的区别_application.yml 引用bootstrap.yml_keep one's resolveY的博客-CSDN博客
远程和本地配置文件的优先级:远程项目应用名配置文件 > 远程扩展配置文件 > 远程共享配置文件 > 本地配置文件。
如果我们想让本地最优先,可以在nacos配置文件中配置实现!
Spring Cloud Alibaba Nacos Config 提供了三种配置能力从 Nacos 拉取相关的配置
A:通过 spring.cloud.nacos.config.shared-configs[n].data-id 方式支持多个共享 dataId 配置
B:通过 spring.cloud.nacos.config.extension-configs[n]-data-id 方式支持多个扩展 dataId 配置
C:通过内部相关规则(应用名、应用名+Profile)自动生成相关的 dataId 配置
当三种方式同时使用时,它们的优先级关系:A < B < C,同理,若在这三种方式中配置了同样的参数时,则会使用 C 配置的参数值
spring: # 配置中心地址 application: # 服务名称 name: nacos-config-test # 环境配置 例如 admin-dev.yaml #profiles: # active: dev cloud: nacos: discovery: # 开启nacos作为服务注册中心,默认值:true enabled: true # nacos集群服务注册地址 server-addr: localhost:8848 # nacos用户名 username: nacos # nacos密码 password: nacos # 命名空间,默认 public,可设置dev,pro等,相同特征的服务分类,先去nacos命名空间创建 # namespace: public # 分组,默认 DEFAULT_GROUP 相同特征的服务划分的更细 group: DEFAULT_GROUP # 临时实例,默认true,false永久实例,即使宕机也不会从nacos服务中删除,可应对雪崩保护,避免服务被删除 ephemeral: true # 权重 1-100 数值越大权重越大分配的流量就越大,通常结合权重负载均衡策略 # weight: 100 config: server-addr: ${spring.cloud.nacos.discovery.server-addr} username: ${spring.cloud.nacos.discovery.username} password: ${spring.cloud.nacos.discovery.password} namespace: 918ccce6-801e-4014-8ed2-c2b6a30658c2 # dataid为yaml的文件扩展名配置方式 ${spring.application.name}.${file‐extension:properties} file-extension: yml # namespace: # group: DEFAULT_GROUP # context-path: /nacos extension-configs: - dataId: user-center-dev.yml group: A_GROUP refresh: true - dataId: member-center-dev.yml group: B_GROUP refresh: false # 共享配置 #shared-configs: # - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
此处有坑
配置文件的读取优先级
那么多配置文件,如果有重复的配置项,那么应该听从谁的?谁会覆盖谁呢?
- 通过内部相关规则(应用名、扩展名、profiles)自动生成相关的 Data Id 配置优先级最高
- nacos中的配置优先于本地配置,本地的bootstrap.yml>bootstrap.properties>application.yml>application.yaml>application.properties
- 扩展配置(extension-configs) > 共享配置(shared-configs)
- 同为扩展配置,存在如下优先级关系:extension-configs[3] > extension-configs[2] > extension-configs[1] > extension-configs[0]
- 同为共享配置,存在如下优先级关系:shared-configs[3] > shared-configs[2] > shared-configs[1] > shared-configs[0]
总的来说是:(线上) 服务名-profile.yml>服务名.yml>extension-configs[3]>extension-configs[2]>shared-configs[3]>(本地) shared-configs[2]>bootstrap.yml>bootstrap.properties>application.yml>application.yaml>application.properties
终极方案
有的配置可以通用于各个服务中,怎么共享使用呢?(shared-configs)
shared-configs: # 共享配置文件
- data-id: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
group: DEFAULT_GROUP
所对应的配置名就是application-dev.yml
总结